RecyclerView

RecyclerView

  • RecyclerView 是google在android 5.0新推出的一个控件, RecyclerView可以完全替代掉ListView,GridView,它的灵活性与可替代性比Listview更好,但是RecyclerView使用起来也是相对于比较麻烦的,很多东西都是需要我们自定义的,比如Item的点击事件也是要自定义

  • 添加RecyclerView的依赖


compile 'com.android.support:recyclerview-v7:25.3.1'

RecyclerView简单使用

enter description here

  • 布局代码

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:title="RecyclerViewDemo"
        android:background="@color/colorPrimary"/>


    <android.support.v7.widget.RecyclerView
        android:id="@+id/rv"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</LinearLayout>
  • RecyclerView的Adapter类,需要继承RecyclerView.Adapter,并实现他的三个方法
    • getItemCount : 可以看做是ListView的getCount方法,用来确定我要显示多少个item
    • onCreateViewHolder : 其实就是ListView的getView中的两段逻辑
    • 1 创建view对象(将xml转为view)
    • 2 找到view对象里面的一些控件,对其进行一些展示的设置
    • onBindViewHolder : 对ViewHolder里面的控件设置数据

public class MyRecyclerViewAdapter extends RecyclerView.Adapter {
    private List<String> mDatas;

    //接收要显示的数据
    public void setDatas(List<String> datas) {
        mDatas = datas;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_layout, parent, false);
        MyRecyclerViewHolder myViewHolder = new MyRecyclerViewHolder(view);
        return myViewHolder;
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
        ((MyRecyclerViewHolder) holder).setTextView(mDatas.get(position));
    }

    @Override
    public int getItemCount() {
        return mDatas != null ? mDatas.size() : 0;
    }
}
  • ViewHolder类的代码

public class MyRecyclerViewHolder extends RecyclerView.ViewHolder{

    private CardView mCardview;
    private TextView mTextView;

    public MyRecyclerViewHolder(View itemView) {
        super(itemView);
        mTextView = (TextView) itemView.findViewById(R.id.tv);
        mCardview = (CardView) itemView.findViewById(card_view);
    }

    public void setTextView(String text){
        if (mTextView != null){
            mTextView.setText(text);
        }
    }
}
  • 在Activity中获取到RecyclerView,并设置Adapter,把要显示的数据传递给Adapter
  • 以下代码都是跟ListView一样的逻辑,唯一不一样的是我们必须给RecyclerView设置layoutManage,不然的话是显示不出数据的,有以下三种layoutManager
    • GridLayoutManager(Context context, int spanCount, int orientation,boolean reverseLayout) :
    • 显示出来的效果跟网格布局是一样的
    • context : 上下文对象
    • spanCount : 如果排列方向是水平方向,就表示行数,否则就是列数
    • reverseLayout : 为true就是把数据反向显示
    • StaggeredGridLayoutManager : 瀑布流
    • LinearLayoutManager : 效果跟ListView是一样的
mRv = (RecyclerView) findViewById(R.id.rv);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(MainActivity.this);
mRv.setLayoutManager(manager);  
mAdapter = new MyRecyclerViewAdapter(); //创建RecyclerView的Adapter
mAdapter.setDatas(mDatas);              //给Adapter设置数据
mRv.setAdapter(mAdapter);

自定义Item点击事件

enter description here
* 自定义Item点击事件需要用到接口回调的方式

  • 在Adapter类中的onBindViewHolder方法里添加以下代码
  • 添加一个方法用来接收接口的示例

    private OnRecyclerViewItemOnClickListener mListener;

    public void setListener(OnRecyclerViewItemOnClickListener listener) {
        mListener = listener;
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
        ((MyRecyclerViewHolder) holder).setTextView(mDatas.get(position));

        //设置点击事件
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mListener != null) {
                    mListener.onItemClick(position);
                }
            }
        });
    }
  • 接口回调的代码

public interface OnRecyclerViewItemOnClickListener {
    //  position是Item的位置
    void onItemClick(int position);
}
  • 最后需要在使用Item点击事件的类中实现OnRecyclerViewItemOnClickListener接口,然后调用Adapter中的setListener方法

设置添加/删除数据的动画效果

enter description here
* 这个是RecyclerView自带的添加/删除的动画效果,只需要在添加数据后加上以下代码就可以了


