问题
I'm currently trying to implement Drag and Drop between two Fragments. I already added them both to my Activity like this
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.add(R.id.leftContainer, new MainActivityFragment());
ft.add(R.id.rightContainer, new CartFragment());
ft.commit();
I have several CardViews in my MainActivityFragment. I'd like to drag them over to a ListView in my CartFragment. Then I'd add a new item to this ListView after the CardView has been dropped.
I've added this code in my MainActivityFragment so far
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View currentView = inflater.inflate(R.layout.fragment_main, container, false);
firstProduct = (LinearLayout) currentView.findViewById(R.id.firstProduct);
firstProduct.setOnTouchListener(new MyTouchListener());
return currentView;
}
private final class MyTouchListener implements View.OnTouchListener {
public boolean onTouch(View view, MotionEvent motionEvent) {
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
ClipData data = ClipData.newPlainText("", "");
View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view);
view.startDrag(data, shadowBuilder, view, 0);
return true;
} else {
return false;
}
}
}
class MyDragListener implements View.OnDragListener {
Drawable enterShape = getResources().getDrawable(R.drawable.drag_overlay);
@Override
public boolean onDrag(View v, DragEvent event) {
int action = event.getAction();
switch (event.getAction()) {
case DragEvent.ACTION_DRAG_STARTED:
// do nothing
v.setBackgroundDrawable(enterShape);
break;
case DragEvent.ACTION_DRAG_ENTERED:
break;
case DragEvent.ACTION_DRAG_EXITED:
break;
case DragEvent.ACTION_DROP:
// Dropped, reassign View to ViewGroup
View view = (View) event.getLocalState();
view.setVisibility(View.VISIBLE);
break;
case DragEvent.ACTION_DRAG_ENDED:
default:
break;
}
return true;
}
}
If the CardView I want to drag and the ListView I want to drop it on would be in the same View, I'd just just say
listView.setOnDragListener(new MyDragListener());
But since I can't access the ListView because it's in a different Fragment I have no idea how to do this.
I've already seen this thread drag-and-drop-between-two-fragments
but still I can't figure it out.
Hope I described it well enough, thanks in advance!
回答1:
I came across this same issue and found an excellent way to implement this using abstract classes. You can write your abstract class:
public abstract class SomeFragment extends Fragment{
//add your touch and drag listeners here
}
And then have your two classes that originally extended Fragment extend your abstract class instead:
public class MainActivityFragment extends SomeFragment{
}
Since your listeners were defined in your abstract class, these assignments would be allowed:
public class CartFragment extends SomeFragment{
listView.setOnDragListener(new MyDragListener());
}
And, your subclasses like CartFragment will still be of type Fragment because SomeFragment is of type Fragment.
回答2:
The onDrag method must be implemented inside that fragment that will be accepting the DragEvent.Action_Drop case, and then you set this method on to the view(Fragment view) that you want to accept the dropped view
来源:https://stackoverflow.com/questions/29283904/drag-and-drop-view-between-two-fragments