【问题标题】:Android Fragment onCreateView with Gestures带有手势的 Android 片段 onCreateView
【发布时间】:2016-08-12 12:08:43
【问题描述】:

我正在尝试在片段中使用手势;我在处理我的详细信息片段的 FragmentActivity 中有以下内容。我试图发生的是当在视图上检测到滑动以将视图内的数据替换为上一个或下一个条目时。

如果有更好的处理方法;我完全同意。然而,这里发生的是 onFling 方法从未真正被调用过。

public static class DetailsFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
        if (container == null) {
            return null;
        }
        View v = inflater.inflate(R.layout.my_view, null, false);
        final GestureDetector gesture = new GestureDetector(getActivity(),
            new GestureDetector.SimpleOnGestureListener() {
                @Override
                public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
                    float velocityY) {

                    final int SWIPE_MIN_DISTANCE = 120;
                    final int SWIPE_MAX_OFF_PATH = 250;
                    final int SWIPE_THRESHOLD_VELOCITY = 200;
                    try {
                        if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH)
                            return false;
                        if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE
                            && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                            Log.i(Constants.APP_TAG, "Right to Left");
                        } else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE
                            && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                            Log.i(Constants.APP_TAG, "Left to Right");
                            titles.showDetails(getPosition() - 1);
                        }
                    } catch (Exception e) {
                        // nothing
                    }
                    return super.onFling(e1, e2, velocityX, velocityY);
                }
            });

        v.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return gesture.onTouchEvent(event);
            }
        });

        return v;
    }
}

【问题讨论】:

    标签: android


    【解决方案1】:

    看起来下面的问题解释了这一点:Android: GestureDetector won't catch Gestures

    另外,结果如下:

    解决办法其实就是重写onDown方法,返回true;否则手势检测器将停止并且检测不到向上:

            final GestureDetector gesture = new GestureDetector(getActivity(),
                new GestureDetector.SimpleOnGestureListener() {
    
                    @Override
                    public boolean onDown(MotionEvent e) {
                        return true;
                    }
    
                    @Override
                    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
                        float velocityY) {
                        Log.i(Constants.APP_TAG, "onFling has been called!");
                        final int SWIPE_MIN_DISTANCE = 120;
                        final int SWIPE_MAX_OFF_PATH = 250;
                        final int SWIPE_THRESHOLD_VELOCITY = 200;
                        try {
                            if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH)
                                return false;
                            if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE
                                && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                                Log.i(Constants.APP_TAG, "Right to Left");
                            } else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE
                                && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                                Log.i(Constants.APP_TAG, "Left to Right");
                            }
                        } catch (Exception e) {
                            // nothing
                        }
                        return super.onFling(e1, e2, velocityX, velocityY);
                    }
                });
    
            v.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    return gesture.onTouchEvent(event);
                }
            });
    

    【讨论】:

    • 只是好奇:为什么对手势的引用没有丢失?
    • @LemLordjeKo 为什么对gesture 的引用会丢失? gesture 被我们创建的 View.OnTouchListener 作为引用保存,而视图本身 v 作为引用保存。 Java 已经足够成熟了,如果有一个对象的路径,它几乎肯定不会被 GC。
    • 上述 sn-p 工作需要以下导入: import android.view.View.OnTouchListener;导入 android.view.MotionEvent;导入android.view.GestureDetector;导入android.util.Log;类常量 { public static final String APP_TAG = "mytag"; }
    【解决方案2】:

    几个厘米

    1. 我不得不如下调整我的代码:

      v.setOnTouchListener(new View.OnTouchListener() {
          @Override        
          public boolean onTouch(View v, MotionEvent event) {
      
              // return gesture.onTouchEvent(event);
      
              gesture.onTouchEvent(event);
              return true; // <-- this line made the difference
          }
      });
      
    2. 另外,如果您使用 xml 文件来创建视图

      View v = inflater.inflate(R.layout.my_view, null, false);
      

    确保您实际上是在按预期的视图。夸大测试的一个好方法是在布局 xml 文件中将宽度和高度都设为“match_parent”而不是“wrap_content”。

    【讨论】:

    • 我错过了 @mwillbanks 覆盖 onDown 以为 SimpleOnGestureListener 返回 true。我只在 onSingleTapConfirmed 和 onDoubleTap 上实现。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-23
    • 2016-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多