在网格布局上检测拖动手势

15 浏览
0 Comments

在网格布局上检测拖动手势

我想在我的Android应用程序中实现fling手势检测。

我有一个包含9个ImageViewGridLayout,可以在此处找到源代码:Romain Guys的Grid布局

我使用的文件来自Romain Guy的Photostream应用程序,只进行了轻微的调整。

对于简单的点击情况,我只需要将我添加的每个ImageViewonClickListener设置为实现View.OnClickListener的主要activity即可。似乎更复杂的是实现识别fling的功能。我认为这是因为它可能跨越多个views

  • 如果我的activity实现了OnGestureListener,我不知道如何将其设置为GridImage视图的手势监听器。

    public class SelectFilterActivity extends Activity implements
       View.OnClickListener, OnGestureListener { ...
    

  • 如果我的activity实现了OnTouchListener,那么我就没有onFling方法可以重写(它有两个事件作为参数,允许我确定这个fling是否值得注意)。

    public class SelectFilterActivity extends Activity implements
        View.OnClickListener, OnTouchListener { ...
    

  • 如果我创建一个自定义的View,比如GestureImageView,它扩展了ImageView,我不知道如何告诉activity从视图中检测到一个fling。无论如何,我尝试过这个,但是当我触摸屏幕时,方法没有被调用。

我真的只需要一个跨视图工作的具体示例。我应该在什么时候以及如何附加这个listener?我需要能够检测单击。

// Gesture detection
mGestureDetector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener() {
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        int dx = (int) (e2.getX() - e1.getX());
        // don't accept the fling if it's too short
        // as it may conflict with a button push
        if (Math.abs(dx) > MAJOR_MOVE && Math.abs(velocityX) > Math.absvelocityY)) {
            if (velocityX > 0) {
                moveRight();
            } else {
                moveLeft();
            }
            return true;
        } else {
            return false;
        }
    }
});

是否有可能在屏幕顶部放置一个透明视图来捕捉滑动手势?

如果不从XML中inflate我的子图像视图,我可以将GestureDetector作为构造函数参数传递给我创建的新ImageView子类吗?

这是我正试图使fling检测起作用的非常简单的活动:SelectFilterActivity (Adapted from photostream)

我一直在看这些资源:

到目前为止都没有起作用,我希望能得到一些指点。

admin 更改状态以发布 2023年5月23日
0
0 Comments

以上的一个答案提到了处理不同像素密度,但建议手动计算刷卡参数。值得注意的是,您实际上可以使用ViewConfiguration类从系统获取缩放的合理值:

final ViewConfiguration vc = ViewConfiguration.get(getContext());
final int swipeMinDistance = vc.getScaledPagingTouchSlop();
final int swipeThresholdVelocity = vc.getScaledMinimumFlingVelocity();
final int swipeMaxOffPath = vc.getScaledTouchSlop();
// (there is also vc.getScaledMaximumFlingVelocity() one could check against)

我注意到使用这些值会导致滑动的“感觉”在应用和系统的其余部分之间更加一致。

0
0 Comments

感谢Code Shogun,我在其中的代码中作出了适应性的调整。

让你的活动像往常一样实现OnClickListener

public class SelectFilterActivity extends Activity implements OnClickListener {
  private static final int SWIPE_MIN_DISTANCE = 120;
  private static final int SWIPE_MAX_OFF_PATH = 250;
  private static final int SWIPE_THRESHOLD_VELOCITY = 200;
  private GestureDetector gestureDetector;
  View.OnTouchListener gestureListener;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    /* ... */
    // Gesture detection
    gestureDetector = new GestureDetector(this, new MyGestureDetector());
    gestureListener = new View.OnTouchListener() {
      public boolean onTouch(View v, MotionEvent event) {
        return gestureDetector.onTouchEvent(event);
      }
    };
  }
  class MyGestureDetector extends SimpleOnGestureListener {
    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
      try {
        if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH)
          return false;
        // right to left swipe
        if(e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
          Toast.makeText(SelectFilterActivity.this, "Left Swipe", Toast.LENGTH_SHORT).show();
        } else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
          Toast.makeText(SelectFilterActivity.this, "Right Swipe", Toast.LENGTH_SHORT).show();
        }
      } catch (Exception e) {
         // nothing
      }
      return false;
    }
    @Override
    public boolean onDown(MotionEvent e) {
      return true;
    }
  }
}

将手势监听器附加到添加到主布局的所有视图;

// Do this for each view added to the grid
imageView.setOnClickListener(SelectFilterActivity.this); 
imageView.setOnTouchListener(gestureListener);

当你的重写方法被调用时感到惊奇,包括activity的onClick(View v)和手势监听器的onFling

public void onClick(View v) {
  Filter f = (Filter) v.getTag();
  FilterFullscreenActivity.show(this, input, f);
}

后续的“fling”舞蹈是可选的,但值得鼓励。

0