【问题标题】:RecyclerView - Drag and Drop - move item over another item. (placeholder)RecyclerView - 拖放 - 将项目移到另一个项目上。 (占位符)
【发布时间】:2021-03-12 10:32:53
【问题描述】:

我有一个适配器、Recyclerview 和 ItemTouchHelper。 我想制作占位符,由于移动,可以在其上放置物品。 占位符现在被制作为空元素。但是不知道怎么才能把元素直接放在这个上面。

我的适配器:

public class DateTimeAdapter extends RecyclerView.Adapter<MainHolder> implements ItemTouchHelperAdapter {
    private List<MainItem> values;
    private RecyclerView.RecycledViewPool viewPool = new RecyclerView.RecycledViewPool();
    private Activity context;
    private final OnStartDragListener mDragStartListener;
    private boolean initEmpty = false;

    public DateTimeAdapter(Activity context, List<MainItem> values, OnStartDragListener dragListener) {
        this.values = values;
        this.context = context;
        mDragStartListener = dragListener;
    }


    @NonNull
    @Override
    public MainHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view;
        switch (viewType){
            case (Constants.ITEM_HEADER_TEXT_VIEWTYPE):
                view = LayoutInflater.from(context).inflate(R.layout.list_group_item, parent, false);
                return new HeaderHolder(view);
            case (Constants.ITEM_EVENT_TEXT_VIEWTYPE):
                view = LayoutInflater.from(context).inflate(R.layout.item_wo_items, parent, false);
                return new ItemHolder(view);
            case (Constants.ITEM_PLACEHOLDER_VIEWTYPE):
                view = LayoutInflater.from(context).inflate(R.layout.item_placeholder, parent, false);
                return new PlaceHolder(view);
            default: throw new IllegalArgumentException();
        }
    }

    @Override
    public void onBindViewHolder(@NonNull final MainHolder holder, int position) {
        holder.setData(values.get(position));

        if (holder.getItemViewType() == Constants.ITEM_PLACEHOLDER_VIEWTYPE){

        }
    }


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

    @Override
    public int getItemViewType(int position) {
        return values.get(position).getViewType();
    }

    protected LocalTime getStartTimebyHeader(int position){
        ListIterator<MainItem> listIterator = values.listIterator(position);
        while (listIterator.hasPrevious()){
            MainItem t = listIterator.previous();
            if (t.getHeaderItem() != null){
                DateTimeFormatter parse = new DateTimeFormatterBuilder().appendPattern("HH:mm").toFormatter();
                LocalTime localTime = LocalTime.parse(t.getHeaderItem().getHeaderText(), parse);
                return localTime;
            }
        }
        return null;
    }



    protected LocalTime getEndTimebyHeader(int position){
        ListIterator<MainItem> listIterator = values.listIterator(position);
        while (listIterator.hasNext()){
            MainItem t = listIterator.next();
            if (t.getHeaderItem() != null){
                DateTimeFormatter parse = new DateTimeFormatterBuilder().appendPattern("HH:mm").toFormatter();
                LocalTime localTime = LocalTime.parse(t.getHeaderItem().getHeaderText(), parse);
                return localTime;
            }
        }
        return null;
    }


    @Override
    public boolean onItemMove(int fromPosition, int toPosition) {
        if (fromPosition < toPosition) {
            for (int i = fromPosition; i < toPosition; i++) {
                Collections.swap(values, i, i + 1);
            }
        } else {
            for (int i = fromPosition; i > toPosition; i--) {
                Collections.swap(values, i, i - 1);
            }
        }
        notifyItemMoved(fromPosition, toPosition);

        return true;
    }

    @Override
    public void onItemDismiss(int position) {
        values.remove(position);
        notifyItemRemoved(position);
    }
}

