Android RecycleView 基础使用

 1.添加依赖:

  compile 'com.android.support:recyclerview-v7:26.0.0-alpha1'

2. MyAdapter继承RecyclerView.Adapter<MyAdapter.MyViewHolder>  
         回调方法:onCreateViewHolder  创建ViewHolder
         回调方法:onBindViewHolder    数据展示
 2.1.MyViewHolder 继承 RecyclerView.ViewHolder

MyAdapter  代码如下:

package org.xm.recyclerviewsimple;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.TextView;

import java.util.List;
import java.util.Random;

/**
 * Created by yxm2909 on 2016/7/13.
 */
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {

    private static final String TAG = "MyAdapter";
    private List<String> datas;
    private LayoutInflater inflater;
    private OnItemClickListener mOnItemClickListener;
    private OnItemLongClickListener mOnItemLongClickListener;

    public interface OnItemClickListener {
        public void onClick(View parent, int position);
    }

    public interface OnItemLongClickListener {
        public boolean onLongClick(View parent, int position);
    }

    public void setOnItemClickListener(OnItemClickListener l) {
        this.mOnItemClickListener = l;
    }

    public void setOnItemLongClickListener(OnItemLongClickListener l) {
        this.mOnItemLongClickListener = l;
    }

    public MyAdapter(Context context, List<String> datas) {
        this.datas = datas;
        inflater = LayoutInflater.from(context);
    }

    public class MyViewHolder extends RecyclerView.ViewHolder {
        private View itemView;
        private TextView title;
        CheckBox checkBox;


        public MyViewHolder(View itemView) {
            super(itemView);
            this.itemView = itemView;
            title = (TextView) itemView.findViewById(R.id.rv_main_item_title);
            checkBox=  itemView.findViewById(R.id.rv_main_checkbox);

        }
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        Log.e(TAG, "create a new item");
        MyViewHolder holder = new MyViewHolder(inflater.inflate(R.layout.rv_main_item, parent, false));
        return holder;
    }

    @Override
    public void onBindViewHolder(final MyViewHolder holder, final int position) {
        Log.e(TAG, "set value to item:" + position);
        holder.title.setText(datas.get(position));

        if(position%2==0){
            holder.checkBox.setChecked(true);
        }else{
            holder.checkBox.setChecked(false);
        }


        int height = Math.abs((new Random().nextInt(200)) );
        if (height < 10) {
            height += 70;
        }
        holder.title.setHeight(height);
     // 设置点击事件回调
        if (mOnItemClickListener != null) {
            holder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    int pos = holder.getLayoutPosition();
                    mOnItemClickListener.onClick(holder.itemView, pos);
                }
            });
        }
        // 设置长按 事件回调
        if (mOnItemLongClickListener != null) {
            holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View view) {
                    int pos = holder.getLayoutPosition();
                    mOnItemLongClickListener.onLongClick(holder.itemView, pos);
                    return false;
                }
            });
        }
    }

    @Override
    public int getItemCount() {
        return datas.size();
    }

    public void addData(int position, String content){
        datas.add(position,content);
    }

    public void removeData(int position){
        datas.remove(position);
    }
}

 3.     mRecyclerView.setLayoutManager(new LinearLayoutManager(this));   // 设置水平滚动 
     或者: 
         // 上下文、(水平、垂直滚动方向)、 是否逆序(逆序第一个摆在末尾)
     mRecyclerView.setLayoutManager(new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false));
            mRecyclerView.scrollToPosition(initData().size()-1);    // 滚动到底部

            
             mRecyclerView.setLayoutManager(new GridLayoutManager(this,3));    // 变gridview一行3个
             
               // 瀑布流,StaggeredGridLayoutManager.VERTICAL 垂直滑动  水平摆放4个
                // 有问题,因为复用,位置会自动调换
        mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(4, StaggeredGridLayoutManager.VERTICAL));
  
  3.     mMyAdapter = new MyAdapter(MainActivity.this, initData());  // initData()数据源和上下文
  
  4.     mRecyclerView.setAdapter(mMyAdapter);   // 设置adapter

 new Adapter以后Adapter内部会回调 , getItemCount 、onCreateViewHolder、onBindViewHolder 对应方法

  6.  设置item、点击长按事件: 
     // 给chiild item添加点击事件回调到外部

 7. item 添加删除
         // 设置添加、删除item默认动画
        mRecyclerView.setItemAnimator(new DefaultItemAnimator());
        
       mMyAdapter.notifyItemInserted(position);  // RecycleView有单独是适配方法,不像ListView要刷新说有的item 

