一、为什么用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();
}
}