I have an app and it has been working well. However, after I upgraded the phone to Android 7.0, the drag and drop function was broken. And if I further upgrade the phone to Android 7.1, it works well again.
And then I created a test app to find out the cause, but I can only "prove" that it has something to do with the nested EditText inside a RelativeLayout.
Here is the code to show the log:
private class EntryHolder{
View mEntryLayout;
View mEntryContainer;
}
void addView() {
EntryHolder eh = new EntryHolder();
eh.mEntryLayout = getLayoutInflater()
.inflate(R.layout.edit_item, mContainer, false);
eh.mEntryContainer = eh.mEntryLayout.findViewById(R.id.field_container);
eh.mEntryContainer.setTag(eh);
eh.mEntryLayout.setTag(eh);
mContainer.addView(eh.mEntryLayout, mIndex++);
eh.mEntryContainer.setOnLongClickListener(this);
eh.mEntryLayout.setOnDragListener(mDragListener);
}
private class DragListener implements View.OnDragListener {
String[] ACTIONS = {"---", "STARTED ", "LOCATION ", "DROP ",
"ENDED ", "ENTERED ", "EXITED "};
@Override
public boolean onDrag(View view, DragEvent dragEvent) {
int action = dragEvent.getAction();
Log.d("Drag&Drop", ACTIONS[action]+view.toString());
switch(action) {
case DragEvent.ACTION_DRAG_STARTED:
case DragEvent.ACTION_DRAG_ENTERED:
case DragEvent.ACTION_DRAG_ENDED:
case DragEvent.ACTION_DRAG_LOCATION:
case DragEvent.ACTION_DROP:
return true;
}
return false;
}
@Override
public boolean onLongClick(View view) {
ClipData not_used_clip = ClipData.newPlainText("", "");
EntryHolder eh = (EntryHolder)view.getTag();
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
eh.mEntryLayout.startDrag(not_used_clip, new View.DragShadowBuilder(eh.mEntryLayout),
eh.mEntryLayout, 0);
}
else {
eh.mEntryLayout.startDragAndDrop(not_used_clip, new View.DragShadowBuilder(eh.mEntryLayout),
eh.mEntryLayout, 0);
}
view.setAlpha(0.0f);
return true;
}
in onCreateView method of the test activity, addView is called 3 times to dynamically add 3 of the frame_layout.
If I put the frame_layout xml this way:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:elevation="8dp">
<RelativeLayout android:id="@+id/field_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="4dp"
android:paddingBottom="4dp"
android:longClickable="true"
android:background="@android:color/holo_blue_bright">
<LinearLayout android:id="@+id/line1"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="36dp">
<!--Something is supposed to be here-->
</LinearLayout>
<EditText
android:id="@+id/field_value"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Value"
android:layout_below="@id/line1"
android:textAppearance="@style/TextAppearance.AppCompat.Body2"/>
</RelativeLayout>
</FrameLayout>
The output in logcat would simply be the following in Android API 24,
...D/Drag&Drop: STARTED android.widget.FrameLayout{63144b4 ...
...D/Drag&Drop: STARTED android.widget.FrameLayout{231eb23 ...
...D/Drag&Drop: STARTED android.widget.FrameLayout{d141b9e ...
...D/Drag&Drop: ENDED android.widget.FrameLayout{63144b4 ...
...D/Drag&Drop: ENDED android.widget.FrameLayout{d141b9e ...
...D/Drag&Drop: ENDED android.widget.FrameLayout{231eb23 ...
In other versions (including API 23- and API 25), the output would be much more with ENTERED, LOCATION and EXITED
If I remove the RelativeLayout in the middle or if I remove the EditText, then it is fine in API 24 as well. But I need that level of layout in my actual app so I cannot solve it this way.
Can anybody have any suggestions on the problem? Thank you!