RecyclerView实例讲解

RecyclerView是什么:

RecylerView是support-v7包中的新组件,是一个强大的滑动组件,那么已经有了ListView,为什么还要存在RecyclerView,因为他的优势有很多啊。

RecyclerView优势:

1.自带缓存原理
2.灵活的控制item的增删动画,布局构造也很方便改变。
3.扩展性好

RecyclerView如何使用:

1.添加依赖包
2.创建布局文件(类比电动车)
3.创建实体类(类比充电器电线)
4.创建适配器(类比充电器核心部分)
5.填充数据,绑定适配器(电源,同时连接充电器,电动车)

效果展现:

代码实现:
1.添加依赖包:
compile 'com.android.support:recyclerview-v7:26.1.0'
2.创建布局文件player_item.xml(类比电动车)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:orientation="horizontal"
    android:layout_height="wrap_content">

    <ImageView
        android:id="@+id/item_imgv"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_margin="5dp"
        android:src="@mipmap/ic_launcher_round"/>

    <TextView
        android:id="@+id/item_tv"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:text="梅西"
        android:textSize="25sp"
        android:gravity="center_vertical"/>

</LinearLayout>
3.创建实体类(类比充电器电线)
public class Player {
    //表示球星的名字
    private String playerName;
    //表示图片的id
    private  int imgID;

    public Player(String playerName, int imgID) {
        this.playerName = playerName;
        this.imgID = imgID;
    }

    public String getPlayerName() {
        return playerName;
    }

    public void setPlayerName(String playerName) {
        this.playerName = playerName;
    }

    public int getImgID() {
        return imgID;
    }

    public void setImgID(int imgID) {
        this.imgID = imgID;
    }
}
4.创建适配器(类比充电器核心部分)
//自定义类继承RecyclerView.Adapter,将泛型指定为PlayerAdapter.ViewHolder
public class PlayerAdapter extends RecyclerView.Adapter<PlayerAdapter.ViewHolder> {
    //创建list集合,泛型为之前定义的实体类
    private List<Player> playerList;
    //添加构造方法
    public PlayerAdapter(List<Player> playerList) {
        this.playerList = playerList;
    }
    //在onCreateViewHolder()中完成布局的绑定,同时创建ViewHolder对象,返回ViewHolder对象
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.player_item,parent,false);
        ViewHolder holder = new ViewHolder(view);
        return holder;
    }
    //在内部类中完成对控件的绑定
    public class ViewHolder extends RecyclerView.ViewHolder {

        private ImageView imageView;
        private TextView textView;

        public ViewHolder(View itemView) {
            super(itemView);
            imageView = itemView.findViewById(R.id.item_imgv);
            textView = itemView.findViewById(R.id.item_tv);
        }
    }
    //在onBindViewHolder()中完成对数据的填充
    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {

        holder.imageView.setImageResource(playerList.get(position).getImgID());
        holder.textView.setText(playerList.get(position).getPlayerName());
    }
    //这个方法很简单了,返回playerList中的子项的个数
    @Override
    public int getItemCount() {
        return playerList.size();
    }
}
5.填充数据,绑定适配器(电源,同时连接充电器,电动车)

1.修改MainActivity中的布局,添加RecyclerView控件:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.recyclerviewtest.MainActivity">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/main_rv"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    </android.support.v7.widget.RecyclerView>

</android.support.constraint.ConstraintLayout>

2.修改MainActivity中的代码:

public class MainActivity extends AppCompatActivity {

    private RecyclerView recyclerView;
    private List<Player> playerList = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //initList()方法用于给playerList填充数据
        initList();

