第三章 RecyclerView

本文详细介绍了如何使用RecyclerView替代ListView,并展示了其实现方法,包括不同布局管理器的使用,如LinearLayoutManager、StaggeredGridLayoutManager和GridLayoutManager,还介绍了如何为RecyclerView添加点击事件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、为什么用RecyclerView来代替ListView
①ListView性能较差,需要使用一些技巧来优化它
②RecyclerView优化了ListView存在的各种不足之处

二、基本用法
1、 在build.gradle中的dependencies闭包中添加

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

添加后如下

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:25.3.1'
    compile 'com.android.support.constraint:constraint-layout:1.0.2'
    compile 'com.android.support:recyclerview-v7:25.3.1'
    testCompile 'junit:junit:4.12'
}

添加后同步即可

2、在布局中加入RecyclerView控件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_height="match_parent"
    android:layout_width="match_parent">

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

三、实现和ListView中的水果类相同的效果
1.将ListView例子中的fruit类和fruit_item.xml复制过来
2.新建一个FruitAdapter类

package com.example.kim.recyclerview;

import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.List;

/**
 * Created by KIM on 2017/4/27.
 */

public  class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder> {
    private List<Fruit> mFruitList;

    //定义一个内部类ViewHolder并继承RecyclerView的ViewHolder
    static class   ViewHolder extends RecyclerView.ViewHolder{
        ImageView fruitImage;
        TextView  fruitName;
    //用于获取到布局中ImageView和TextView中的实例
        public ViewHolder(View view){
            super(view);
            fruitImage= (ImageView)view.findViewById(R.id.fruit_image);
            fruitName =(TextView)view.findViewById(R.id.fruit_name);
        }
    }
    //用于把用展现的数据源传进来
        public FruitAdapter(List<Fruit>fruitList){
            mFruitList=fruitList;
        }
    //FruitAdapter继承自Recycler.Adapter 就必须重写onCreateViewHolder()、onBindViewHolder()
    //和getItemCount()
    //onCreateViewHolder用于创建ViewHolder实例
        public ViewHolder onCreateViewHolder(ViewGroup parent,int viewType){
            View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.
                            fruit_item,parent,false);
            ViewHolder holder = new ViewHolder(view);
            return holder;
        }

    @Override//用于对RecyclerView的每个子项进行赋值,用position来得到当前实例
         public void onBindViewHolder(ViewHolder holder, int position) {
            Fruit fruit = mFruitList.get(position);
            holder.fruitName.setText(fruit.getName());
            holder.fruitImage.setImageResource(fruit.getImageId());
        }
    //用于告诉Recycler有多少子项
    public int getItemCount(){
            return mFruitList.size();
        }
}

3、修改MainActivity中的代码

package com.example.kim.recyclerview;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.widget.LinearLayout;

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

public class MainActivity extends AppCompatActivity {
    private List<Fruit>fruitList=new ArrayList<>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initFruits();
        //获取RecyclerView实例
        RecyclerView recyclerView=(RecyclerView)findViewById(R.id.recycler_view);
        //创建一个LinearLayoutManger对象 设置到RecyclerView对象当中,用于实现RecyclerView的存在方式
        LinearLayoutManager layoutManager=new LinearLayoutManager(this);
        recyclerView.setLayoutManager(layoutManager);

        FruitAdapter adapter = new FruitAdapter(fruitList);
        recyclerView.setAdapter(adapter);
    }
    private void initFruits(){
        for(int i=0;i<2;i++){
            Fruit apple =new Fruit("Apple",R.drawable.apple_pic);
            fruitList.add(apple);
            Fruit mango =new Fruit("Mango",R.drawable.mango_pic);
            fruitList.add(mango);
            //.........省略N多水果
        }
}

四、实现横向滚动
1.对fruit_item进行修改

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="100dp"
    //因为每种水果文字长度不同,用wrap_content的话
    //RecyclerView子项会长短不一,所以使用固定值100dp
    android:layout_height="wrap_content">

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/fruit_image"
        android:layout_gravity="center_horizontal"/>
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/fruit_name"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="10dp"/>
</LinearLayout>

2、对MainActivity进行修改

package com.example.kim.recyclerview;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.widget.LinearLayout;

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

public class MainActivity extends AppCompatActivity {
    private List<Fruit> fruitList = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initFruits();
        //获取RecyclerView实例
        RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
        //创建一个LinearLayoutManger对象 设置到RecyclerView对象当中,用于实现RecyclerView的存在方式
        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
        recyclerView.setLayoutManager(layoutManager);

        FruitAdapter adapter = new FruitAdapter(fruitList);
        recyclerView.setAdapter(adapter);
    }

    private void initFruits() {
        for (int i = 0; i < 20; i++) {
            Fruit apple = new Fruit("Apple", R.drawable.apple_pic);
            fruitList.add(apple);
            Fruit mango = new Fruit("Mango", R.drawable.mango_pic);
            fruitList.add(mango);
            //.........省略N多水果
        }
    }
}

五、实现瀑布流布局(StaggeredGridManager)
1、修改fruit_item

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_margin="5dp">
    <!--    这里将100dp修改成wrap_content,因为瀑布流的
        宽度应根据布局的列数来自动适配-->

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/fruit_image"
        android:layout_gravity="center_horizontal"/>
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/fruit_name"
        android:layout_gravity="left"
        android:layout_marginTop="10dp"/>
