欢迎使用CSDN-markdown编辑器

前言

仿今日头条频道选择页

1、效果

这里写图片描述

2、工程文件目录
这里写图片描述

3、具体实现
ItemDragHelperCallback.java

package com.komling.itemtouchdemo;

import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.support.v7.widget.helper.ItemTouchHelper;

/**
 * Created by 梧桐树 on 2017/11/28.
 */

public class ItemDragHelperCallback extends ItemTouchHelper.Callback {

    /**
     * 指定可以支持的拖放和滑动的方向
     * 这里我们启用了上下左右两种方向。注:上下为拖动(drag),左右为滑动(swipe)
     *
     * @param recyclerView
     * @param viewHolder
     * @return
     */
    @Override
    public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
        int dragFlags;
        RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();
        if (manager instanceof GridLayoutManager || manager instanceof StaggeredGridLayoutManager) {
            dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
        } else {
            dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
        }

        //如果想支持滑动(删除)操作,swipeFlags = ItemTouchHelper.START|ItemTouchHelper.END
        int swipeFlags = 0;
        //使用helperItemTouchHelper.makeMovementFlags(int, int)来构造返回的flag
        return makeMovementFlags(dragFlags, swipeFlags);
    }

    @Override
    public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
        if (viewHolder.getItemViewType() != target.getItemViewType()) {
            return false;
        }

        if (recyclerView.getAdapter() instanceof IOnItemMoveListener) {
            IOnItemMoveListener listener = (IOnItemMoveListener) recyclerView.getAdapter();
            listener.onItemMove(viewHolder.getAdapterPosition(), target.getAdapterPosition());
        }
        return true;
    }

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

    @Override
    public boolean isLongPressDragEnabled() {
        return false;
    }

    @Override
    public boolean isItemViewSwipeEnabled() {
        return false;
    }
}

RecyclerListAdapter.xml

package com.komling.itemtouchdemo;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import java.util.Collections;
import java.util.List;

/**
 * Created by 梧桐树 on 2017/11/28.
 */

public class RecyclerListAdapter extends RecyclerView.Adapter implements IOnItemMoveListener {

    //我的频道 标题部分
    public static final int TYPE_MY_CHANNEL_HEADER = 0;
    //我的频道
    public static final int TYPE_MY_CHANNEL = 1;
    //其他频道 标题部分
    public static final int TYPE_OTHER_CHANNEL_HEADER = 2;
    //其他频道
    public static final int TYPE_OTHER_CHANNEL = 3;

    //我的频道之前header的数量
    private static final int COUNT_PRE_MY_HEADER = 1;
    //其他频道之前的header的数量
    private static final int COUNT_PRE_OTHER_HEADER = COUNT_PRE_MY_HEADER + 1;

    private Context context;
    private ItemTouchHelper itemTouchHelper;
    private List<String> mMyChannel, mOtherChannel;

    private boolean isEditMode = false;


    public RecyclerListAdapter(Context context, ItemTouchHelper helper, List<String> mMyChannel, List<String> mOtherChannel) {
        this.context = context;
        this.itemTouchHelper = helper;
        this.mMyChannel = mMyChannel;
        this.mOtherChannel = mOtherChannel;
    }