        recyclerView = findViewById(R.id.main_rv);
        //创建LinearLayoutManager,用于决定RecyclerView的布局方式
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(MainActivity.this);
        recyclerView.setLayoutManager(linearLayoutManager);
        //创建适配器
        PlayerAdapter adapter = new PlayerAdapter(playerList);
        recyclerView.setAdapter(adapter);
    }

    private void initList() {
        for (int i = 0;i<3;i++){
            //通过条用构造方法,赋值
            Player messi = new Player("梅西",R.mipmap.messi);
            //将数据填充到playerList中去
            playerList.add(messi);
            Player cluo = new Player("C罗",R.mipmap.cluo);
            playerList.add(cluo);
            Player guadi = new Player("瓜迪奥拉",R.mipmap.guadi);
            playerList.add(guadi);
            Player debu = new Player("德布劳内",R.mipmap.debu);
            playerList.add(debu);
            Player xiaobai = new Player("小白",R.mipmap.xiaobai);
            playerList.add(xiaobai);
            Player sunke = new Player("孙可",R.mipmap.sunke);
            playerList.add(sunke);
        }
    }
}
over
之前我提到RecyclerView有很好的扩展性,不过扩展性好有什么用呢,下面我用一个例子来说明,实现内容的横向滚动。
效果展现:

代码实现步骤:
1.修改player_item.xml中的布局文件,这里修改布局主要是为了美观,并不妨碍功能的实现:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="60dp"
    android:orientation="vertical"
    android:layout_height="wrap_content">

    <ImageView
        android:id="@+id/item_imgv"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_margin="5dp"
        android:src="@mipmap/ic_launcher_round"/>

    <TextView
        android:id="@+id/item_tv"
        android:layout_gravity="center_horizontal"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:text="梅西"
        android:textSize="15sp"
        />

</LinearLayout>
2.在MainActivity中添加一句话,就OK了:
 recyclerView = findViewById(R.id.main_rv);
        //创建LinearLayoutManager,用于决定RecyclerView的布局方式
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(MainActivity.this);
        //通过setOrientation()设置布局的排列方向
        linearLayoutManager.setOrientation(LinearLayout.HORIZONTAL);
        recyclerView.setLayoutManager(linearLayoutManager);
        //创建适配器
        PlayerAdapter adapter = new PlayerAdapter(playerList);
        recyclerView.setAdapter(adapter);
RecyclerView除了LinearlayoutManager外,还有其他的布局方式,下面我们就是用StaggeredGridLayoutManager来实现瀑布流的效果吧:
效果展现:

代码实现:
1.修改player_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="wrap_content"
    android:orientation="vertical">

    <ImageView
        android:id="@+id/item_imgv"
        android:layout_width="match_parent"
        android:layout_height="150dp"
        android:layout_gravity="center_horizontal"
        android:src="@mipmap/ic_launcher_round" />

    <TextView
        android:id="@+id/item_tv"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="left"
        android:text="梅西"
        android:textSize="15sp"
        android:layout_marginTop="10dp"/>

</LinearLayout>
修改MainActivity中的代码
public class MainActivity extends AppCompatActivity {