</LinearLayout>

2、修改MainActivity

package com.example.kim.recyclerview;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.widget.LinearLayout;

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

public class MainActivity extends AppCompatActivity {
    private List<Fruit> fruitList = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initFruits();
        //获取RecyclerView实例
        RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
        StaggeredGridLayoutManager layoutManager =new
                StaggeredGridLayoutManager(4,StaggeredGridLayoutManager.VERTICAL);
        //传入2个参数,布局列数和布局排列方向
        recyclerView.setLayoutManager(layoutManager);
        FruitAdapter adapter = new FruitAdapter(fruitList);
        recyclerView.setAdapter(adapter);
    }

    private void initFruits() {
        for (int i = 0; i < 20; i++) {
            Fruit apple = new Fruit(getRandomLengthName("apple"), R.drawable.apple_pic);
            fruitList.add(apple);
            Fruit mango = new Fruit(getRandomLengthName("mango"), R.drawable.mango_pic);
            fruitList.add(mango);
            //.........省略N多水果
        }
    }

    //创建一个getRandomLengthName方法,使水果的名字随机重复几次,来使瀑布流效果明显
    private String getRandomLengthName(String name){
        Random random = new Random();
        int length = random.nextInt(20)+1;
        //若不+1则产生0-19之间的整数,+1后产生1—10之间的整数
        StringBuilder builder = new StringBuilder();
        for(int i=0;i<length;i++){
            builder.append(name);
            //append()用于字符串拼接
        }
        return builder.toString();
    }
}

六、实现网格布局(GridLayoutManager)

package com.example.kim.recyclerview;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.widget.LinearLayout;

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

public class MainActivity extends AppCompatActivity {
    private List<Fruit> fruitList = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initFruits();
        RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
        GridLayoutManager layoutManager =new
                GridLayoutManager(MainActivity.this,4);
        //这里传入两个参数context和布局列数
        recyclerView.setLayoutManager(layoutManager);
        FruitAdapter adapter = new FruitAdapter(fruitList);
        recyclerView.setAdapter(adapter);
    }

    private void initFruits() {
        for (int i = 0; i < 20; i++) {
            Fruit apple = new Fruit("apple", R.drawable.apple_pic);
            fruitList.add(apple);
            Fruit mango = new Fruit("mango", R.drawable.mango_pic);
            fruitList.add(mango);
            //.........省略N多水果
        }
    }
}

七、RecyclerView的点击事件

package com.example.kim.recyclerview;

import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import java.util.List;

/**
 * Created by KIM on 2017/4/27.
 */

public  class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder> {
    private List<Fruit> mFruitList;

    //定义一个内部类ViewHolder并继承RecyclerView的ViewHolder
    static class   ViewHolder extends RecyclerView.ViewHolder{
        View fruitView;
        //添加fruitView
        ImageView fruitImage;
        TextView  fruitName;
    //用于获取到布局中ImageView和TextView中的实例
        public ViewHolder(View view){
            super(view);
            fruitView = view;
            //用fruitView来保存子项最外层布局
            fruitImage= (ImageView)view.findViewById(R.id.fruit_image);
            fruitName =(TextView)view.findViewById(R.id.fruit_name);
        }
    }
    //用于把用展现的数据源传进来
        public FruitAdapter(List<Fruit>fruitList){
            mFruitList=fruitList;
        }
    //FruitAdapter继承自Recycler.Adapter 就必须重写onCreateViewHolder()、onBindViewHolder()
    //和getItemCount()
    //onCreateViewHolder用于创建ViewHolder实例
        public ViewHolder onCreateViewHolder(ViewGroup parent,int viewType){
            View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.
                            fruit_item,parent,false);
           final ViewHolder holder = new ViewHolder(view);
            holder.fruitView.setOnClickListener(new View.OnClickListener(){
                public void onClick(View v){
                    int position = holder.getAdapterPosition();
                    Fruit fruit=mFruitList.get(position);
                    Toast.makeText(v.getContext(),"You Click View",Toast.LENGTH_SHORT).show();
                }
            });
            holder.fruitImage.setOnClickListener(new View.OnClickListener(){
                public void onClick(View v){
                    int position=holder.getAdapterPosition();
                    Fruit fruit=mFruitList.get(position);
                    Toast.makeText(v.getContext(),"You Click Image",Toast.LENGTH_SHORT).show();
                }
            });
            holder.fruitName.setOnClickListener(new View.OnClickListener(){
                public void onClick(View v){
                    int position = holder.getAdapterPosition();
                    Fruit fruit = mFruitList.get(position);
                    Toast.makeText(v.getContext(),"You Click Name",Toast.LENGTH_SHORT).show();
                }
            });
            return holder;
        }

    @Override//用于对RecyclerView的每个子项进行赋值,用position来得到当前实例
         public void onBindViewHolder(ViewHolder holder, int position) {
            Fruit fruit = mFruitList.get(position);
            holder.fruitName.setText(fruit.getName());
            holder.fruitImage.setImageResource(fruit.getImageId());
        }
    //用于告诉Recycler有多少子项
    public int getItemCount(){
            return mFruitList.size();
        }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值