我一直试图弄清楚Android中ScrollViews中MotionEvents的行为,这是我无法弄清楚的.
作为一个例子,我创建了一个Activity,里面有一个ScrollView,ScrollView里面有一个LinearLayout.我实现了自己的类来控制与触摸相关的功能:
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MyInnerLayout inner = new MyInnerLayout(getApplicationContext());
MyLayout layout = new MyLayout(getApplicationContext());
layout.addView(inner,new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT));
setContentView(layout);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
Log.i("scrollview","activity dispatchTouchEvent "+ev.getAction());
return super.dispatchTouchEvent(ev);
};
@Override
public boolean onTouchEvent(MotionEvent ev) {
Log.i("scrollview","activity on touch "+ev.getAction());
return super.onTouchEvent(ev);
}
public class MyLayout extends ScrollView {
public MyLayout(Context context) {
super(context);
}
@Override
public boolean dispatchKeyEvent(KeyEvent ev) {
Log.i("scrollview","layout dispatchKeyEvent "+ev.getAction());
return super.dispatchKeyEvent(ev);
}
@Override …Run Code Online (Sandbox Code Playgroud) 我能够使用 MotionEvent.obtain 在典型的 android 视图(文本框、按钮等)上模拟点击事件,如下所示:
int meta_state = 0;
MotionEvent motionEvent = MotionEvent.obtain(
SystemClock.uptimeMillis(),
SystemClock.uptimeMillis(),
MotionEvent.ACTION_DOWN,
x,
y,
meta_state
);
motionEvent.recycle();
view_tapped.dispatchTouchEvent(motionEvent);
Run Code Online (Sandbox Code Playgroud)
view_tapped 是对我要将事件发送到的视图的引用。但是,当我在 webview 上调用 dispatchTouchEvent 时,它似乎没有点击里面的任何元素。
我还在 webview 中放置了一个 onTouchListener,然后当视图被手指实际点击时转储与motionevent 相关的所有信息,然后创建一个具有所有相同信息的新motionevent 并将其分派到webview,它没有点击屏幕。onTouchListener 仍然被触发,但屏幕上的元素没有被点击。
我还尝试使用 Javascript 来完成它,通过尝试找出特定坐标处的元素,然后通过注入 javascript 来触发 click 事件,但也没有运气。
关于我做错了什么的任何想法?
我有一个自定义ViewGroup覆盖onInterceptTouchEvent().它接收ACTION_DOWN但从未收到ACTION_MOVE.我的理解是,除非它返回"true",否则它应该接收所有MotionEvent.
ViewGroup包含两个视图,一个ImageView和一个GridLayout.
我的拦截代码是:
@Override
public boolean onInterceptTouchEvent(MotionEvent ev)
{
final int action = ev.getAction();
switch (action & MotionEvent.ACTION_MASK)
{
case MotionEvent.ACTION_DOWN:
logD ("DDV Intercept DOWN");
break;
case MotionEvent.ACTION_POINTER_DOWN:
logD ("DDV Intercept P DOWN"); // logD: shell around Log.d()
break;
case MotionEvent.ACTION_MOVE:
logD ("DDV Intercept MOVE");
break;
case MotionEvent.ACTION_UP:
logD ("DDV Intercept UP");
break;
case MotionEvent.ACTION_POINTER_UP:
logD ("DDV Intercept P UP " + ev.getActionIndex());
break;
case MotionEvent.ACTION_CANCEL:
logD ("DDV Intercept CANCEL");
break;
default:
logD ("DDV Intercept " + (action & MotionEvent.ACTION_MASK)); …Run Code Online (Sandbox Code Playgroud) 我注意到该函数在Action_down之后没有中断,那么代码可以运行到ACTION_MOVE,是吗?
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
ensureTarget();
final int action = MotionEventCompat.getActionMasked(ev);
if (mReturningToStart && action == MotionEvent.ACTION_DOWN) {
mReturningToStart = false;
}
if (!isEnabled() || mReturningToStart || canChildScrollUp() || mRefreshing) {
// Fail fast if we're not in a state where a swipe is possible
return false;
}
switch (action) {
case MotionEvent.ACTION_DOWN:
setTargetOffsetTopAndBottom(mOriginalOffsetTop - mCircleView.getTop(), true);
mActivePointerId = MotionEventCompat.getPointerId(ev, 0);
mIsBeingDragged = false;
final float initialMotionY = getMotionEventY(ev, mActivePointerId);
if (initialMotionY == -1) {
return false;
} …Run Code Online (Sandbox Code Playgroud) 这似乎是android中相当普遍的模式.我正在尝试创建类似Facebook显示广告的方式:
您可以看到它们具有外部垂直回收视图,内部水平回收视图作为外部垂直recyclerview适配器中的项目之一.
我按照Google的指南"在ViewGroup中管理触摸事件" - http://developer.android.com/training/gestures/viewgroup.html,因为Recyclerview扩展了ViewGroup,其代码类似于我想要做的.
我对它进行了一些定制,以便检测Y轴的移动而不是X轴的移动,并将其应用到外部垂直再循环视图.
/**
* Created by Simon on 10/11/2015.
*///This is the recyclerview that would allow all vertical scrolls
public class VerticallyScrollRecyclerView extends RecyclerView {
public VerticallyScrollRecyclerView(Context context) {
super(context);
}
public VerticallyScrollRecyclerView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public VerticallyScrollRecyclerView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
ViewConfiguration vc = ViewConfiguration.get(this.getContext());
private int mTouchSlop = vc.getScaledTouchSlop();
private boolean mIsScrolling;
private float startY;
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
final int …Run Code Online (Sandbox Code Playgroud) android touch-event android-layout motionevent android-recyclerview
我正在制作非常简单的应用程序。它需要显示一个包含广义世界地图的 SVG。通过单击城市名称(svg 矩形),我需要显示与该城市对应的另一个 SVG。此外,所有 SVG 都必须支持缩放和平移。
我设法让 SVG 支持缩放和平移,效果很好。为此,我使用svg-android库来渲染SVG,并使用定制的TouchImageView进行平移、缩放和捕获缩放和触摸事件。但是,在 Android 中的 SVG 上制作可点击区域似乎是不可能的。
我尝试了蛮力,在每次用户交互(触摸或缩放)和每次点击 SVG 时重新计算我感兴趣区域的位置,以检查我的区域(矩形列表)是否包含该点,并执行相应的操作。
这不起作用,因为我无法理解计算规则MotionEvent#getX/Y和类似方法。也许我可以为固定 SVG 实现这一点,但对于可缩放,我真的不能。
任何提示?这在Android中甚至可能吗?
我必须计算点击屏幕的手指总数。
使用的触摸事件如下:
relTouch.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch(event.getPointerCount()){
case 1:
Toast.makeText(MainActivity.this, "Single touch", Toast.LENGTH_SHORT).show();
break;
case 2:
Toast.makeText(MainActivity.this, "Double touch", Toast.LENGTH_SHORT).show();
break;
case 3:
Toast.makeText(MainActivity.this, "Triple touch", Toast.LENGTH_SHORT).show();
break;
}
return true;
}
});
Run Code Online (Sandbox Code Playgroud)
运行良好。
但是,问题是当我用多个手指点击时,它也会给我单击一下。如果我用 3 个手指点击,它也会给我单击和双击。
如何解决这个问题?
我听说过:
MotionEvent e;
float press = e.getPressure(...);
Run Code Online (Sandbox Code Playgroud)
但是这只会在没有触摸时返回0,而在我的手指触摸屏幕时则返回1.
是否可以通过触摸电容屏找到手指放在屏幕上的压力值?
或者我的预感是否正确,这只适用于电阻屏幕..?
我指的是一些网站,例如 http://developer.android.com/reference/android/view/MotionEvent.html http://www.vogella.com/tutorials/AndroidTouch/article.html 来学习 MotionEvent 来设计用户界面。问题是我对诸如pointerIndex、Id、getActionIndex、getActionMasked 等术语以及与MotionEvent 相关的其他重要方法感到困惑。
我有一个onTouchListenerfor 我LinearLayout的ListViews 并且我正在尝试使用ACTION_DOWN和ACTION_UP数据来检测用户何时滑动到下一个ListView. 然而,MotionEventnever equals ACTION_DOWN,虽然ACTION_UP工作完美。经过大量的谷歌搜索,我能找到的唯一解决方案是在调用事件时返回 true,但我已经这样做了。这是我的onTouchListener代码
View.OnTouchListener mTouchListener = new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
downX = event.getX();
return true;
} else if (event.getAction() == MotionEvent.ACTION_UP) {
upX = event.getX();
if(userSwipedFarEnough)
doStuff()
return true;
}
return false;
}
};
Run Code Online (Sandbox Code Playgroud) android ×10
motionevent ×10
touch ×3
touch-event ×2
java ×1
pressure ×1
scrollview ×1
svg ×1
svg-android ×1
webview ×1