第一步:添加相应的依赖库
RecyclerView定义在support库中,使用前需要在项目的build.gradle中添加相应的依赖才行。
- 右键app,选中OpenMoudleSetting一项,在弹出来的窗口选Dependencies,点击加号,选Librirary dependency。搜索添加,recyclerview和appcompat两项
compile 'com.android.support:recyclerview-v7:26.0.0-alpha1'
compile 'com.android.support:appcompat-v7:26.0.0-alpha1'
第二步:搭建itemView:布局RecyclerView的样式
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<ImageView
android:id="@+id/fruit_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/fruit_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dp"
/>
</LinearLayout>
第三步:定义一个实体类,存储itemView要显示的数据
public class Fruit {
private String name;
private int imageId;
public Fruit(String name, int imageId) {
this.name = name;
this.imageId = imageId;
}
public String getName() {
return name;
}
public int getImageId() {
return imageId;
}
}
第四步:自定义适配器
public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder> {
private List<Fruit> mFruitList;
//定义一个内部类,ViewHolder继承自RecyclerView.ViewHolder
static class ViewHolder extends RecyclerView.ViewHolder {
ImageView fruitImage;
TextView fruitNme;
//定义构造函数
public ViewHolder(android.view.View view) {
super(view);
fruitImage = (ImageView) view.findViewById(R.id.fruit_image);
fruitNme = (TextView) view.findViewById(R.id.fruit_name);
}
}
//定义一个构造函数,把要展示的数据源传进来
public FruitAdapter(List<Fruit> fruitList) {
mFruitList = fruitList;
}
/**因为ViewHolder是继承自RecyclerView.Adapter的,所以必须重写
* onCreateViewHolder():用于创建ViewHolder实例
* onBindViewHolder():用于对RecyclerView子项的数据进行赋值的,会在每个子项滚动到屏幕内的时候执行。
* getItemCount():用于告诉RecyclerView一共有多少个子项
* 3个方法*/
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//加载fruit_item布局
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.fruit_item, parent, false);
//创建viewHolder实例,把加载的布局出入到构造函数中
ViewHolder holder = new ViewHolder(view);
return holder;
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
//通过position参数得到当前的Fruit实例
Fruit fruit = mFruitList.get(position);
//把数据设置到ViewHolder中。
holder.fruitImage.setImageResource(fruit.getImageId());
holder.fruitNme.setText(fruit.getName());
}
@Override
public int getItemCount() {
//返回数据源的长度
return mFruitList.size();
}
}
第五步:加载RecyclerView
public class MainActivity extends AppCompatActivity {
private List<Fruit> fruitList = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_layout);
//初始化水果数据
initFruits();
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
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 bananna = new Fruit("Banana", R.drawable.banana_pic);
fruitList.add(bananna);
Fruit orange = new Fruit("Orange", R.drawable.orange_pic);
fruitList.add(orange);
Fruit watermelo = new Fruit("waterelon", R.drawable.watermelon_pic);
fruitList.add(watermelo);
Fruit pear = new Fruit("Pear", R.drawable.pear_pic);
fruitList.add(pear);
Fruit grape = new Fruit("Grape", R.drawable.grape_pic);
fruitList.add(grape);
Fruit pineapple = new Fruit("Pineapple", R.drawable.pineapple_pic);
fruitList.add(pineapple);
Fruit strawberry = new Fruit("cherry", R.drawable.cherry_pic);
fruitList.add(strawberry);
}
}
}
RecyclerView横向滚动
第一步:修改fruit_item布局如下
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="100dp"
android:layout_height="wrap_content"
//将LinearLayout改成垂直方向排列,图片在上,文字在下
android:orientation="vertical"
>
<ImageView
android:id="@+id/fruit_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
//设置图片水平居中
android:layout_gravity="center_horizontal"/>
<TextView
android:id="@+id/fruit_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
//设置文字水平居中
android:layout_gravity="center_vertical"
//设置文字与图片保持一定距离
android:layout_marginTop="10dp"
/>
</LinearLayout>
第二步:在activity中设置RecyclerView的滚动方向
public class MainActivity extends AppCompatActivity {
private List<Fruit> fruitList = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_layout);
//初始化水果数据
initFruits();
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
//设置RecyclerView滚动的方向
layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
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 bananna = new Fruit("Banana", R.drawable.banana_pic);
fruitList.add(bananna);
Fruit orange = new Fruit("Orange", R.drawable.orange_pic);
fruitList.add(orange);
Fruit watermelo = new Fruit("waterelon", R.drawable.watermelon_pic);
fruitList.add(watermelo);
Fruit pear = new Fruit("Pear", R.drawable.pear_pic);
fruitList.add(pear);
Fruit grape = new Fruit("Grape", R.drawable.grape_pic);
fruitList.add(grape);
Fruit pineapple = new Fruit("Pineapple", R.drawable.pineapple_pic);
fruitList.add(pineapple);
Fruit strawberry = new Fruit("cherry", R.drawable.cherry_pic);
fruitList.add(strawberry);
}
}
}
- 运行结果
- ListView和RecyclerView的差别
- ListView的布局排列是由自身去管理的,而RecyclerView则将工作交给LayoutManager,LayoutManager中制定了一套可扩展的布局排列接口,子类只要按照接口的规范来实现就可以制定出各种不同的排列方式的布局。
- GridLayoutManager和StaggeredGridLayoutManager也是RecyclerView提供的两种内置布局。GridLayoutManager可以用于网格布局,StaggeredGridLayoutManager可以用于实现瀑布流布局。
RecyclerView实现瀑布流布局
第一步:修改fruit_item布局文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
//设置宽度,由瀑布流的列数决定
android:layout_width="match_parent"
//设置高度随内容自适应
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_margin="5dp"
>
<ImageView
android:id="@+id/fruit_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"/>
<TextView
android:id="@+id/fruit_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:layout_marginLeft="10dp"
/>
</LinearLayout>
第二步:修改activity的代码
public class MainActivity extends AppCompatActivity {
private List<Fruit> fruitList = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_layout);
//初始化水果数据
initFruits();
//设置瀑布流滚动的列数
StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL);
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(getRandomLentgthName("apple"), R.drawable.apple_pic);
fruitList.add(apple);
Fruit bananna = new Fruit(getRandomLentgthName("Banana"), R.drawable.banana_pic);
fruitList.add(bananna);
Fruit orange = new Fruit(getRandomLentgthName("Orange"), R.drawable.orange_pic);
fruitList.add(orange);
Fruit watermelo = new Fruit(getRandomLentgthName("waterelon"), R.drawable.watermelon_pic);
fruitList.add(watermelo);
Fruit pear = new Fruit(getRandomLentgthName("Pear"), R.drawable.pear_pic);
fruitList.add(pear);
Fruit grape = new Fruit(getRandomLentgthName("Grape"), R.drawable.grape_pic);
fruitList.add(grape);
Fruit pineapple = new Fruit(getRandomLentgthName("Pineapple"), R.drawable.pineapple_pic);
fruitList.add(pineapple);
Fruit strawberry = new Fruit(getRandomLentgthName("cherry"), R.drawable.cherry_pic);
fruitList.add(strawberry);
}
}
private String getRandomLentgthName(String name) {
Random random = new Random();
int length = random.nextInt(20) + 1;
StringBuilder builder = new StringBuilder();
for (int i = 0; i < length; i++) {
builder.append(name);
}
return builder.toString();
}
}
RecyclerView的点击事件
不同ListView,RecyclerView没有OnItemClickListener()这样的注册监听器方法,而是需要在Adapter中在OnCreateViewHolder()方法中给具体的子项注册点击事件。
private List<Fruit> mFruitList;
//定义一个内部类,ViewHolder继承自RecyclerView.ViewHolder
static class ViewHolder extends RecyclerView.ViewHolder {
View fruitView;
ImageView fruitImage;
TextView fruitNme;
//定义构造函数
public ViewHolder(View view) {
super(view);
fruitView = view;
fruitImage = (ImageView) view.findViewById(R.id.fruit_image);
fruitNme = (TextView) view.findViewById(R.id.fruit_name);
}
}
//定义一个构造函数,把要展示的数据源传进来
public FruitAdapter(List<Fruit> fruitList) {
mFruitList = fruitList;
}
/**因为ViewHolder是继承自RecyclerView.Adapter的,所以必须重写
* onCreateViewHolder():用于创建ViewHolder实例
* onBindViewHolder():用于对RecyclerView子项的数据进行赋值的,会在每个子项滚动到屏幕内的时候执行。
* getItemCount():用于告诉RecyclerView一共有多少个子项
* 3个方法*/
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//加载fruit_item布局
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.fruit_item, parent, false);
//创建viewHolder实例,把加载的布局出入到构造函数中
final ViewHolder holder = new ViewHolder(view);
//注册点击事件
holder.fruitView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int position = holder.getAdapterPosition();
Fruit fruit = mFruitList.get(position);
Toast.makeText(v.getContext(), "点击了背景视图"+fruit.getName(), Toast.LENGTH_SHORT).show();
}
});
holder.fruitImage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int position = holder.getAdapterPosition();
Fruit fruit = mFruitList.get(position);
Toast.makeText(v.getContext(), "点击了图片"+fruit.getName(), Toast.LENGTH_SHORT).show();
}
});
return holder;
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
//通过position参数得到当前的Fruit实例
Fruit fruit = mFruitList.get(position);
//把数据设置到ViewHolder中。
holder.fruitImage.setImageResource(fruit.getImageId());
holder.fruitNme.setText(fruit.getName());
}
@Override
public int getItemCount() {
//返回数据源的长度
return mFruitList.size();
}
}