美文网首页
RecyclerView的使用(Android开发必备,替换掉L

RecyclerView的使用(Android开发必备,替换掉L

作者: Android高级工程师 | 来源:发表于2019-05-06 17:20 被阅读0次

    RecyclerView简介:

    RecyclerView是support-v7包中的新控件,是ListView的升级版,使用方法和基本原理和ListView类似,区别是,RecycleView强行把ListView中的 getView ()方法拆分,把其中的ViewHolder单独封装起来,只需要实现自定定义的ViewHolder就行了,改组件会帮我们自动回收复用每一个item。

    RecyclerView相对于ListView的优点:

    1. 可以使用布局管理器LayoutManager来管理RecyclerView的显示方式:水平、垂直、网络、网格交错布局;
    2. 自定义item的分割条,实现自定义(不知道是优点还是缺点,见仁见智吧 ( ̄▽ ̄)");
    3. 可以控制item的添加和删除的动画,非常自由,可以自定义动画,配合具体场景,效果非常棒;
    4. 动态的在指定位置添加和删除某一项,而列表不会回到顶部,动态的update列表数据(非常需要);
    5. 缺点:就是没有OnItemClickListenter(),需要自己在RecycleView内部自定义列表项的点击事件或则长按事件(按需求自己添加);
    6. 在Material Design中和CardView(和RecycleView同时出现的新控件)配合使用,显示效果非常突出(现在很多新的主流App都使用了这种结构,后面会有demo展示)。

    RecycleView的基本使用步骤:

    ** 1、模拟对象和获取对象集合数据(这里只是模拟数据)**

    package com.world.hello.recycleview;
     
    /**
     * 模拟对象数据
     * Created by chengguo on 2016/5/30.
     */
    public class SampleModel {
        private String message;
     
        public SampleModel(String message) {
            this.message = message;
        }
     
        public void setMessage(String s) {
            message = s;
        }
     
        public String getMessage() {
            return message;
        }
    }
    
    
    package com.world.hello.recycleview;
     
    import java.util.ArrayList;
     
    /**
     * 模拟数据集合
     * Created by chengguo on 2016/5/30.
     */
    public class DemoApp {
        //获取要显示的数据(初始化数据)
        public static ArrayList<SampleModel> getSampleData(int size) {
            ArrayList<SampleModel> sampleData = new ArrayList<SampleModel>(size);
            for (int i = 0; i < size; i++) {
                sampleData.add(new SampleModel("新的列表项 " + i));
            }
            
            return sampleData;
        }
    }
    
    

    2、绘制列表项之间的分割条
    使用RecyclerView控件通常需要指定列表项的分割条。定制分割条的原理是编写一个RecyclerView.ItemDecoration的子类,并实现onDrawOver方法,在该方法中需要绘制所有列表项之间的分割条。如下所示:

    package com.world.hello.recycleview;
     
    import android.content.Context;
    import android.content.res.TypedArray;
    import android.graphics.Canvas;
    import android.graphics.drawable.Drawable;
    import android.support.v7.widget.RecyclerView;
    import android.view.View;
     
    /**
     * 定制分割线
     * Created by chengguo on 2016/5/30.
     */
    public class SampleDivider extends RecyclerView.ItemDecoration {
        //默认分割条Drawable资源的Id
        private static final int[] ATTRS = {android.R.attr.listDivider};
        //分割条的Drawable对象
        private Drawable mDicider;
     
        public SampleDivider(Context context) {
            TypedArray ta = context.obtainStyledAttributes(ATTRS);
            //获取分割条的drawable对象
            mDicider = ta.getDrawable(0);
            //回收ta所占用的空间
            ta.recycle();
     
        }
     
        /**
         * 在改方法中绘制了所有列表项之间的分割条
         *
         * @param c
         * @param parent
         */
        @Override
        public void onDrawOver(Canvas c, RecyclerView parent) {
     
            //获取列表项距离左边源的距离
            int left = parent.getPaddingLeft();
            //获取列表项距离右边源的距离
            int right = parent.getWidth() - parent.getPaddingRight();
            //获取列表的总数
            int childCount = parent.getChildCount();
            //开始绘制这些列表项之间的分割线
            for (int i = 0; i < childCount; i++) {
                //获取当前的列表
                View child = parent.getChildAt(i);
                //获取当前列表项的布局参数信息
                RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
                //计算分割条左上角的的纵坐标
                int top = child.getBottom() + params.bottomMargin;
                //计算分割条右下角的纵坐标
                int bottom = top + mDicider.getIntrinsicHeight();
                //设置分割条绘制的位置
                mDicider.setBounds(left,top,right,bottom);
                //开始绘制当前列表项下方的分割条
                mDicider.draw(c);
            }
        }
    }
    
    

    **
    3、实现Adapter类**
    就像ListView的adapter一般会继承BaseAdapter一样,RecyclerView也提供了这样的一个基类RecyclerView.Adapter,改基类支持泛型,泛型用于指定列表项中控件。如下:

    package com.world.hello.recycleview;
     
    import android.support.v7.widget.RecyclerView;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.TextView;
     
    import java.util.ArrayList;
    import java.util.Random;
     
    /**
     * recycleView的adapter
     * Created by chengguo on 2016/5/30.
     */
    public class SampleRecycleAdapter extends RecyclerView.Adapter<SampleRecycleAdapter.ViewHolder>{
     
        //保存列表项数据
        private final ArrayList<SampleModel> sampleData = DemoApp.getSampleData(30);
     
        //创建列表项中显示的控件对象(需要使用Adapter指定泛型)
        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            //获取列表项控件LinearLayer对象
            View rowView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item,parent,false);
            return new ViewHolder(rowView);
        }
     
        //在该方法中设置列表项中显示的值
        @Override
        public void onBindViewHolder(ViewHolder holder, int position) {
     
            SampleModel rowData = sampleData.get(position);
            holder.textViewSample.setText(rowData.getMessage());
            holder.itemView.setTag(rowData);
        }
     
        //设置列表项总和
        @Override
        public int getItemCount() {
            return sampleData.size();
        }
     
        //删除指定列表项的数据
        public void removeData(int position){
            sampleData.remove(position);
            //通知recycleView某个列表项被删除了
            notifyItemRemoved(position);
        }
     
        //在指定的位置添加一个新的列表项
        public void addItem(int position){
            //使用随机数字
            sampleData.add(position,new SampleModel("新增列表项"+ new Random().nextInt(100)));
            notifyItemInserted(position);
        }
     
        /**
         * ViewHolder用于存储列表项中显示的控件,(这里只有一个TextView做示例)
         */
        public static class ViewHolder extends RecyclerView.ViewHolder{
     
            private TextView textViewSample;
     
            public ViewHolder(View itemView) {
                super(itemView);
                textViewSample = (TextView) itemView.findViewById(R.id.text_view);
            }
        }
    
    

    ** 注意:SampleRecyclerAdapter类中所有使用@Override的方法都是覆盖的父类的同名方法。这些方法中和ListView对应的Adapter中的方法有些不同,在新Adapter中没有了getView()方法,而是使用onCreateViewHolder和OnBindViewHolder方法。前者用于获取列表项控件,后者用于指定在控件中显示的数据。 还有就是以前数据发生变化时,只能调用notifyDataSetChanged()方法通知数据是否发生变化,现在可以使用notifyItemRemoved()方法告诉具体哪个位置的数据被移除,使用notifyItemInserted()方法通知某一个新的列表项背添加。还有很多新的Api非常实用,如下面图片,就不一一介绍了;**

    在这里插入图片描述
    4、在Activity中使用RecyclerView
    recycleView是Android Support library中的控件,所以需要在Android studio中的app的gradle中添加下面的依赖

    compile 'com.android.support:design:23.4.0'

    然后就可以使用RecycleView这个控件了,这里实现了RecycleView的动态添加和删除操作。稍微要比listview复杂点,要设置RecycleView的排列方式 、item间的分割线、item增加和删除的动画;具体使用代码如下:

    package com.world.hello.recycleview;
     
    import android.app.Activity;
    import android.os.Bundle;
    import android.support.design.widget.FloatingActionButton;
    import android.support.v7.widget.DefaultItemAnimator;
    import android.support.v7.widget.LinearLayoutManager;
    import android.support.v7.widget.RecyclerView;
    import android.view.View;
    import android.view.animation.AnimationUtils;
    import android.widget.Button;
     
    public class MainActivity extends Activity {
     
        //顶部删除按钮
        private Button mDeleteBar;
        //recyclerView
        private RecyclerView mRecyclerView;
        //添加item按钮,这里也是使用Design库里面的一个新控件,就当做一个按钮使用。只是样式很好看
        private FloatingActionButton mAddBtn;
     
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            mDeleteBar = (Button) findViewById(R.id.delete_btn);
            mAddBtn = (FloatingActionButton) findViewById(R.id.add_item);
     
            //获取到recyclerView
            mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
            //创建LinearLayoutManager
            final LinearLayoutManager layoutManager = new LinearLayoutManager(this);
            //为RecyclerView指定布局管理器对象
            mRecyclerView.setLayoutManager(layoutManager);
            //创建列表项分割线对象
            final RecyclerView.ItemDecoration itemDecoration = new SampleDivider(this);
            //RecyclerView控件指定分割线对象
            mRecyclerView.addItemDecoration(itemDecoration);
            //创建SampleRecyclerAdapter
            final SampleRecycleAdapter sampleRecycleAdapter = new SampleRecycleAdapter();
            //为RecyclerView控件指定Adapter
            mRecyclerView.setAdapter(sampleRecycleAdapter);
            //设置Item增加、移除动画
            mRecyclerView.setItemAnimator(new DefaultItemAnimator());
     
     
            //为右下角按钮添加点击事件
            mAddBtn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //获取第一个可视的列表项的位置,再加上2个位置,为了演示方便
                    int positionToAdd = layoutManager.findFirstCompletelyVisibleItemPosition() + 2;
                    //在该位置的后面插入新的列表项
                    sampleRecycleAdapter.addItem(positionToAdd);
                }
            });
     
            //为顶部的删除面板添加点击事件
            mDeleteBar.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //获取第一个可视的列表项的位置,再加上2个位置,为了演示方便
                    int positionToRemove = layoutManager.findFirstCompletelyVisibleItemPosition() + 2;
                    //删除第一个可视的列表项
                    sampleRecycleAdapter.removeData(positionToRemove);
                    //删除完成后隐藏删除面板
                    hideDeleteBar();
                }
            });
     
            //为RecyclerView控件设置滚动事件
            mRecyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {
                //滚动状态变化事件的方法
                @Override
                public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                    super.onScrollStateChanged(recyclerView, newState);
                }
     
                //滚动事件方法(判断上下或者左右滚动)
                @Override
                public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                    //如果是垂直显示的列表, dy>0 表示向上滚动,否则表示向下滚动
                    //如果是水平显示的列表,dx > 0 表示向右滚动,否则表示向左滚动
                    if (dy > 0) {
                        //向上滚动时,隐藏删除面板,
                        if (mDeleteBar.getVisibility() == View.VISIBLE) {
                            hideDeleteBar();
                        }
                    } else {
                        //向下滚动时,显示显示面板
                        if (mDeleteBar.getVisibility() == View.GONE) {
                            showDeleteBar();
                        }
                    }
                }
            });
        }
     
        /**
         * 显示删除栏,使用动画效果
         */
        private void showDeleteBar() {
            mDeleteBar.startAnimation(AnimationUtils.loadAnimation(this, R.anim.translate_show));
            mDeleteBar.setVisibility(View.VISIBLE);
        }
     
        /**
         * 隐藏删除栏,使用动画效果
         */
        private void hideDeleteBar() {
            mDeleteBar.startAnimation(AnimationUtils.loadAnimation(this, R.anim.translate_hide));
            mDeleteBar.setVisibility(View.GONE);
        }
    }
    
    

    main_activity.xml文件如下:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app ="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="com.world.hello.recycleview.MainActivity">
     
        <Button
            android:id="@+id/delete_btn"
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:text="删除一项"
            android:background="#4400ffee"
            android:textSize="14dp"/>
     
        <android.support.v7.widget.RecyclerView
            android:id="@+id/recycler_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
     
        <android.support.design.widget.FloatingActionButton
            android:id="@+id/add_item"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:borderWidth="0dp"
            app:rippleColor="#eeff0000"
            android:src="@android:drawable/ic_input_add"
            android:layout_alignParentBottom="true"
            android:layout_alignParentRight="true"
            android:layout_alignParentEnd="true"
            android:layout_marginRight="33dp"
            android:layout_marginEnd="33dp"
            android:layout_marginBottom="38dp" />
     
    </RelativeLayout>
    
    

    list_item.xml文件如下:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:gravity="center_vertical"
        android:orientation="vertical">
     
        <TextView
            android:id="@+id/text_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center_vertical"
            android:textColor="@android:color/black"
            android:textSize="16sp" />
    </LinearLayout>
    
    

    效果图如下:

    image.png

    喜欢请点击+关注哦

    相关文章

      网友评论

          本文标题:RecyclerView的使用(Android开发必备,替换掉L

          本文链接:https://www.haomeiwen.com/subject/izydoqtx.html