14

好的。这件事几乎让我发疯。

几天前,我可以实现下面的代码,当我尝试向右或向左滑动时,成功调用了 toast。

但是,现在不能调用了,因为 e1 始终为空!

这怎么可能发生?我在模拟器上尝试了这段代码,但一个用户报告我,它在真实设备上也不起作用。

public class SwipeGestureListener extends GestureDetector.SimpleOnGestureListener{

    private static final int SWIPE_MIN_DISTANCE = 150;
    private static final int SWIPE_MAX_OFF_PATH = 100;

    private static final int SWIPE_THRESHOLD_VELOCITY = 100;
    private final Activity activity;
    protected MotionEvent mLastOnDownEvent = null;

    public SwipeGestureListener(Activity activity) {
        this.activity = activity;
    }

    @Override
    public boolean onDown(MotionEvent e) {
        mLastOnDownEvent = e;
        System.out.println(e);
        return super.onDown(e);
    }

    @Override   
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        System.out.println(e1 + " " + e2);
        if (e1==null)
            e1 = mLastOnDownEvent;
        if (e1==null || e2==null)
            return false;

        float dX = e2.getX()-e1.getX();
        float dY = e2.getY()-e1.getY();

        if (Math.abs(dY)<SWIPE_MAX_OFF_PATH && Math.abs(velocityX)>=SWIPE_THRESHOLD_VELOCITY && Math.abs(dX)>=SWIPE_MIN_DISTANCE ) {

            if (dX>0) {
                Toast.makeText(activity.getApplicationContext(), "Right Swipe", Toast.LENGTH_SHORT).show();
                activity.fetchPrevious();
            } else {
                Toast.makeText(activity.getApplicationContext(), "Left Swipe", Toast.LENGTH_SHORT).show();
                activity.fetchNext();
            }

            return true;
        } 

        return false;
    }

}

实现手势的代码:

final GestureDetector gdt = new GestureDetector(this, new SwipeGestureListener(this));
listview.setOnTouchListener(new OnTouchListener(){

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        gdt.onTouchEvent(event);
        return false;
        }

});
4

4 回答 4

1

我尝试了您的代码,但确实没有用,然后我将 GestureDetector 更改为较新/更新的 API“GestureDetectorCompat”并更改了一些其他内容:使用 GestureDetector.OnGestureListener 而不是 OnSimpleGestureListener,onDown() 应该返回 true 并且然后它起作用了。我无法向您解释,确切的问题是什么。但变化线似乎是有问题的。也许有人可以解释潜在的问题。看看代码,它正在工作:

public class MainActivity extends Activity {
   ImageView imageView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        imageView= (ImageView) findViewById(R.id.imageView1);

        final GestureDetectorCompat gdt = new GestureDetectorCompat(this, new SwipeGestureListener(this));
        imageView.setOnTouchListener(new OnTouchListener(){

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return gdt.onTouchEvent(event);
                }

        });

    }




    public class SwipeGestureListener implements GestureDetector.OnGestureListener{

        private static final int SWIPE_MIN_DISTANCE = 150;
        private static final int SWIPE_MAX_OFF_PATH = 100;

        private static final int SWIPE_THRESHOLD_VELOCITY = 100;
        private final Activity activity;
        protected MotionEvent mLastOnDownEvent = null;

        public SwipeGestureListener(Activity activity) {
            this.activity = activity;
    }

        @Override
        public boolean onDown(MotionEvent e) {
            mLastOnDownEvent = e;
            System.err.println("ondown");
            //System.out.println(e);
            return true;
        }

        @Override   
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            System.err.println("onFling");
            System.out.println(e1 + " " + e2);
            if (e1==null)
                e1 = mLastOnDownEvent;
            if (e1==null || e2==null)
                return false;

            float dX = e2.getX()-e1.getX();
            float dY = e2.getY()-e1.getY();

            if (Math.abs(dY)<SWIPE_MAX_OFF_PATH && Math.abs(velocityX)>=SWIPE_THRESHOLD_VELOCITY && Math.abs(dX)>=SWIPE_MIN_DISTANCE ) {

                if (dX>0) {
                    Toast.makeText(activity.getApplicationContext(), "Right Swipe", Toast.LENGTH_SHORT).show();
                   // activity.fetchPrevious();
                } else {
                    Toast.makeText(activity.getApplicationContext(), "Left Swipe", Toast.LENGTH_SHORT).show();
                   // activity.fetchNext();
                }

                return true;
            } 

            return false;
        }

        @Override
        public void onLongPress(MotionEvent e) {
            // TODO Auto-generated method stub

    }

        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { 
            // TODO Auto-generated method stub
            return false;
    }

        @Override
        public void onShowPress(MotionEvent e) {
            // TODO Auto-generated method stub

    }

       @Override
       public boolean onSingleTapUp(MotionEvent e) {
          // TODO Auto-generated method stub
           return false;
       }

       }

   }

请试一试!

于 2013-06-30T14:18:17.347 回答
0

我有同样的问题。如果有一个 onclicklistener 等正在滑动项目,您应该删除该侦听器。然后它将起作用。谢谢..

于 2015-03-19T19:06:14.663 回答
0

我有同样的问题。确保您的所有视图都添加了相同的setOnTouchListener()方法。如果您的触摸位置在视野之外,您将进入nulle1。

我的例子:

private View.OnTouchListener onTouchListener = new OnSwipeTouchListener(mActivity) {

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            return super.onTouch(v, event);
        }

        @Override
        public void onSwipeLeft() {

        }

        @Override
        public void onSwipeRight() {
        }
    };


    @Override
    public View onCreateView(LayoutInflater inflater,
                      ViewGroup container, Bundle savedInstanceState) {

    //Inflate the layout for this fragment
    View v = inflater.inflate(R.layout.view, container, false);
    mListView = (ListView) v.findViewById(R.id.list);
    v.setFocusableInTouchMode(true);
    v.requestFocus();
    v.setOnTouchListener(onTouchListener);
    mListView.setOnTouchListener(onTouchListener);

    mAdapter = new OnlineAdapter(getActivity(), R.layout.row, onTouchListener);
    mListView.setAdapter(mAdapter);
    return v;

}

还有我的列表适配器:

@Override
    public View getView(final int position, View convertView, ViewGroup parent) {

        // something

            mImage = (ImageView) convertView.findViewById(R.id.image);
            mImage.setOnTouchListener(onTouchListener);
    }
于 2015-01-13T15:42:48.913 回答
0

我有一个类似的问题,并通过添加 FrameLayout 以及所需的视图来解决它(我使用的是 GridView,但认为它可以与 ListView 或其他视图一起使用)

GestureListener 和你的一样。布局:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout android:id="@+id/colors_grid_panel"
             xmlns:android="http://schemas.android.com/apk/res/android"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:background="@color/white"
             android:paddingLeft="@dimen/create_side_padding"
             android:paddingRight="@dimen/create_side_padding"
             android:visibility="gone">

    <GridView
        android:id="@+id/colors_grid"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:numColumns="7"
        android:paddingBottom="10dp"
        android:paddingTop="10dp"
        android:stretchMode="columnWidth"
        android:verticalSpacing="10dp"/>

    <FrameLayout
        android:id="@+id/stub"
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</FrameLayout>

在代码中:

colorsGrid.setOnTouchListener(onSwipeTouchListener);
stub.setOnTouchListener(onSwipeTouchListener);
于 2016-01-22T10:20:56.057 回答