【发布时间】:2014-05-04 05:26:53
【问题描述】:
在我的应用程序中,我必须将视图移动到布局上的任何位置。所以我使用了onTouchListener。在onClick 和onLongClick 上,我必须执行一些其他任务。我可以移动视图。但是,听众之间存在冲突。当我移动视图时,有时会调用onClick 或onLongClick。而且,当用户移动视图时,我不希望它们被调用。我怎样才能避免这种情况?我已经提到了这个link 来交叉检查我的代码。但是,找不到错误。以下是我的代码:
OnTouch 视图
broItemView.setOnTouchListener(new View.OnTouchListener() {
private int deltaX;
private int deltaY;
private float initialTouchX;
private float initialTouchY;
private boolean isMoved;
private int lastTouchX;
private int lastTouchY;
@Override
public boolean onTouch(final View v, final MotionEvent event) {
ViewGroup vg = (ViewGroup) v.getParent();
draggedViewIndex = vg.indexOfChild(v);
initialTouchX = event.getRawX();
initialTouchY = event.getRawY();
boolean result = v.onTouchEvent(event);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
isMoved = false;
FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) v
.getLayoutParams();
deltaX = (int) initialTouchX - params.leftMargin;
deltaY = (int) initialTouchY - params.topMargin;
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
if (!isMoved
&& event.getAction() != MotionEvent.ACTION_UP) {
ViewGroup vg = (ViewGroup) v
.getParent();
draggedViewIndex = vg.indexOfChild(v);
ClipData data = ClipData.newPlainText(
"", "");
DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(
v);
v.startDrag(data, shadowBuilder, v, 0);
v.setVisibility(View.INVISIBLE);
Animation slideUp = AnimationUtils
.loadAnimation(
WMMBFragmentContainerActivity.this,
R.anim.slide_up_dialog);
crossImage.setVisibility(View.VISIBLE);
crossImage.startAnimation(slideUp);
}
}
});
}
}, 1000);
break;
}
case MotionEvent.ACTION_MOVE: {
Log.e(TAG, "ACTION_MOVE");
FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) v
.getLayoutParams();
params.leftMargin = (int) initialTouchX - deltaX;
params.topMargin = (int) initialTouchY - deltaY;
v.setLayoutParams(params);
isMoved = true;
break;
}
case MotionEvent.ACTION_UP: {
Log.e(TAG, "ACTION_UP");
initialTouchX = 0;
initialTouchY = 0;
deltaX = 0;
deltaY = 0;
if (!isMoved) {
Log.e(TAG, "ACTION_UP if");
showRunningTransactionFragment(mBroList
.get(draggedViewIndex));
} else {
Log.e(TAG, "ACTION_UP else");
isMoved = false;
}
break;
}
default:
Log.e(TAG, "default");
return result;
}
relBroCircle.invalidate();
Log.e(TAG, "defaultqqq ");
return true;
}
});
更新 1:
所以,根据下面 Viswanath 的建议,我修改了我的代码。但是,我仍然面临问题。当我移动onTouch 中的视图时,有时,我在处理程序中编写的代码会被执行。我不希望在用户移动视图时执行此操作。我想让它顺利成为 Facebook 信使 ChatHeads。它们的onClick or onLongClick 仅在用户想要执行它们时被调用。我不明白我在哪里犯了错误。
更新 2:
现在,我删除了多个侦听器并尝试在onTouch 中执行所有我想要的操作。它的工作除了一个问题。即使我点击视图(直到现在我还没有移动视图),ACTION_MOVE 被调用,因此isMoved 变为 true。因此,在这种情况下,ACTION_UP 中的 if block 中的代码永远不会被执行。为了查明我是否做错了什么,我创建了一个虚拟项目,选择了textview 并添加了onTouchListener 和onClickListener。然后,进行点击操作。此外,我发现ACTION_MOVE 在onClick 之前首先被调用,然后onClick 中的代码被执行。那么,我怎样才能得到onClick 效果呢?我已经更新了我的代码。
【问题讨论】:
-
不要设置多个监听器。最好在 onTouchListener 中处理所有这些事情
-
按照 Viswanath 之前的建议进行了尝试,但有时,处理程序中的代码在移动视图时会被执行。我已经更新了我的代码。