MainActivity  代码区域: 

package org.xm.recyclerviewsimple;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.util.Log;
import android.view.View;
import android.widget.ImageButton;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivity";
    private RecyclerView mRecyclerView;
    private MyAdapter mMyAdapter;
    ImageButton ib_top;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ib_top = (ImageButton)findViewById(R.id.ib_top);

        mRecyclerView = (RecyclerView) findViewById(R.id.rv_main);
        // 默认垂直滚动
      //    mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
        // 上下文、(水平、垂直方向)、 是否逆序(逆序第一个摆在末尾)
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this,LinearLayoutManager.HORIZONTAL,false));
   //      mRecyclerView.scrollToPosition(initData().size()-1);    // 滚动到底部
        //    mRecyclerView.setLayoutManager(new GridLayoutManager(this,3));    // gridview一行3个
        // 瀑布流,StaggeredGridLayoutManager.VERTICAL 垂直滑动  水平摆放4个
    //    mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(4, StaggeredGridLayoutManager.VERTICAL));
        // 只有GridViewManager有这个方法
        GridLayoutManager gridLayoutManager=new GridLayoutManager(this,1);
        // 设置跨度大小监听
        gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
            @Override
            public int getSpanSize(int position) {
                Log.e("denganzhi1","position:"+position); // pisiton表示将要显示的item的position
                if(position<=10){
                    //隐藏
                    ib_top.setVisibility(View.GONE);
                }else{
                    //显示
                    ib_top.setVisibility(View.VISIBLE);
                }
                return 1;
            }
        });
        ib_top.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
               mRecyclerView.scrollToPosition(0);
            }
        });
      //  mRecyclerView.setLayoutManager(gridLayoutManager);
        SystemDivider  systemDivider=new SystemDivider(this);
        systemDivider.setmOriientation(LinearLayoutManager.HORIZONTAL);
        mRecyclerView.addItemDecoration(systemDivider);


        mMyAdapter = new MyAdapter(MainActivity.this, initData());
        mMyAdapter.setOnItemClickListener(new MyAdapter.OnItemClickListener() {
            @Override
            public void onClick(View parent, int position) {
                mMyAdapter.addData(position,"add at------new------:"+position);
           // // 设置添加、删除item默认动画
                // 会在positon前插入
                mMyAdapter.notifyItemInserted(position);
                //    mMyAdapter.notifyItemRangeInserted(int positionStart, int itemCount);  // 批量插入
            }
        });
        mMyAdapter.setOnItemLongClickListener(new MyAdapter.OnItemLongClickListener() {
            @Override
            public boolean onLongClick(View parent, int position) {
               // 设置item 的删除 
              mMyAdapter.removeData(position);
                mMyAdapter.notifyItemRemoved(position);
                return false;
            }
        });
        mRecyclerView.setAdapter(mMyAdapter);
//        mRecyclerView.addItemDecoration(new MyItemDivider(this,R.drawable.rv_main_item_divider));

        // 设置添加、删除item默认动画
      //  mRecyclerView.setItemAnimator(new DefaultItemAnimator());

    }

    private List<String> initData() {
        List<String> datas = new ArrayList<String>();
        for (int i = 0; i <= 100; i++) {
            datas.add("item:" + i);
        }
        return datas;
    }

// 切换为水平,布局切换
    SystemDivider  dector= null;
    public void shuiping(View view){
        // 必须要首先 removeItemDecoration
        mRecyclerView.removeItemDecoration(dector);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this,LinearLayoutManager.HORIZONTAL,false));

        dector =new SystemDivider(this);
        dector.setmOriientation(LinearLayoutManager.HORIZONTAL);

        mRecyclerView.addItemDecoration(dector);
    }
// 切换为垂直,布局切换
    public void chuizhi(View view){

        mRecyclerView.removeItemDecoration(dector);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false));

        dector =new SystemDivider(this);
        dector.setmOriientation(LinearLayoutManager.VERTICAL);

        mRecyclerView.addItemDecoration(dector);
    }
}


     8. 设置 绘制水平 、垂直 分割线
        解决方法:    如果是基本需要,只要下面有分割线条