    private RecyclerView recyclerView;
    private List<Player> playerList = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //initList()方法用于给playerList填充数据
        initList();
        recyclerView = findViewById(R.id.main_rv);
        //创建StaggeredGridLayoutManager,瀑布布局
        /**
         * @param spanCount   If orientation is vertical, spanCount is number of columns. If
         *                    orientation is horizontal, spanCount is number of rows.  分割的数目,具体可以看英文备注
         * @param orientation {@link #VERTICAL} or {@link #HORIZONTAL}  布局的排列方式
         */
        StaggeredGridLayoutManager staggeredGridLayoutManager = new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL);
        recyclerView.setLayoutManager(staggeredGridLayoutManager);
        //创建适配器
        PlayerAdapter adapter = new PlayerAdapter(playerList);
        recyclerView.setAdapter(adapter);
    }

    private void initList() {
        for (int i = 0;i<3;i++){
            //通过条用构造方法,赋值,调用getRandomLengthName()方法获取随机长度的名字
            Player messi = new Player(getRandomLengthName("梅西"),R.mipmap.messi);
            //将数据填充到playerList中去
            playerList.add(messi);
            Player cluo = new Player(getRandomLengthName("C罗"),R.mipmap.cluo);
            playerList.add(cluo);
            Player guadi = new Player(getRandomLengthName("瓜迪奥拉"),R.mipmap.guadi);
            playerList.add(guadi);
            Player debu = new Player(getRandomLengthName("德布劳内"),R.mipmap.debu);
            playerList.add(debu);
            Player xiaobai = new Player(getRandomLengthName("小白"),R.mipmap.xiaobai);
            playerList.add(xiaobai);
            Player sunke = new Player(getRandomLengthName("孙可"),R.mipmap.sunke);
            playerList.add(sunke);
        }
    }
    //这里创建getRandomLengthName()方法是因为,如果名字的长度几乎一样长,瀑布流的效果就不能很明显得展现出来
    private String getRandomLengthName(String name){
        //产生1-10的随机数
        Random random = new Random();
        int length = random.nextInt(10)+1;
        //创建StringBuilder对象,他是字符长变量,可以通过append()方法增长他的长度
        StringBuilder builder = new StringBuilder();
        for (int i=0;i<length;i++){
            builder.append(name);
        }
        return builder.toString();
    }
}
over
最后如何对RecyclerView的子项进行监听呢,RecyclerView并不能像ListView那样对子项直接进行监听,那是因为直接对子项进行监听有一个缺点,那就是只能对整个子项目进行监听,要实现对子项中的某个控件进行监听则比较苦难,所以RecyclerView就直接摈弃了这种监听方法,那么他是怎么实现监听的呢?下面我将做出解答:
效果展现:

代码实现:只需要修改适配器部分:
//自定义类继承RecyclerView.Adapter,将泛型指定为PlayerAdapter.ViewHolder
public class PlayerAdapter extends RecyclerView.Adapter<PlayerAdapter.ViewHolder> {
    //创建list集合,泛型为之前定义的实体类
    private List<Player> playerList;
    //添加构造方法
    public PlayerAdapter(List<Player> playerList) {
        this.playerList = playerList;
    }
    //在onCreateViewHolder()中完成布局的绑定,同时创建ViewHolder对象,返回ViewHolder对象
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.player_item,parent,false);
        final ViewHolder holder = new ViewHolder(view);
        //在onCreateViewHolder()中对子项进行监听
        //holder.playerView说明他是对整个子项进行监听
        holder.playerView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //通过getAdapterPosition()方法获取点击的是哪个子项
                int position = holder.getAdapterPosition();
                Toast.makeText(v.getContext(),playerList.get(position).getPlayerName(), Toast.LENGTH_SHORT).show();
            }
        });
        //holder.imageView说明他是对图片进行监听
        holder.imageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int position = holder.getAdapterPosition();
                Toast.makeText(v.getContext(), ""+playerList.get(position).getImgID(), Toast.LENGTH_SHORT).show();
            }
        });
        return holder;
    }
    //在内部类中完成对控件的绑定
    static class ViewHolder extends RecyclerView.ViewHolder {
        //创建View变量playerView,用来对整个子项进行监听
        private View playerView;
        private ImageView imageView;
        private TextView textView;

        public ViewHolder(View itemView) {
            super(itemView);
            //将子项对外层的布局itemView赋给playerView,这样就能表示整个子项
            playerView = itemView;
            imageView = itemView.findViewById(R.id.item_imgv);
            textView = itemView.findViewById(R.id.item_tv);
        }
    }
    //在onBindViewHolder()中完成对数据的填充
    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {

        holder.imageView.setImageResource(playerList.get(position).getImgID());
        holder.textView.setText(playerList.get(position).getPlayerName());
    }
    //这个方法很简单了,返回playerList中的子项的个数
    @Override
    public int getItemCount() {
        return playerList.size();
    }
}
over

如果对你有所帮助:这是我的支付宝账户:18018346990,哈哈

  • 10
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

intoSunshine

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值