首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >网格布局中的Fling手势检测

网格布局中的Fling手势检测
EN

Stack Overflow用户
提问于 2009-06-01 23:35:31
回答 16查看 415.1K关注 0票数 1.2K

我想让fling手势检测在我的安卓应用程序中工作。

我所拥有的是一个包含9个GridLayoutImageView,源代码可以在这里找到:Romain Guys的网格布局

我拿的那个文件来自Romain的光流应用,并且只稍微修改了一下。

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

  • 如果我的活动实现了OnGestureListener,我不知道如何将其设置为Grid或添加的Image视图的手势侦听器。 公共类SelectFilterActivity扩展活动实现View.OnClickListener,OnGestureListener {.
  • 如果我的活动实现了OnTouchListener,那么我就没有onFling方法到override (它有两个事件作为参数,允许我确定fling是否值得注意)。 公共类SelectFilterActivity扩展活动实现View.OnClickListener,OnTouchListener {.
  • 如果我做了一个自定义的View,比如扩展ImageViewGestureImageView,我不知道如何从视图中知道fling已经发生了。在任何情况下,我尝试了这个方法,当我触摸屏幕时,这些方法没有被调用。

我真的需要一个跨视图工作的具体例子。什么,何时,以及如何附加这个listener?我需要能够检测到单一的点击也。

代码语言:javascript
复制
// 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;
        }
    }
});

是否有可能在我的屏幕顶部放置一个透明的视图来捕捉抛出的画面?

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

这是一个非常简单的活动,我试图让fling检测工作:SelectFilterActivity (改编自光流)

我一直在看这些消息来源:

  • 检测手势.教程
  • SDK文档
  • 计算器代码

到目前为止,没有什么对我有用,我希望得到一些指点。

EN

回答 16

Stack Overflow用户

回答已采纳

发布于 2009-06-02 09:30:55

感谢码Shogun,它的代码我适应了我的情况。

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

代码语言:javascript
复制
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;
    }
  }
}

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

代码语言:javascript
复制
// Do this for each view added to the grid
imageView.setOnClickListener(SelectFilterActivity.this); 
imageView.setOnTouchListener(gestureListener);

在被覆盖的方法被击中时,请敬畏地观察活动的onClick(View v)和手势侦听器的onFling

代码语言:javascript
复制
public void onClick(View v) {
  Filter f = (Filter) v.getTag();
  FilterFullscreenActivity.show(this, input, f);
}

在后“放纵”舞蹈是可选的,但鼓励。

票数 839
EN

Stack Overflow用户

发布于 2011-04-20 17:26:49

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

代码语言:javascript
复制
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)

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

票数 214
EN

Stack Overflow用户

发布于 2011-04-21 10:24:21

我的做法有点不同,并编写了一个实现View.onTouchListener的额外检测器类。

onCreate只是简单地将它添加到最低的布局中,如下所示:

代码语言:javascript
复制
ActivitySwipeDetector activitySwipeDetector = new ActivitySwipeDetector(this);
lowestLayout = (RelativeLayout)this.findViewById(R.id.lowestLayout);
lowestLayout.setOnTouchListener(activitySwipeDetector);

其中,id.lowestLayout是布局层次结构中视图最低的id.xxx,lowestLayout被声明为RelativeLayout

然后是实际的活动滑动检测器类:

代码语言:javascript
复制
public class ActivitySwipeDetector implements View.OnTouchListener {

static final String logTag = "ActivitySwipeDetector";
private Activity activity;
static final int MIN_DISTANCE = 100;
private float downX, downY, upX, upY;

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

public void onRightSwipe(){
    Log.i(logTag, "RightToLeftSwipe!");
    activity.doSomething();
}

public void onLeftSwipe(){
    Log.i(logTag, "LeftToRightSwipe!");
    activity.doSomething();
}

public void onDownSwipe(){
    Log.i(logTag, "onTopToBottomSwipe!");
    activity.doSomething();
}

public void onUpSwipe(){
    Log.i(logTag, "onBottomToTopSwipe!");
    activity.doSomething();
}

public boolean onTouch(View v, MotionEvent event) {
    switch(event.getAction()){
        case MotionEvent.ACTION_DOWN: {
            downX = event.getX();
            downY = event.getY();
            return true;
        }
        case MotionEvent.ACTION_UP: {
            upX = event.getX();
            upY = event.getY();

            float deltaX = downX - upX;
            float deltaY = downY - upY;

       // swipe horizontal?
        if(Math.abs(deltaX) > Math.abs(deltaY))
        {
            if(Math.abs(deltaX) > MIN_DISTANCE){
                // left or right
                if(deltaX > 0) { this.onRightSwipe(); return true; }
                if(deltaX < 0) { this.onLeftSwipe(); return true; }
            }
            else {
                    Log.i(logTag, "Horizontal Swipe was only " + Math.abs(deltaX) + " long, need at least " + MIN_DISTANCE);
                    return false; // We don't consume the event
            }
        }
        // swipe vertical?
        else 
        {
            if(Math.abs(deltaY) > MIN_DISTANCE){
                // top or down
                if(deltaY < 0) { this.onDownSwipe(); return true; }
                if(deltaY > 0) { this.onUpSwipe(); return true; }
            }
            else {
                    Log.i(logTag, "Vertical Swipe was only " + Math.abs(deltaX) + " long, need at least " + MIN_DISTANCE);
                    return false; // We don't consume the event
            }
        }

            return true;
        }
    }
    return false;
}

}

对我来说真的很好!

票数 152
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/937313

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档