Android上拖放按钮的问题



我希望能够在用户拖动按钮时移动按钮。我使用的是API 11级中引入的拖放API,它可以工作。这是代码:

public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
final Button button = (Button) findViewById(R.id.button);
button.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
v.startDrag(null, new View.DragShadowBuilder(v), null, 0);
return true;
}
});
findViewById(R.id.test_main_layout).setOnDragListener(new View.OnDragListener() {
@Override
public boolean onDrag(View v, DragEvent event) {
switch (event.getAction()) {
case DragEvent.ACTION_DRAG_STARTED:
button.setVisibility(View.INVISIBLE);
break;
case DragEvent.ACTION_DROP:
button.setY(event.getY() - button.getHeight() / 2.F);
button.setX(event.getX() - button.getWidth() / 2.F);
break;
case DragEvent.ACTION_DRAG_ENDED:
button.setVisibility(View.VISIBLE);
break;
}
return true;
}
});
}
}
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:id="@+id/test_main_layout"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/edit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/edit"
android:text="Some text"/>
</RelativeLayout>

目前的行为是,当用户按住按钮时,它会消失,它的"阴影"会出现并被拖动。然后,拖动完成后,阴影将替换为实际按钮。

它的工作方式有两个问题:

  1. 当用户停止拖动时,它会有一个看起来很糟糕的闪烁?看起来好像有一小段时间阴影消失了,真正的按钮还没有显示出来。有可能以某种方式摆脱它吗?

  2. 当EditText具有焦点时,行为会发生变化。只需将XML中的TextView更改为EditText即可复制它。通过此更改,拖动阴影时原始按钮不会消失,两者都可见!为什么会这样,以及如何解决?

我正在两个设备上测试它,一个是5.0.1,另一个是5.1,行为一致(两个问题)。

原来问题#2(按钮没有消失)是由以下原因引起的:https://code.google.com/p/android/issues/detail?id=25073.简而言之,由于某些原因,带有ACTION_DRAG_STARTED的mu onDrag()从未被调用,因为EditText(或实际上是TextView)#onDragEvent在具有焦点时返回true:

case DragEvent.ACTION_DRAG_STARTED:
return mEditor != null && mEditor.hasInsertionController();

在这种情况下,mEditor不为null。对我来说,我改变了逻辑,不依赖于被调用的启动,将代码移到其他地方,它工作得很好。

最新更新