我正在尝试为我的android应用程序实现一个定制的拖放(一种简化的块状方法)。问题是我有一组可用的动作,在左边,我想把它们拖到右边,代表动作的连续性。拖放过程工作得很好,但是我还有最后一件事要做。我希望原来的街区保持原貌。但就目前而言,它消失时,下降完成。
下面是我的应用程序的一些插图:拖放
以下是我目前的代码:
@Override
public boolean onDrag(View v, DragEvent event) {
int action = event.getAction();
switch (action) {
case DragEvent.ACTION_DRAG_STARTED:
// Determines if this View can accept the dragged data
if (event.getClipDescription().hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN)) {
return true;
}
return false;
case DragEvent.ACTION_DRAG_ENTERED:
v.getBackground().setColorFilter(Color.GRAY, PorterDuff.Mode.SRC_IN);
v.invalidate();
return true;
case DragEvent.ACTION_DRAG_LOCATION:
// Ignore the event
return true;
case DragEvent.ACTION_DRAG_EXITED:
v.getBackground().clearColorFilter();
v.invalidate();
return true;
case DragEvent.ACTION_DROP:
// Gets the item containing the dragged data
ClipData.Item item = event.getClipData().getItemAt(0);
// Gets the text data from the item.
String dragData = item.getText().toString();
switch (dragData){
case ("Aller au POI"):
// SOME CODE
break;
default:
break;
}
v.getBackground().clearColorFilter();
v.invalidate();
View vw = (View) event.getLocalState();
ViewGroup owner = (ViewGroup) vw.getParent();
owner.removeView(vw); // I would like not to remove that
LinearLayout container = (LinearLayout) v;
container.addView(vw);
vw.setVisibility(View.VISIBLE);
return true;
case DragEvent.ACTION_DRAG_ENDED:
v.getBackground().clearColorFilter();
v.invalidate();
if (event.getResult())
//Toast.makeText(this, "The drop was handled.", Toast.LENGTH_SHORT).show();
Snackbar.make(findViewById(R.id.layout_dragged_mission_blocks), "Action ajoutée", Snackbar.LENGTH_LONG)
.show();
else
//Toast.makeText(this, "The drop didn't work.", Toast.LENGTH_SHORT).show();
Snackbar.make(findViewById(R.id.layout_dragged_mission_blocks), "Erreur à l'ajout de l'action", Snackbar.LENGTH_LONG)
.setBackgroundTint(Color.RED)
.show();
// returns true; the value is ignored.
return true;
// An unknown action type was received.
default:
Log.e("DragDrop Example", "Unknown action type received by OnDragListener.");
break;
}
return false;
}
我明白 owner.removeView(vw);
可能是问题所在,但当我删除此行时,会出现错误: java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
我做错什么了吗?
编辑
下面是一些附加代码:
onlongclick():
@Override
public boolean onLongClick(View v) {
// Create a new ClipData.Item from the ImageView object's tag
ClipData.Item item = new ClipData.Item((CharSequence) v.getTag());
// Create a new ClipData using the tag as a label, the plain text MIME type, and
// the already-created item. This will create a new ClipDescription object within the
// ClipData, and set its MIME type entry to "text/plain"
String[] mimeTypes = {ClipDescription.MIMETYPE_TEXT_PLAIN};
ClipData data = new ClipData(v.getTag().toString(), mimeTypes, item);
// Instantiates the drag shadow builder.
View.DragShadowBuilder dragshadow = new View.DragShadowBuilder(v);
// Starts the drag
v.startDragAndDrop(data // data to be dragged
, dragshadow // drag shadow builder
, v // local data about the drag and drop operation
, 0 // flags (not currently used, set to 0)
);
return true;
}
oncreate():
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mission_creation);
// SLAMWARE agent
mAgent = getSlamwareAgent();
// Toolbar
toolbar = findViewById(R.id.toolbar);
toolbar.setTitle("Génération de mission");
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.d(TAG, "Back from toolbar button pressed");
Intent returnIntent = new Intent();
setResult(RESULT_CANCELED, returnIntent);
finish();
}
});
// Blockly-like Drag'n'drop
//Find all views and set Tag to all draggable views
goToPOI_block_tv = (TextView) findViewById(R.id.go_to_POI_block);
goToPOI_block_tv.setTag(goToPOI_block_tv.getText().toString());
goToPOI_block_tv.setOnLongClickListener(this);
wait_duration_block_tv = (TextView) findViewById(R.id.wait_duration_block);
wait_duration_block_tv.setTag(wait_duration_block_tv.getText().toString());
wait_duration_block_tv.setOnLongClickListener(this);
wait_action_block_tv = (TextView) findViewById(R.id.wait_action_block);
wait_action_block_tv.setTag(wait_action_block_tv.getText().toString());
wait_action_block_tv.setOnLongClickListener(this);
say_block_tv = (TextView) findViewById(R.id.say_block);
say_block_tv.setTag(say_block_tv.getText().toString());
say_block_tv.setOnLongClickListener(this);
go_home_block_tv = (TextView) findViewById(R.id.go_home_block);
go_home_block_tv.setTag(go_home_block_tv.getText().toString());
go_home_block_tv.setOnLongClickListener(this);
//Set Drag Event Listeners for defined layouts
// TODO gérer le cas où on remet le block dans la palette d'actions
findViewById(R.id.layout_available_mission_blocks).setOnDragListener(new View.OnDragListener() {
@Override
public boolean onDrag(View v, DragEvent event) {
// Log.d(TAG, "Entering onDragListener");
switch (event.getAction()) {
case DragEvent.ACTION_DRAG_STARTED:
return true;
case DragEvent.ACTION_DROP:
ClipData clipData = event.getClipData();
//...
return false;
default:
return false;
}
}
});
findViewById(R.id.layout_dragged_mission_blocks).setOnDragListener(this);
save_mission_b = (Button) findViewById(R.id.save_mission_fab);
actionsToExportLayout = findViewById(R.id.layout_dragged_mission_blocks);
saveMission();
}
布局xml
<androidx.drawerlayout.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".activity.MissionCreationActivity">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".BlocklyActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="56dp"
android:orientation="horizontal"
tools:layout_editor_absoluteX="-2dp"
android:focusable="true"
android:focusableInTouchMode="true">
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical"
app:cardUseCompatPadding="false"
app:cardElevation="8dp"
app:cardCornerRadius="3dp">
<LinearLayout
android:id="@+id/layout_available_mission_blocks"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:paddingTop="50dp"
android:paddingLeft="40dp"
android:gravity="left"
android:background="#FFFFFF"
android:orientation="vertical">
<com.google.android.material.chip.Chip
android:id="@+id/go_to_POI_block"
style="@style/Widget.MaterialComponents.Chip.Action"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:chipIcon="@drawable/pin_icon"
android:text="Aller au POI"
app:chipBackgroundColor="@color/transparent_red"
/>
<Space
android:layout_width="match_parent"
android:layout_height="15dp"/>
<com.google.android.material.chip.Chip
android:id="@+id/wait_duration_block"
style="@style/Widget.MaterialComponents.Chip.Action"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:chipIcon="@drawable/wait_icon"
android:text="Attendre (durée)"
app:chipBackgroundColor="@color/transparent_green"
/>
<Space
android:layout_width="match_parent"
android:layout_height="15dp"/>
<com.google.android.material.chip.Chip
android:id="@+id/wait_action_block"
style="@style/Widget.MaterialComponents.Chip.Action"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:chipIcon="@drawable/wait_action_icon"
android:text="Attendre (action)"
app:chipBackgroundColor="@color/transparent_blue"
/>
<Space
android:layout_width="match_parent"
android:layout_height="15dp"/>
<com.google.android.material.chip.Chip
android:id="@+id/go_home_block"
style="@style/Widget.MaterialComponents.Chip.Action"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:chipIcon="@drawable/home_icon"
android:text="Retour en base"
app:chipBackgroundColor="@color/transparent_violet"
/>
<Space
android:layout_width="match_parent"
android:layout_height="15dp"/>
<com.google.android.material.chip.Chip
android:id="@+id/say_block"
style="@style/Widget.MaterialComponents.Chip.Action"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:chipIcon="@drawable/say_icon"
app:chipBackgroundColor="@color/transparent_yellow"
android:text="Dire"
/>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
<LinearLayout
android:id="@+id/layout_dragged_mission_blocks"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight=".70"
android:background="#FFFFFF"
android:gravity="center"
android:orientation="vertical" >
</LinearLayout>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
android:id="@+id/save_mission_fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="32dp"
android:layout_marginRight="32dp"
android:text="Sauvegarder la mission"
app:icon="@drawable/check_icon"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_gravity="end|bottom" />
</RelativeLayout>
<include
layout="@layout/app_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</androidx.drawerlayout.widget.DrawerLayout>
暂无答案!
目前还没有任何答案,快来回答吧!