//添加动画, position是添加数据的位置
mAdapter.notifyItemInserted(int position);
//删除动画, position是删除数据的位置
mAdapter.notifyItemRemoved(int position);
  • 如果是要自定义动画效果需要给RecyclerView调用setItemAnimator方法,并实现SimpleItemAnimator的方法,具体的动画这里就不演示了

        mRv.setItemAnimator(new SimpleItemAnimator() {
            @Override
            public boolean animateRemove(RecyclerView.ViewHolder holder) {
                return false;
            }

            @Override
            public boolean animateAdd(RecyclerView.ViewHolder holder) {
                return false;
            }

            @Override
            public boolean animateMove(RecyclerView.ViewHolder holder, 
                                       int fromX, int fromY, int toX, int toY) {
                return false;
            }

            @Override
            public boolean animateChange(RecyclerView.ViewHolder oldHolder, 
                                         RecyclerView.ViewHolder newHolder, 
                                         int fromLeft, int fromTop, int toLeft, int toTop) {
                return false;
            }

            @Override
            public void runPendingAnimations() {

            }

            @Override
            public void endAnimation(RecyclerView.ViewHolder item) {

            }

            @Override
            public void endAnimations() {

            }

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

RecyclerView拖拽/滑动删除效果

enter description here
* 需要实现拖拽和滑动的效果要用到ItemTouchHelper类,ItemTouchHelper是一个处理RecyclerView的滑动删除和拖拽的辅助类
* 下面就直接附上代码了


    mItemTouchHelper = new ItemTouchHelper(new ItemTouchHelper.Callback() {
            @Override
            public int getMovementFlags(RecyclerView recyclerView, 
                                        RecyclerView.ViewHolder viewHolder) {
                //拖拽和滑动的标志
                int dragFlags = 0
                int swipeFlags = 0;
                //判断是否是网格布局还是瀑布流
                if (recyclerView.getLayoutManager() instanceof StaggeredGridLayoutManager ||                            recyclerView.getLayoutManager() instanceof GridLayoutManager) {
                    //网格布局有四个方向
                    dragFlags = ItemTouchHelper.UP |
                            ItemTouchHelper.DOWN |
                            ItemTouchHelper.LEFT |
                            ItemTouchHelper.RIGHT;
                } else if (recyclerView.getLayoutManager() instanceof LinearLayoutManager) {
                    //线性布局有两个方向
                    dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
                    swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END;
                }
                return makeMovementFlags(dragFlags, swipeFlags);
            }

            @Override
            public boolean onMove(RecyclerView recyclerView, 
                                 RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
                //长按会回调这个方法
                int from=viewHolder.getAdapterPosition();
                int to=target.getAdapterPosition();

                String moveItem = mDatas.get(from);
                mDatas.remove(from);
                mDatas.add(to,moveItem);//交换数据链表中数据的位置

                mAdapter.notifyItemMoved(from,to);//更新适配器中item的位置
                return true;
            }

            @Override
            public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
                TextView tv = (TextView) viewHolder.itemView.findViewById(R.id.tv);
                String data = tv.getText().toString();
                mDatas.remove(data);
                //这里处理滑动删除
                mAdapter.notifyDataSetChanged();
            }

            @Override
            public boolean isLongPressDragEnabled() {
                //返回true则为所有item都设置可以拖拽
                return true;
            }

            //当item拖拽开始时调用
            @Override
            public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
                super.onSelectedChanged(viewHolder, actionState);
                if(actionState==ItemTouchHelper.ACTION_STATE_DRAG){
                    viewHolder.itemView.setBackgroundColor(Color.TRANSPARENT);//拖拽时设置背景色为透明
                }
            }

            //当item拖拽完成时调用
            @Override
            public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
                super.clearView(recyclerView, viewHolder);
                viewHolder.itemView.setBackgroundColor(Color.WHITE);//拖拽停止时设置背景色为白色
            }

            //当item视图变化时调用
            @Override
            public void onChildDraw(Canvas c, RecyclerView recyclerView, 
                                    RecyclerView.ViewHolder viewHolder, float dX, 
                                    float dY, int actionState, boolean isCurrentlyActive) {
                super.onChildDraw(c, recyclerView, viewHolder, dX, dY, 
                                  actionState, isCurrentlyActive);
                //根据item滑动偏移的值修改item透明度。screenwidth是我提前获得的屏幕宽度
                viewHolder.itemView.setAlpha(1-Math.abs(dX)/width);
            }
        });
  • 添加完以上代码后,我们还需要然ItemTouchHelper跟RecyclerView绑定在一起

mItemTouchHelper.attachToRecyclerView(mRv);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值