How to drag and drop an image from a Recycler view and place it outside of it into another layout

喜你入骨 提交于 2019-12-24 06:43:01

问题


I have a horizontal Recylcer view which holds a list of items. Each item has a text view and image view to represent the item (e.g an image of a square and the text "Square" above the image). The recylcer view is inside of it's own relative layout positioned at the top of the screen. What I need to do is drag an image from the recycler view and drop it outside of it into another layout that is below this one. However, the image that is dragged from the recycler view must not be removed, but instead a copy of the image should be placed into the outside layout. The image must also be dropped in the exact position in the layout where the user releases their finger. Is there any way to achieve this?

An example of this could be like in a game, where the user has a list of objects to drag and drop into the game world.

Here's an example to illustrate what I mean:

Adapter class for Recycler View:

public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder> {

private List<ListItems> listItems;
private Context context;

public RecyclerAdapter(List<ListItems> listItems, Context context) {
    this.listItems = listItems;
    this.context = context;
}

@Override
public RecyclerAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View v = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.layout_recycler_view_row_one, parent, false);

    ViewHolder vh = new ViewHolder(v);
    return vh;
}

@Override
public void onBindViewHolder(RecyclerAdapter.ViewHolder holder, int position) {

    ListItems listItems = listItems.get(position);

    holder.textView.setText(listItems.getItemName());
    holder.imageView.setImageResource(listItems.getImageDrawable());
}


@Override
public int getItemCount() {
    return listItems.size();
}

public class ViewHolder extends RecyclerView.ViewHolder {

    public ImageView imageView;
    public TextView textView;

    public ViewHolder(View itemView) {
        super(itemView);
        imageView = (ImageView) itemView.findViewById(R.id.item_image_view);
        textView = (TextView) itemView.findViewById(R.id.item_name_text_view);

    }
}

MainActivity.class:

 public class MainActivity extends AppCompatActivity {

RelativeLayout relativeLayoutMiddle;

private RecyclerView recyclerView;
private RecyclerView.LayoutManager layoutManager;
private RecyclerView.Adapter adapter;
private List<ListItems> listItems;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    listItems = new ArrayList<>();

    for (int i = 0; i < 4; i++) {
        if(i==0)
        {
            ListItems listItems = new ListItems("Square", R.drawable.square);
            listItems.add(listItems);
        }
        else if(i==1)
        {
            ListItems listItems = new ListItems("Circle", R.drawable.circle);
            listItems.add(listItems);
        }
        else if(i==2)
        {
            ListItems listItems = new ListItems("Rectangle", R.drawable.rectangle);
            listItems.add(listItems);
        }
        else if(i==3)
        {
            ListItems listItems = new ListItems("Triangle", R.drawable.triangle);
            listItems.add(listItems);
        }
    }

    recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
    recyclerView.setHasFixedSize(true);
    layoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
    recyclerView.setLayoutManager(layoutManager);
    adapter = new RecyclerAdapter(listItems, this);
    recyclerView.setAdapter(adapter);

    relativeLayoutMiddle = (RelativeLayout) findViewById(R.id.relativeLayoutMiddle);

回答1:


This can basically be accomplished in just a few lines of code using the Android drag and drop api.

  1. Call View.startDragAndDrop
  2. Attach a View.OnDragListener to your drop container
  3. Wait for DragEvent.ACTION_DROP and then inflate and position your shape

In your RecyclerView.Adapter, attach a View.OnLongClickListener and then call View.startDragAndDrop. Something like:

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    final View v = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.layout_recycler_view_row_one, parent, false);
    final ViewHolder holder = new ViewHolder(v);
    final View shape = holder.imageView;
    holder.itemView.setOnLongClickListener(v -> {
        final ListItems item = listItems.get(holder.getAdapterPosition());
        final DragData state = new DragData(item, shape.getWidth(), shape.getHeight());
        final DragShadowBuilder shadow = new DragShadowBuilder(shape);
        ViewCompat.startDragAndDrop(shape, null, shadow, state, 0);
        return true;
    });
    return holder;
}

public class DragData {

    public final ListItems item;
    public final int width;
    public final int height;

    public DragData(ListItems item, int width, int height) {
        this.item= item;
        this.width = width;
        this.height = height;
    }

}

In your Activity or wherever you inflate your bottom container layout, call View.setOnDragListener and when DragEvent.ACTION_DROP is called we can inflate a copy of the View you called startDragAndDrop on. Something like:

@Override
public boolean onDrag(View v, DragEvent event) {
    switch (event.getAction()) {
        case DragEvent.ACTION_DRAG_ENTERED:
            dropContainer.setBackgroundColor(GREEN);
            break;
        case DragEvent.ACTION_DRAG_EXITED:
            dropContainer.setBackgroundColor(RED);
            break;
        case DragEvent.ACTION_DRAG_ENDED:
            dropContainer.setBackgroundColor(WHITE);
            break;
        case DragEvent.ACTION_DROP:
            final float dropX = event.getX();
            final float dropY = event.getY();
            final DragData state = (DragData) event.getLocalState();

            final ImageView shape = (ImageView) LayoutInflater.from(this).inflate(
                    R.layout.view_shape, dropContainer, false);
            shape.setImageResource(state.item.getImageDrawable());
            shape.setX(dropX - (float) state.width / 2);
            shape.setY(dropY - (float) state.height / 2);
            shape.getLayoutParams().width = state.width;
            shape.getLayoutParams().height = state.height;
            dropContainer.addView(shape);
            break;
        default:
            break;
    }
    return true;
}

Results



来源:https://stackoverflow.com/questions/45802611/how-to-drag-and-drop-an-image-from-a-recycler-view-and-place-it-outside-of-it-in

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!