Как создать полупрозрачное окно рециркулятора на Android? - PullRequest
0 голосов
/ 08 января 2019

Мой вопрос прост, но реализация на Android очень сложная. Мне интересно, как я могу перетащить только «перетаскиваемую часть», то есть элементы под заголовками.

recyclerview table with categories

Я следовал этому руководству , чтобы реализовать функцию перетаскивания. Но как я могу различить Header ViewHolder и Item ViewHolder при перетаскивании?

Класс адаптера указан ниже

public class ColorRecyclerViewAdapter extends
        RecyclerView.Adapter<ColorRecyclerViewAdapter.ItemViewHolderSelector> implements TouchCallbackHelperAdapter {

    private Context context;
    private ArrayList<String> mItems;
    private final HelperOnStartDragListener mDragStartListener;
    private ItemViewHolderSelector oldHolder;

    public ColorRecyclerViewAdapter(Context context, ArrayList<String> data, HelperOnStartDragListener dragStartListener) {
        this.context = context;
        this.mItems = data;
        this.mDragStartListener = dragStartListener;
    }

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

    @Override
    public boolean onItemMove(final int fromPosition, final int toPosition) {
        if (fromPosition < toPosition) {
            for (int i = fromPosition; i < toPosition; i++) {
                Collections.swap(mItems, i, i + 1);
            }
        } else {
            for (int i = fromPosition; i > toPosition; i--) {
                Collections.swap(mItems, i, i - 1);
            }
        }
        mDragStartListener.onFinishDrag(null);
        notifyItemMoved(fromPosition, toPosition);
        return true;
    }

    public ArrayList<String> getData() {
        return mItems;
    }

    public void addItem(String item) {
        mItems.add(item);
        notifyItemInserted(mItems.size() - 1);
    }

    @Override
    public ItemViewHolderSelector onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view;
        view = LayoutInflater.from(context).inflate(R.layout.color_recycler_view_item_drag_mode, parent, false);
        return new ItemViewHolderSelector(view);
    }

    @Override
    public void onBindViewHolder(@NonNull final ItemViewHolderSelector holder, final int position) {
        final String item = mItems.get(position);
        holder.name.setText(item);
        holder.drag.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        mDragStartListener.onStartDrag(holder);
                        break;
                }
                return true;
            }
        });
    }

    @Override
    public int getItemCount() {
        return mItems != null ? mItems.size() : 0;
    }

    class ItemViewHolderSelector extends RecyclerView.ViewHolder implements HelperViewHolderSelector {

        private TextView name;
        private ImageView drag;
        private View itemView;

        ItemViewHolderSelector(View itemView) {
            super(itemView);
            this.itemView = itemView;
            drag = itemView.findViewById(R.id.color_recycler_view_drag);
            name = itemView.findViewById(R.id.color_recycler_view_name);
        }

        @Override
        public void onItemSelected() {
            itemView.setBackgroundColor(Color.LTGRAY);
        }

        @Override
        public void onItemClear() {
            itemView.setBackgroundColor(0);
        }
    }
}

Edit:

На основании ответа @fernandospr я создал хранилище с окончательным кодом. Вы можете получить доступ к нему здесь .

1 Ответ

0 голосов
/ 08 января 2019

RecyclerView просто показывает виды, которые вы создаете на onCreateViewHolder.

В зависимости от вашей позиции вам нужно будет создавать разные виды. Это означает, что вы создадите HeaderViewHolder, когда позиция соответствует заголовку, и ItemViewHolder, когда позиция соответствует элементу.

Так что вам придется рефакторинг вашего ColorRecyclerViewAdapter до:

private static final int HEADER_VIEW = 0;
private static final int ITEM_VIEW = 1;

@Override
public RecyclerView.ViewHolderSelector onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    if (viewType == ITEM_VIEW) {
       ...
       return new ItemViewHolderSelector(view);
    } else {
       ...
       return new HeaderViewHolderSelector(view);
    }
}

@Override
public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, final int position) {
   if (ITEM_VIEW == holder.getItemViewType()) {
      ...
   } else {
      ...
   }
}

@Override
public int getItemCount() {
   return itemsCount + headersCount;
}

Внутри onBindViewHolder вы должны разрешить перетаскивание элемента, только установив TouchListener.

Кроме того, внутри методов onMove и и onSwiped вы должны использовать позицию, чтобы узнать, является ли это заголовок или элемент и разрешить или нет выполнение:

@Override
public void onItemDismiss(int position) {
   if (isItemPosition(position)) { 
      ...
   }
}

@Override
public boolean onItemMove(final int fromPosition, final int toPosition) {
   if (isItemPosition(position)) { 
      ...
   }
}

isItemPosition() - это метод, который вам нужно написать, который зависит от того, как адаптер хранит данные элементов и заголовков.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...