1、可以字节写到ViewHolder中
         2、也可以设置margin ViewHoder的,然后设置背景
      实现原理: 继承  RecyclerView.ItemDecoration  首先重写 getItemOffsets 绘制一个Rect矩形
然后 onDraw 指定矩形坐标,根据坐标draw即可 mDivider.setBounds(left,top,right,bottom);
          如果是高要求: 水平 滚动左右都需要分 割线????

SystemDivider  分隔线代码区域: 

package org.xm.recyclerviewsimple;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.v4.view.ViewCompat;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;

/**
 * Created by denganzhi on 2020/3/2.
 */

public class SystemDivider extends  RecyclerView.ItemDecoration  {

    private  int mOriientation;

    public void setmOriientation(int mOriientation) {
        if(mOriientation != LinearLayoutManager.VERTICAL && mOriientation != LinearLayoutManager.HORIZONTAL ){
            throw  new  IllegalArgumentException("必须为水平或者垂直方向");
        }
        this.mOriientation = mOriientation;
    }

    private  int[] attrs=new int[]{
            android.R.attr.listDivider
    };

    private Drawable mDivider;

    public SystemDivider(Context context){
   //  获取系统分割线的 listDivider
        TypedArray typedArray=context.obtainStyledAttributes(attrs);

        mDivider=typedArray.getDrawable(0);

        typedArray.recycle();

    }

     // 2. 计算坐标绘制 mDivider.draw(c)
    @Override
    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
        super.onDraw(c, parent, state);
        // 垂直
        // Android Padding  和 div 一样
        if(this.mOriientation == LinearLayoutManager.VERTICAL){

          int  left = parent.getPaddingLeft();
          int right = parent.getWidth()-parent.getPaddingRight();

          int chiildCount = parent.getChildCount();

          for (int i=0;i<chiildCount;i++){
              View child = parent.getChildAt(i);

              RecyclerView.LayoutParams params= (RecyclerView.LayoutParams) child.getLayoutParams();

              int top = child.getBottom() + params.bottomMargin + Math.round(ViewCompat.getTranslationY(child));

              int bottom = top + mDivider.getIntrinsicHeight();


              mDivider.setBounds(left,top,right,bottom);

              mDivider.draw(c);

          }

        }else{


            int  top = parent.getPaddingTop();
            int bottom = parent.getHeight()- parent.getPaddingBottom();


            int childCount = parent.getChildCount();

            for (int i=0;i<childCount;i++){
                View child = parent.getChildAt(i);

                RecyclerView.LayoutParams params= (RecyclerView.LayoutParams) child.getLayoutParams();

                int left = child.getRight() +  params.rightMargin+ Math.round(ViewCompat.getTranslationX(child));
                int right = left + mDivider.getIntrinsicHeight();


                mDivider.setBounds(left,top,right,bottom);

                mDivider.draw(c);

            }


        }
    }

    //int left, int top, int right, int bottom
    // 1. 设置位置,占位置
    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        super.getItemOffsets(outRect, view, parent, state);

        //垂直滚动, 设置一个RECT占据位置
        if(this.mOriientation == LinearLayoutManager.VERTICAL){
            outRect.set(0, 0, 0, mDivider.getIntrinsicWidth());

        }else{

            outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
        }
    }
}

 最终效果:

      9. 给每一个Item绘制水平 、垂直分隔线 ,原理和 8 相同

styles.xml 中覆盖布局:

 item_divider.xml 选在器 /res/drawable下:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" 
    android:shape="rectangle">
    <size android:width="2dp" android:height="2dp"/>
	<solid android:color="#ff0000"/>
</shape>

 styles.xml

<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- 替换系统的listDivider  -->
        <item name="android:listDivider">@drawable/item_divider</item>
    </style>

</resources>
MyDivider 代码实现:
package mk.denganzhi.com.myapplication;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.v4.view.ViewCompat;
import android.support.v7.widget.RecyclerView;
import android.view.View;

/**
 * Created by denganzhi on 2020/3/3.
 */

public class MyDivider extends  RecyclerView.ItemDecoration  {

