Android RecyclerView的应用

一:RecyclerView是什么
从Android5.0开始,谷歌推出一个用于大量数据展现的新控件RecyclerView,能够代替传统的ListView,更加弱小和灵便。
在AndroidX我的项目中增加依赖:implementation 'androidx.recyclerview:recyclerview:1.1.0'
在非AndroidX我的项目中增加依赖:implementation 'com.android.support:recyclerview-v7:26.1.0'//对应的是compileSdkVersion的版本

//Android布局应用<android.support.v7.widget.RecyclerView    android:layout_width="match_parent"    android:layout_height="match_parent" />        //AndroidX布局应用    <androidx.recyclerview.widget.RecyclerView        android:layout_width="match_parent"        android:layout_height="match_parent"/>

RecyclerView的长处
1.反对部分刷新
2.能够自定义Item增删时的动画
3.可能实现Item拖拽和侧滑删除等性能
二:RecyclerView应用

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical">    <androidx.recyclerview.widget.RecyclerView        android:id="@+id/tv_recycler"        android:layout_width="match_parent"        android:layout_height="match_parent"/></LinearLayout>

1.创立布局管理器
LinearLayoutManager:线性布局,以垂直或程度滚动形式显示列表
GridLayoutManager:网格布局,在网格中显示我的项目
StaggeredGridLayoutManager:瀑布流布局,在扩散对齐网格中显示我的项目

LinearLayoutManager layoutManager=new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false);//线性布局管理器  GridLayoutManager gridLayoutManager=new GridLayoutManager(this,3);//网格布局管理器    StaggeredGridLayoutManager staggeredGridLayoutManager=new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL);//瀑布流布局  

2.适配器应用

public class MyRecycleViewAdapter extends RecyclerView.Adapter<MyRecycleViewAdapter.MyHolder> {    private List<String> mDatas;//数据源    private Context context;          private OnItemClickListener onItemClickListener;    /**向内部提供调用设置监听*/    public void setOnItemClickListener(OnItemClickListener onItemClickListener){        this.onItemClickListener=onItemClickListener;    }    public MyRecycleViewAdapter(Context context,List<String> mDatas) {        this.context=context;        this.mDatas = mDatas;    }    /**     * 创立ViewHolder并返回,后续item布局里控件都是从ViewHolder中取出     */    @NonNull    @Override    public MyHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {        //将咱们自定义的item布局转成View        View view = LayoutInflater.from(context).inflate(R.layout.item_one, parent, false);        //将View传递给咱们自定义ViewHolder        return new MyHolder(view);    }    /**通过办法提供的ViewHolder,将数据绑定到的ViewHolder中*/    @Override    public void onBindViewHolder(@NonNull MyHolder holder, int position) {        holder.tv_content.setText(mDatas.get(position));                 holder.tv_content.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                if (onItemClickListener!=null){                    onItemClickListener.onItemClick(v,holder.getAdapterPosition()+1);                }            }        });    }    /**     * 获取数据源总的条目     */    @Override    public int getItemCount() {        return mDatas.size();    }   static class MyHolder extends RecyclerView.ViewHolder {        TextView tv_content;        public MyHolder(@NonNull View itemView) {            super(itemView);            tv_content=itemView.findViewById(R.id.tv_content);        }    }         /**自定义的接口*/    public interface OnItemClickListener{        void onItemClick(View view,int position);    }}

RecyclerView 封装了viewholder的回收复用,标准化了ViewHolder,编写Adapter面向的是ViewHolder而不是View,复用的逻辑封装了
创立适配器步骤:
1.创立Adapter:创立一个继承RecyclerView.Adapter<VH>的Adapter类(VH是ViewHolder的类名)
2.创立ViewHolder:在Adapter中创立一个继承RecyclerView.ViewHolder的动态外部类,记为VH。ViewHolder的实现和ListView的ViewHolder实现简直一样。
三个办法:
onCreateViewHolder: 创立ViewHolder并返回,后续item布局里控件都是从ViewHolder中取出。
onBindViewHolder:通过办法提供的ViewHolder,将数据绑定到ViewHolder中。
getItemCount:获取数据源总的条数。
下面2个适配器和布局管理器是必须设置的

3.Item Decoration(可选)设置分割线