我的 ItemTouchHelper

 ItemTouchHelper.SimpleCallback simpleCallback = new ItemTouchHelper.SimpleCallback(0, 0) {


            @Override
            public boolean canDropOver(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder current, @NonNull RecyclerView.ViewHolder target) {
                if (target.getAdapterPosition() != 0 && target.getAdapterPosition() != dta.getItemCount()-1)
                    return true;
                return false;
            }

            @Override
            public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
                Log.d("onMove", Integer.toString(viewHolder.getAdapterPosition()) + " - " + Integer.toString(target.getAdapterPosition()));
                dta.onItemMove(viewHolder.getAdapterPosition(), target.getAdapterPosition());
                return true;

            }

            @Override
            public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {

            }

            @Override
            public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
                int dragFlags =  viewHolder.getItemViewType() == Constants.ITEM_EVENT_TEXT_VIEWTYPE ? ItemTouchHelper.UP | ItemTouchHelper.DOWN : 0;
                int swipeFlags =  viewHolder.getItemViewType() == Constants.ITEM_EVENT_TEXT_VIEWTYPE ? ItemTouchHelper.START | ItemTouchHelper.END : 0;
                return makeMovementFlags(dragFlags, swipeFlags);
            }

            @Override
            public void clearView(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
                showingDatas.get(viewHolder.getAdapterPosition()).getEventItem().setTimeS(dta.getStartTimebyHeader(viewHolder.getAdapterPosition()));
                showingDatas.get(viewHolder.getAdapterPosition()).getEventItem().setTimeE(dta.getEndTimebyHeader(viewHolder.getAdapterPosition()));
                dta.notifyItemChanged(viewHolder.getAdapterPosition());
                super.clearView(recyclerView, viewHolder);
            }
        };

        ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleCallback);
        itemTouchHelper.attachToRecyclerView(rvPlan);

我该怎么做?

【问题讨论】:

    标签: java android android-recyclerview itemtouchhelper


    【解决方案1】:

    问题已解决:数据类用于区分普通视图和占位符视图。在适配器中使用以下列表:

    data class MyData(var type:Int, var name: String)
    val list = mutableListOf(MyData(0,"PlaceHolder"),MyData(1,"Normal"),MyData(1,"Noraml"),MyData(0,"Place Holder"),MyData(1,"Normal"),MyData(1,"Normal"))
    

    自定义项目触摸侦听器类:

        ItemTouchHelper(object : RecyclerViewDragDetector() {
            override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder): Boolean {
    
                if (adapter.getItemViewType(viewHolder.adapterPosition) == 1){
                    if (adapter.getItemViewType(target.adapterPosition)!= 1){
    
                        list[target.adapterPosition].type = 1
                        list[target.adapterPosition].name = "Normal"
                        adapter.notifyItemChanged(target.adapterPosition)
                        list.removeAt(viewHolder.adapterPosition)
                        adapter.notifyDataSetChanged()
                    }
                }
                return true
            }
            override fun isLongPressDragEnabled(): Boolean {
                return true
            }
        }).attachToRecyclerView(recyclerView)
    

    根据您的需要更改适配器。我的示例适配器如下所示:

        inner class MyAdapter: RecyclerView.Adapter<RecyclerView.ViewHolder>(){
        private val viewTypeHeader = 0
        private val viewTypeNormal = 1
        inner class MyHolder(view: View): RecyclerView.ViewHolder(view){
            val textView: TextView = view.findViewById(R.id.normal_tv)
            fun bind(myData: MyData){
                textView.text = myData.name
            }
        }
        inner class MyHeaderHolder(view:View): RecyclerView.ViewHolder(view){
            val textView: TextView = view.findViewById(R.id.header_tv)
            fun bind(myData: MyData){
                textView.text = myData.name
            }
        }
        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
            return if (viewType == viewTypeHeader){
                val view = LayoutInflater.from(parent.context).inflate(R.layout.header, parent, false)
                MyHeaderHolder(view)
            }else {
                val view = LayoutInflater.from(parent.context).inflate(R.layout.list_item, parent, false)
                MyHolder(view)
            }
        }
    
        override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
          if (getItemViewType(position) == viewTypeHeader){
                (holder as MyHeaderHolder).bind(list[position])
          }else{
              (holder as MyHolder).bind(list[position])
          }
        }
    
        override fun getItemViewType(position: Int): Int {
            return if (list[position].type == viewTypeHeader)
                return viewTypeHeader
            else
                viewTypeNormal
    
        }
        override fun getItemCount(): Int {
            return list.size
        }
    }
    

    【讨论】:

    • 此解决方案不起作用。我想将具有 EVENT ViewType 的项目放在具有 PLACEHOLDER ViewType 的项目上。我该怎么做?
    • 好的,让我检查并确认您。
    • 好的,我在等
    • 问题已解决。你可以查看我更新的答案。
    • 刚刚更新 if else 条件现在。您可以使用刚刚更新的代码进行检查。
    猜你喜欢
    • 1970-01-01
    • 2016-03-26
    • 2017-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-06
    • 1970-01-01
    • 2014-09-22
    相关资源
    最近更新 更多