    private  int[] attrs=new int[]{
            android.R.attr.listDivider
    };

    private Drawable mDivider;


    public MyDivider(Context context){
        //  获取系统分割线的 listDivider
        TypedArray typedArray=context.obtainStyledAttributes(attrs);

        mDivider=typedArray.getDrawable(0);

        typedArray.recycle();

    }

    @Override
    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
       // 首先 调用自己的onDraw,然后在 绘制下面的
        super.onDraw(c, parent, state);

        drawVertical(c,parent);
        drawHorizontal(c,parent);
        //   // 绘制底部
    }
    private void drawHorizontal(Canvas c, RecyclerView parent) {
        // 绘制水平间隔线
        int childCount = parent.getChildCount();
        for (int i = 0; i < childCount; i++) {
            View child = parent.getChildAt(i);
            RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
            int left = child.getLeft() - params.leftMargin;
            int right = child.getRight()+ params.rightMargin;
            int top = child.getBottom() + params.bottomMargin;
            int bottom = top + mDivider.getIntrinsicHeight();

            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(c);
        }


    }

    private void drawVertical(Canvas c, RecyclerView parent) {
        //绘制垂直间隔线(垂直的矩形)
        int childCount = parent.getChildCount();
        for (int i = 0; i < childCount; i++) {
            View child = parent.getChildAt(i);
            RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
            int left = child.getRight() + params.rightMargin;
            int right = left + mDivider.getIntrinsicWidth();
            int top = child.getTop() - params.topMargin;
            int bottom = child.getBottom() + params.bottomMargin;

            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(c);
        }

    }


    // 1. 设置一个矩形
    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {


        int right = mDivider.getIntrinsicWidth();
        int bottom = mDivider.getIntrinsicHeight();

        //int left, int top, int right, int bottom)
        outRect.set(0,0,right,bottom);



        super.getItemOffsets(outRect, view, parent, state);
    }
}
MainActivity 中代码:
package mk.denganzhi.com.myapplication;

import android.content.Context;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class MainActivity extends AppCompatActivity {


    RecyclerView mRecyclerView;
    MyAdapter myAdapter;
    MyDivider myDivider;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mRecyclerView = findViewById(R.id.rv_main);

        mRecyclerView.setLayoutManager(new GridLayoutManager(this,3));    // gridview一行3个
        myAdapter = new MyAdapter(MainActivity.this, initData());
        mRecyclerView.setAdapter(new MyAdapter(this,initData()));
        myDivider = new MyDivider(this);
        mRecyclerView.addItemDecoration(myDivider);
    }

    private List<String> initData() {
        List<String> datas = new ArrayList<String>();
        for (int i = 0; i <= 100; i++) {
            datas.add("item:" + i);
        }
        return datas;
    }

    public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {

        private static final String TAG = "MyAdapter";
        private List<String> datas;
        private LayoutInflater inflater;

        public MyAdapter(Context context, List<String> datas) {
            this.datas = datas;
            inflater = LayoutInflater.from(context);
        }

        public class MyViewHolder extends RecyclerView.ViewHolder {
            private View itemView;
            private TextView title;
            ImageView checkBox;


            public MyViewHolder(View itemView) {
                super(itemView);
                this.itemView = itemView;
                title = (TextView) itemView.findViewById(R.id.rv_main_item_title);
                checkBox=  itemView.findViewById(R.id.rv_main_checkbox);

            }
        }

        @Override
        public MyAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            Log.e(TAG, "create a new item");
             MyAdapter.MyViewHolder holder = new MyAdapter.MyViewHolder(inflater.inflate(R.layout.rv_main_item, parent, false));
            return holder;
        }

        @Override
        public void onBindViewHolder(final MyAdapter.MyViewHolder holder, final int position) {
            Log.e(TAG, "set value to item:" + position);
            holder.title.setText(datas.get(position));
        }

        @Override
        public int getItemCount() {
            return datas.size();
        }

        public void addData(int position, String content){
            datas.add(position,content);
        }

        public void removeData(int position){
            datas.remove(position);
        }
    }

}

  效果图如下:

发布了77 篇原创文章 · 获赞 74 · 访问量 12万+

猜你喜欢

转载自blog.csdn.net/dreams_deng/article/details/104731732
今日推荐