 //增加分割线        tv_recycler.addItemDecoration(new DividerItemDecoration(this,DividerItemDecoration.VERTICAL));//默认的分割线        

能够自定义距离款式须要继承RecyclerView.ItemDecoration类,该类是抽象类

public class MyItemDecoration extends RecyclerView.ItemDecoration {    private final Drawable mLine;    private final int orientation;    public MyItemDecoration(Context context, int orientation) {        this.orientation = orientation;        int[] attrs = new int[]{android.R.attr.listDivider};//零碎的分割线色彩        TypedArray a = context.obtainStyledAttributes(attrs);        mLine = a.getDrawable(0);        a.recycle();    }    /**在Item绘制之前被调用,用于绘制距离款式*/    @Override    public void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {        super.onDraw(c, parent, state);        if (orientation==RecyclerView.HORIZONTAL){            drawVertical(c, parent, state);        }else if (orientation==RecyclerView.VERTICAL){            drawHorizontal(c, parent, state);        }    }    /**onDraw和onDrawOver2个其中一个就行*/    @Override    public void onDrawOver(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {        super.onDrawOver(c, parent, state);    }    /**设置item的偏移量,偏移的局部用于填充距离款式,即设置分割线的宽、高;在RecyclerView的onMesure()中会调用该办法。*/    @Override    public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {        super.getItemOffsets(outRect, view, parent, state);        if (orientation == RecyclerView.HORIZONTAL) {            //画垂直线            outRect.set(0, 0, mLine.getIntrinsicWidth(), 0);        } else if (orientation == RecyclerView.VERTICAL) {            //画水平线            outRect.set(0, 0, 0, mLine.getIntrinsicHeight());        }    }    /**     * 画垂直分割线     */    private void drawVertical(Canvas c, RecyclerView parent, RecyclerView.State state) {        int childCount = parent.getChildCount();        for (int i = 0; i < childCount; i++) {            View child = parent.getChildAt(i);            int left = child.getRight();            int top = child.getTop();            int right = left + mLine.getIntrinsicWidth();            int bottom = child.getBottom();            mLine.setBounds(left, top, right, bottom);            mLine.draw(c);        }    }    /**     * 画程度分割线     */    private void drawHorizontal(Canvas c, RecyclerView parent, RecyclerView.State state) {        int childCount = parent.getChildCount();        for (int i = 0; i < childCount; i++) {            View child = parent.getChildAt(i);            int left = child.getLeft();            int top = child.getBottom();            int right = child.getRight();            int bottom = top + mLine.getIntrinsicHeight();            mLine.setBounds(left, top, right, bottom);            mLine.draw(c);        }    }}

咱们能够批改零碎自定义分割线色彩
在res下values下theme主题中
<!--自定义零碎分割线色彩-->
<item name="android:listDivider">@drawable/customizelistdivider </item>
在res/drawable中设置customizelistdivider

<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android">    <gradient        android:endColor="#ff0000ff"        android:startColor="#ffff0000"        android:type="linear" />    <size android:height="4dp"        android:width="4dp"/></shape>


应用设置自定义分割线
tv_recycler.addItemDecoration(new MyItemDecoration(this,RecyclerView.VERTICAL));

4.ItemAnimator动画(可选)
tv_recycler.setItemAnimator(new DefaultItemAnimator());//设置默认动画
默认动画继承DefaultItemAnimator来实现自定义动画

相干实现

public class SecondActivity extends AppCompatActivity {    private RecyclerView tv_recycler;    private MyRecycleViewAdapter myRecycleViewAdapter;    private List<String> mDatas=new ArrayList<>();    @Override    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_second);        initData();//初始化数据        tv_recycler=findViewById(R.id.tv_recycler);        //创立布局管理器        LinearLayoutManager layoutManager=new LinearLayoutManager(this);//默认垂直排列        //GridLayoutManager gridLayoutManager=new GridLayoutManager(this,3);        //StaggeredGridLayoutManager staggeredGridLayoutManager=new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL);        layoutManager.setOrientation(RecyclerView.HORIZONTAL);//设置程度排列        //LinearLayoutManager layoutManager1=new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false);        //设置布局管理器        tv_recycler.setLayoutManager(layoutManager);        //增加分割线        tv_recycler.addItemDecoration(new MyItemDecoration(this,RecyclerView.VERTICAL));//自定义分割线        tv_recycler.setItemAnimator(new DefaultItemAnimator());        //tv_recycler.addItemDecoration(new DividerItemDecoration(this,DividerItemDecoration.VERTICAL));//默认的分割线        //创立数据适配器        myRecycleViewAdapter=new MyRecycleViewAdapter(this,mDatas);        //设置数据适配器        tv_recycler.setAdapter(myRecycleViewAdapter);        //内部适配器数据监听条目点击        myRecycleViewAdapter.setOnItemClickListener(new MyRecycleViewAdapter.OnItemClickListener() {            @Override            public void onItemClick(View view, int position) {                Toast.makeText(SecondActivity.this, "第"+position+"条数据", Toast.LENGTH_SHORT).show();            }        });    }    private void initData() {        for (int i=0;i<40;i++){            mDatas.add("我是item"+i);        }    }}

5.Item条目监听,点击事件监听

  /**向内部提供调用设置监听*/    public void setOnItemClickListener(OnItemClickListener onItemClickListener){        this.onItemClickListener=onItemClickListener;    }    public MyRecycleViewAdapter(Context context,List<String> mDatas) {        this.context=context;        this.mDatas = mDatas;    }   /**自定义的接口*/    public interface OnItemClickListener{        void onItemClick(View view,int position);    }            @Override    public void onBindViewHolder(@NonNull MyHolder holder, int position) {        holder.tv_content.setText(mDatas.get(position));                 holder.tv_content.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                if (onItemClickListener!=null){                    onItemClickListener.onItemClick(v,holder.getAdapterPosition()+1);//在绑定数据的时候给内部传递得postion从1开始                }            }        });    }        //内部调用开始    myRecycleViewAdapter.setOnItemClickListener(new MyRecycleViewAdapter.OnItemClickListener() {            @Override            public void onItemClick(View view, int position) {                Toast.makeText(SecondActivity.this, "第"+position+"条数据", Toast.LENGTH_SHORT).show();            }        });

END:只愿年过半百,归来仍是少年