安卓系统中,手势是否可以覆盖在可点击的小部件上?

8

我的应用程序包含一个按钮区域。我希望实现的功能是,通过在按钮区域上进行fling手势可以将其切换到另外两个区域(使用ViewFlipper)。

我使用了两种方法来检测手势。第一种方法涉及使用GestureDetector。然而,按钮上的触摸运动事件并没有触发onTouchEvent活动方法,因此,我无法将其转发到GestureDetector类。简而言之,失败了。

第二种方法涉及使用GestureOverlayView。这次,我达到了第二个极端:不仅检测到了手势,还有按钮,手势是在其上执行的。

我希望界面的工作方式如下:如果用户触摸按钮并释放触摸(或只移动手指很少),则按钮报告单击事件,并且不检测手势。另一方面,如果用户触摸屏幕并进行较长的移动,则应检测手势,并且按钮不会报告单击事件。

我已经实现了一个小型概念验证应用程序。活动XML代码如下:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout android:layout_width="match_parent" android:layout_height="match_parent"  xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical">
  <android.gesture.GestureOverlayView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/overlay">
    <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical">
    <TextView android:id="@+id/display" android:layout_width="match_parent" android:layout_height="wrap_content" />
    <Button android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/button"/>
    </LinearLayout>
  </android.gesture.GestureOverlayView>
</LinearLayout>

活动的Java代码如下:
package spk.sketchbook;

import android.app.Activity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import android.gesture.*;
import android.gesture.GestureOverlayView.OnGestureListener;

public class Main extends Activity implements OnGestureListener, OnClickListener
{       
  private void SetupEvents()
  {
    GestureOverlayView ov = (GestureOverlayView)findViewById(R.id.overlay);
    ov.addOnGestureListener(this);

    Button b = (Button)findViewById(R.id.button);
    b.setOnClickListener(this);
  }

  /** Called when the activity is first created. */
  @Override
  public void onCreate(Bundle savedInstanceState)
  {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.main);

    SetupEvents();
  }

  @Override
  public void onGesture(GestureOverlayView arg0, MotionEvent arg1)
  {
    TextView tv = (TextView)findViewById(R.id.display);
    tv.setText("Gesture");
  }

  @Override
  public void onGestureCancelled(GestureOverlayView arg0, MotionEvent arg1)
  {

  }

  @Override
  public void onGestureEnded(GestureOverlayView overlay, MotionEvent event)
  {

  }

  @Override
  public void onGestureStarted(GestureOverlayView overlay, MotionEvent event)
  {

  }

  @Override
  public void onClick(View v)
  {
    TextView tv = (TextView)findViewById(R.id.display);
    tv.setText("Click");
  }


}

问题是:如何实现这样的接口,它可以决定是否将用户操作视为手势或按钮点击?
最好的问候 - Spook。

这是一个关于Android基本手势检测的问题。如果没有人直接回答,这可能会有所帮助。 - CityView
2个回答

3
我解决了这个问题。方法是从GestureOverlayView中捕获手势事件,并在将它们传递给GestureDetector之外,测量用户手势的距离。该距离应存储在私有活动字段中(因此可用于所有事件处理程序)。最后,fling和click处理程序应检查此字段的值;如果它低于某个值(比如说,10像素就可以了),则应将其解释为点击。否则-作为手势。
请注意,按钮既会显示为被点击,并且其单击处理程序也将被调用。我决定创建一个低级别的单击处理程序(附加到所有按钮上方的GestureOverlayView),进行手势/单击检查,并且如果结果是单击,则选择更高级别的单击处理程序之一。
解决方案对我有效;然而,如果有人希望禁用按钮的点击效果并防止处理程序被调用,则可能需要重新定义按钮和/或GestureOverlayView组件。

2

另一种解决方案:

将此函数改为:

public void SetSwipe(View v, final GestureDetector gestureScanner){
    // Sets scroll view listener
    v.setOnTouchListener(new OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
              if (gestureScanner.onTouchEvent(event))  
                return true;  
              else  
                return false;  
        }
    });
}

并且对于每个小部件,按照以下方式进行调用:

scfSetTag.SetSwipe(svAllView, gestureScanner);

如果您需要从多个活动或片段创建这个功能,您可以创建一个class.java文件,并在需要实现滑动的每个活动中实例化这个类。这将检测到对任何小部件的滑动和点击操作。希望能够帮到您!

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