在Android中检测手指滑动到哪个视图

9

虽然过去曾经有类似的问题被提出,但它们似乎没有得到真正的解答,这可能是由于对问题本身的混淆。

简单地说,我想检测当您的手指在屏幕上滑动时进入了哪个视图。在任何Android手机上,这种情况最好的例子就是软键盘。当您按下任何键时,它会显示为弹出窗口,告诉您您的手指下面的字母是什么。如果您现在以单个手势移动手指在键盘上滑动,各种字母会随着您在字母表上移动而弹出。

用于此类行为的监听器是什么?我尝试过OnTouchListeners,但它们似乎只适用于您“触摸”按钮而不是“滑过”它们。

Button button = (Button)findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
  @Override
  public void onClick(View v) {doStuff();}
});

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

OnFocusChangeListener也无法帮助。


只是为了明确,我想要在辅助功能模式下获得类似iPhone的行为。您可以在屏幕上拖动手指,并它会宣布您正在移动的图标。 - Tim
6个回答

8
  • create a Layout
  • add Views to your Layout
  • set the setOnTouchListener to your Layout
  • override the onTouch method with the following:

    public boolean onTouch(View v, MotionEvent event) 
    {
       LinearLayout layout = (LinearLayout)v;
    
        for(int i =0; i< layout.getChildCount(); i++)
        {
    
            View view = layout.getChildAt(i);
            Rect outRect = new Rect(view.getLeft(), view.getTop(), view.getRight(), view.getBottom());
            if(outRect.contains((int)event.getX(), (int)event.getY()))
            {
                                 // over a View
            }
        }
    }
    

3

编辑:

我看到了键盘。我想,它只是一个视图,每个字母的坐标都已知。因此,您可以轻松计算用户滑过的字母。

现在回答:

我不确定,但可能这段代码可以帮助您。

迄今为止,我写了这个代码给自己使用。但是思路如下:

如果我没记错的话,视图没有手势检测器,但您可以将视图的触摸监听器与您的活动的手势监听器结合使用。

一旦您触摸了视图,您就有了

private GestureDetector mGestureDetector;

// x and y coordinates within our view
private static float sideIndexX;
private static float sideIndexY;

@Override
public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    ...
    mGestureDetector = new GestureDetector(this, new SideIndexGestureListener());
}

class MyGestureListener extends
        GestureDetector.SimpleOnGestureListener
{
    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2,
            float distanceX, float distanceY)
    {
        // we know already coordinates of first touch
        // we know as well a scroll distance
        sideIndexX = sideIndexX - distanceX;
        sideIndexY = sideIndexY - distanceY;

        // when the user scrolls within our side index
        // we can show for every position in it a proper
        // item in the country list
        if (sideIndexX >= 0 && sideIndexY >= 0)
        {
            doStuff();
        }

        return super.onScroll(e1, e2, distanceX, distanceY);
    }
}    

button.setOnTouchListener(new OnTouchListener()
{
    @Override
    public boolean onTouch(View v, MotionEvent event)
    {
        // now you know coordinates of touch
        // store them
        sideIndexX = event.getX();
        sideIndexY = event.getY();

        doStuff();

        return false;
    }
});

0

手动处理这个问题相当简单。

使用父布局作为onTouchListener(在下面的示例中,我extend了一个RelativeLayout),您可以使用简单的坐标比较逻辑检查MotionEvent和子View之间的碰撞:

/** Returns the View colliding with the TouchEvent. */
private final View getCollisionWith(final MotionEvent pMotionEvent) {
    // Declare the LocationBuffer.
    final int[] lLocationBuffer = new int[2];
    // Iterate the children.
    for(int i = 0; i < this.getChildCount(); i++) { /** TODO: Order. */
        // Fetch the child View.
        final View lView = this.getChildAt(i);
        // Fetch the View's location.
        lView.getLocationOnScreen(lLocationBuffer);
        // Is the View colliding?
        if(pMotionEvent.getRawX() > lLocationBuffer[0] && pMotionEvent.getRawX() < lLocationBuffer[0] + lView.getWidth() && pMotionEvent.getRawY() > lLocationBuffer[1] && pMotionEvent.getRawY() < lLocationBuffer[1] + lView.getHeight()) {
           // Return the colliding View.
           return lView;
        }
    }
    // We couldn't find a colliding View.
    return null;
}

调用 getCollisionWith 将返回可以任意操作的 View 引用。


0

谢谢,但我仍然不确定如何使用它。我尝试在我的活动中实现GestureDetector.OnGestureListener。我在所有断点处设置了断点,但当我在屏幕上滚动时,它们似乎从未被调用过。类似于这个 - Tim

0

1
谢谢,丹。看起来似乎没有针对手指“穿过”特定视图的监听器。 - Tim
我已经陷入黑莓地狱很长一段时间了,但上次我处理 Android 项目时,我相信我使用了每个视图来检查其自身边界与 TouchEvent 的关系,以便确定 TouchEvent 进入... - Dan

0
简短的回答是不行,不能像 iPhone 的辅助功能模式一样。
直到冰激凌三明治(Android 4.0)发布之前都不行。现在它具有类似 iPhone 的功能,能够在你手指未离开屏幕时识别出下面的元素。

那么你如何做到这一点呢? - jacosta
它在手机的辅助功能菜单中被称为Talkback。 - Tim
什么?我的意思是为了开发。 - jacosta

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接