    @Override
    public int getItemViewType(int position) {
        if (position == 0) {//我的频道标题部分
            return TYPE_MY_CHANNEL_HEADER;
        } else if (position > 0 && position < mMyChannel.size() + COUNT_PRE_MY_HEADER) {//我的频道
            return TYPE_MY_CHANNEL;
        } else if (position == mMyChannel.size() + COUNT_PRE_MY_HEADER) {//其他频道标题部分
            return TYPE_OTHER_CHANNEL_HEADER;
        } else {//其他频道
            return TYPE_OTHER_CHANNEL;
        }
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(final ViewGroup parent, int viewType) {
        final View view;
        switch (viewType) {
            case TYPE_MY_CHANNEL_HEADER:
                view = LayoutInflater.from(context).inflate(R.layout.item_channel_my_header, parent, false);
                final MyChannelHeaderViewHolder holder = new MyChannelHeaderViewHolder(view);
                holder.mTvBtnEdit.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        if (!isEditMode) {
                            startEditMode((RecyclerView) parent);
                            holder.mTvBtnEdit.setText("完成");
                        } else {
                            cancelEditMode((RecyclerView) parent);
                            holder.mTvBtnEdit.setText("编辑");
                        }
                    }
                });
                return holder;
            case TYPE_MY_CHANNEL:
                view = LayoutInflater.from(context).inflate(R.layout.item_channel_my, parent, false);
                final MyChannelViewHolder myHolder = new MyChannelViewHolder(view);
                myHolder.mTextView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        if (isEditMode) {
                            moveMyToOther(myHolder);
                        } else {
                            Toast.makeText(context, mMyChannel.get(myHolder.getAdapterPosition() - COUNT_PRE_MY_HEADER), Toast.LENGTH_LONG).show();
                        }
                    }
                });

                myHolder.mTextView.setOnLongClickListener(new View.OnLongClickListener() {
                    @Override
                    public boolean onLongClick(View v) {
                        if (!isEditMode) {
                            RecyclerView recyclerView = (RecyclerView) parent;
                            startEditMode(recyclerView);

                            View view = parent.getChildAt(0);
                            TextView mTvBtnEdit = view.findViewById(R.id.tv_btn_edit);
                            if (mTvBtnEdit != null) {
                                mTvBtnEdit.setText("完成");
                            }
                        }

                        itemTouchHelper.startDrag(myHolder);
                        return true;
                    }
                });
                return myHolder;
            case TYPE_OTHER_CHANNEL_HEADER:
                view = LayoutInflater.from(context).inflate(R.layout.item_channel_other_header, parent, false);
                return new RecyclerView.ViewHolder(view) {
                };
            case TYPE_OTHER_CHANNEL:
                view = LayoutInflater.from(context).inflate(R.layout.item_channel_other, parent, false);
                final OtherChannelViewHolder otherHolder = new OtherChannelViewHolder(view);
                otherHolder.mTextView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        moveOtehrToMy(otherHolder);
                    }
                });
                return otherHolder;
        }
        return null;
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        if (holder instanceof MyChannelViewHolder) {
            MyChannelViewHolder myHolder = (MyChannelViewHolder) holder;
            myHolder.mTextView.setText(mMyChannel.get(position - COUNT_PRE_MY_HEADER));
            if (isEditMode) {
                myHolder.mImgDel.setVisibility(View.VISIBLE);
            } else {
                myHolder.mImgDel.setVisibility(View.GONE);
            }
        } else if (holder instanceof OtherChannelViewHolder) {
            OtherChannelViewHolder otherHolder = (OtherChannelViewHolder) holder;
            otherHolder.mTextView.setText(mOtherChannel.get(position - mMyChannel.size() - COUNT_PRE_OTHER_HEADER));
        }
    }

    @Override
    public int getItemCount() {
        return mMyChannel.size() + mOtherChannel.size() + COUNT_PRE_OTHER_HEADER;
    }

    @Override
    public void onItemMove(int fromPosition, int toPosition) {
//        用于交换在指定列表中的指定位置的元素。
        Collections.swap(mMyChannel, fromPosition, toPosition);

        notifyItemMoved(fromPosition, toPosition);
    }

    /**
     * 开启编辑模式
     *
     * @param parent
     */
    public void startEditMode(RecyclerView parent) {
        isEditMode = true;

        int visibleChildCount = parent.getChildCount();
        if (mMyChannel.size() <= visibleChildCount - COUNT_PRE_OTHER_HEADER) {
            for (int i = 0; i < mMyChannel.size() + COUNT_PRE_MY_HEADER; i++) {
                View view = parent.getChildAt(i);
                ImageView imgEdit = view.findViewById(R.id.img_del);
                if (imgEdit != null) {
                    imgEdit.setVisibility(View.VISIBLE);
                }
            }
        }
    }

    /**
     * 取消编辑模式
     *
     * @param parent
     */
    public void cancelEditMode(RecyclerView parent) {
        isEditMode = false;

        int visibleChildCount = parent.getChildCount();
        if (mMyChannel.size() <= visibleChildCount - COUNT_PRE_OTHER_HEADER) {
            for (int i = 0; i < mMyChannel.size() + COUNT_PRE_MY_HEADER; i++) {
                View view = parent.getChildAt(i);
                ImageView imgEdit = view.findViewById(R.id.img_del);
                if (imgEdit != null) {
                    imgEdit.setVisibility(View.INVISIBLE);
                }
            }
        }
    }

    /**
     * 我的频道移动到 其他频道
     *
     * @param myHolder
     */
    private void moveMyToOther(MyChannelViewHolder myHolder) {
        int position = myHolder.getAdapterPosition();

        int startPosition = position - COUNT_PRE_MY_HEADER;
        if (startPosition > mMyChannel.size() - 1) {
            return;
        }
        String str = mMyChannel.get(startPosition);
        mMyChannel.remove(startPosition);
        mOtherChannel.add(0, str);

        notifyItemMoved(position, mMyChannel.size() + COUNT_PRE_OTHER_HEADER);
    }

    /**
     * 其他频道移动到 我的频道
     *
     * @param otherHolder
     */
    private void moveOtehrToMy(OtherChannelViewHolder otherHolder) {
        int position = processItemRemoveAdd(otherHolder);
        if (position == -1) {
            return;
        }
        notifyItemMoved(position, mMyChannel.size() - 1 + COUNT_PRE_MY_HEADER);
    }

    private int processItemRemoveAdd(OtherChannelViewHolder otherHolder) {
        int position = otherHolder.getAdapterPosition();

        int startPosition = position - mMyChannel.size() - COUNT_PRE_OTHER_HEADER;
        if (startPosition > mOtherChannel.size() - 1) {
            return -1;
        }
        String str = mOtherChannel.get(startPosition);
        mOtherChannel.remove(startPosition);
        mMyChannel.add(str);
        return position;
    }

    //我的频道标题
    static class MyChannelHeaderViewHolder extends RecyclerView.ViewHolder {
        TextView mTvBtnEdit;

        public MyChannelHeaderViewHolder(View itemView) {
            super(itemView);
            mTvBtnEdit = itemView.findViewById(R.id.tv_btn_edit);
        }
    }

    //我的频道
    static class MyChannelViewHolder extends RecyclerView.ViewHolder {
        TextView mTextView;
        ImageView mImgDel;

        public MyChannelViewHolder(View itemView) {
            super(itemView);
            mTextView = itemView.findViewById(R.id.textView);
            mImgDel = itemView.findViewById(R.id.img_del);
        }
    }

    //其他频道
    static class OtherChannelViewHolder extends RecyclerView.ViewHolder {
        TextView mTextView;
        ImageView mImgDel;

        public OtherChannelViewHolder(View itemView) {
            super(itemView);
            mTextView = itemView.findViewById(R.id.textView);
            mImgDel = itemView.findViewById(R.id.img_del);
        }
    }
}

项目下载地址:http://download.csdn.net/download/ghsfggdsfgdsf/10138808

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值