如何从Recycler视图拖放图像并将其放在另一个布局中 [英] How to drag and drop an image from a Recycler view and place it outside of it into another layout

查看:219
本文介绍了如何从Recycler视图拖放图像并将其放在另一个布局中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个水平的Recylcer视图,其中包含一个项目列表。每个项目具有文本视图和图像视图以表示项目(例如,正方形的图像和图像上方的文本正方形)。 recylcer视图位于屏幕顶部的
相对布局中。我需要做的是从回收器视图中拖动一个图像并将其放在它之外的另一个布局中。但是,不得删除从回收器视图拖动的图像,而应将图像的副本放入外部布局中。还必须将图像放在用户松开手指的布局中的确切位置。有没有办法实现这个目标?

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:

Recycler View的适配器类:

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:

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);


推荐答案

这基本上可以在几行中完成代码使用 Android拖放API

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


  1. 致电 View.startDragAndDrop

  2. 附上 View.OnDragListener 到您的放置容器

  3. 等待 DragEvent.ACTION_DROP 然后给你的形状充气和定位

  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

RecyclerView.Adapter 中,附上一个视图。 OnLongClickListener 然后调用 View.startDragAndDrop 。类似于:

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;
    }

}

活动或者在您向底部容器布局膨胀的任何地方,调用 View.setOnDragListener 以及何时 DragEvent.ACTION_DROP 被调用我们可以通过你打电话给 startDragAndDrop View 的副本。类似于:

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;
}

结果

这篇关于如何从Recycler视图拖放图像并将其放在另一个布局中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