Android界面的丰富多彩都是由于ListView的默默付出,但是需求日益变化,ListView的已经不再好用,并且不再满足“用户日益增长的娱乐需要同落后界面的矛盾”,于是乎Google 开发出来了RecycleView来满足用户各种苛刻需求------说人话。。。
为什么要学RecycleView呢,说来话长,大概是是由于android面试的时候吹牛逼被打脸了...很疼,然后学吧争取不再被打脸,最少不是那么痛 \(0◇0)/。
一、做一个小demo练习一下类似于ListView的简单效果
准备:10张小图片作为素材(地址:
https://pan.baidu.com/s/1dHhdN81)
打开AndroidStudio开始吧
首先,创建一个Bean类
package com.example.hxd.gittest;
public class WangZhe{
private String name;
private int imageId;
public Fruit(String name, int imageId) {
this.name = name;
this.imageId = imageId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getImageId() {
return imageId;
}
public void setImageId(int imageId) {
this.imageId = imageId;
}
}
这个类没有什么好说的。
然后创建一个item用来显示每个recycleView的条目
<?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">
<ImageView
android:id="@+id/iv_name"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_marginLeft="20dp"
android:layout_marginTop="5dp"
android:scaleType="fitXY"
android:src="@mipmap/ic_launcher" />
<TextView
android:id="@+id/tv_img"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dp"
android:text="小机器人" />
</LinearLayout>
显示效果为:
item显示效果
之后,创建RecycleView所在的Activity的布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.hxd.gittest.MainActivity">
<android.support.v7.widget.RecyclerView
android:id="@+id/rv_test"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
重头戏,书写适配器Adapter
package com.example.hxd.gittest;
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;
//1、创建一个Adapter继承自RecyclerView.Adapter,并且泛型为创建的Adapter的ViewHolder
public classWangZheAdapter extends RecyclerView.Adapter<WangZheAdapter.ViewHolder> {
//2、创建适配器数据源
private List<WangZhe> wangZheList ;
//3、构造方法传入数据
public WangZheAdapter(List<WangZhe> wangZhes) {
wangZheList = wangZhes;
}
//4、创建内部类ViewHolder继承自ecyclerView.ViewHolder
//初始化item内部控件
public class ViewHolder extends RecyclerView.ViewHolder {
ImageView ivWZ;
TextView tvWZ;
public ViewHolder(View itemView) {
super(itemView);
ivWZ = itemView.findViewById(R.id.iv_name);
tvWZ = itemView.findViewById(R.id.tv_img);
}
}
//5、重写onCreateViewHolder()方法加载item内部布局,并且返回ViewHolder
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false);
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
//6、重写onBindViewHolder()方法将控件和数据进行适配
@Override
public void onBindViewHolder(WangZheAdaoter.ViewHolder holder, int position) {
wangZhefruit = wangZhList.get(position);
holder.ivWZ.setImageResource(wangZhe.getImageId());
holder.tvWZ.setText(wangZhe.getName());
}
//7、重写getItemCount()方法返回数据源的大小
@Override
public int getItemCount() {
return wangZheList.size();
}
}
创建Adapter一共6步:
①、创建Adapter继承自RecycleView的adapter,并且泛型为创建Adapter的ViewHolder;
②、创建数据源,并且创建含参构造方方法用于向Adapter内部传入数据;
③、创建内部类AdapterViewHolder继承自RecycleView的ViewHolder,并且在内部初始化item数据;
④、重写onCreateViewHolwer(ViewGroup parent,int viewType)方法进行加载布局;
⑤、重写onBindViewHolder(WangZheAdaoter.ViewHolder holder, int position)方法进行数据的适配;
⑥、重写getItemCount方法,返回数据源大小;
好了Adapter就这么简单的创建完成了
最后,在Activity内来实现效果
package com.example.hxd.gittest;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends BaseActivity {
private List<WangZhe> wangZhes= new ArrayList<>();
private RecyclerView rvWZ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initWangZhe();
rvWZ= findViewById(R.id.rv_test);
//创建layout管理器
LinearLayoutManager lm = new LinearLayoutManager(this);
//将管理器设置给RecycleView
rvWZ.setLayoutManager(lm);
WangZheAdapter adapter = new WangZheAdapter (wangZhes);
rvWZ.setAdapter(adapter);
}
private void initWangZhe() {
for (int i = 0; i < 2; i++) {
WangZhe bianqu = new WangZhe ("扁鹊", R.mipmap.bianque);
wangZhes.add(bianqu);
WangZhe daji = new WangZhe ("妲己", R.mipmap.daji);
wangZhes.add(daji);
WangZhe diaochan = new WangZhe ("貂蝉", R.mipmap.diaochan);
wangZhes.add(diaochan);
WangZhe huamulan = new WangZhe ("花木兰", R.mipmap.huamulan);
wangZhes.add(huamulan);
WangZhe libai = new WangZhe ("李白", R.mipmap.libai);
wangZhes.add(libai);
WangZhe liubei = new WangZhe ("刘备", R.mipmap.liubei);
wangZhes.add(liubei);
WangZhe sunbin = new WangZhe ("扁鹊", R.mipmap.sunbin);
wangZhes.add(sunbin);
WangZhe sunshangxiang = new WangZhe ("孙尚香", R.mipmap.sunshangxiang);
wangZhes.add(sunshangxiang);
WangZhe yuji = new WangZhe ("虞姬", R.mipmap.yuji);
wangZhes.add(yuji);
WangZhe zhuangzhou = new WangZhe ("庄周", R.mipmap.zhuangzhou);
wangZhes.add(zhuangzhou);
}
}
}
是不是很简单,来看一下效果
简单Demo效果
二、实现横向滑动
首先,更改一下item布局
<?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="vertical">
<ImageView
android:id="@+id/iv_name"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_marginHorizontal="10dp"
android:layout_marginTop="5dp"
android:scaleType="fitXY"
android:src="@mipmap/ic_launcher" />
<TextView
android:id="@+id/tv_img"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginHorizontal="10dp"
android:gravity="center"
android:text="小机器人" />
</LinearLayout>
横向滑动布局item
然后,微调MainActivity内部代码
package com.example.hxd.gittest;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends BaseActivity {
private List<WangZhe> wangZhes= new ArrayList<>();
private RecyclerView rvWZ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initWangZhe();
rvWZ= findViewById(R.id.rv_test);
//创建layout管理器
LinearLayoutManager lm = new LinearLayoutManager(this);
//实现横向滑动的代码控制,默认纵向滑动
lm.setOrientation(LinearLayout.HORIZONTAL);
//将管理器设置给RecycleView
rvWZ.setLayoutManager(lm);
WangZheAdapter adapter = new WangZheAdapter (wangZhes);
rvWZ.setAdapter(adapter);
}
private void initWangZhe() {
for (int i = 0; i < 2; i++) {
WangZhe bianqu = new WangZhe ("扁鹊", R.mipmap.bianque);
wangZhes.add(bianqu);
WangZhe daji = new WangZhe ("妲己", R.mipmap.daji);
wangZhes.add(daji);
WangZhe diaochan = new WangZhe ("貂蝉", R.mipmap.diaochan);
wangZhes.add(diaochan);
WangZhe huamulan = new WangZhe ("花木兰", R.mipmap.huamulan);
wangZhes.add(huamulan);
WangZhe libai = new WangZhe ("李白", R.mipmap.libai);
wangZhes.add(libai);
WangZhe liubei = new WangZhe ("刘备", R.mipmap.liubei);
wangZhes.add(liubei);
WangZhe sunbin = new WangZhe ("扁鹊", R.mipmap.sunbin);
wangZhes.add(sunbin);
WangZhe sunshangxiang = new WangZhe ("孙尚香", R.mipmap.sunshangxiang);
wangZhes.add(sunshangxiang);
WangZhe yuji = new WangZhe ("虞姬", R.mipmap.yuji);
wangZhes.add(yuji);
WangZhe zhuangzhou = new WangZhe ("庄周", R.mipmap.zhuangzhou);
wangZhes.add(zhuangzhou);
}
}
}
细心的你会发现只是增加了
lm.setOrientation(LinearLayout.HORIZONTAL);
代码,简单吧。
三、实现炫酷瀑布流效果
首先,将item布局改成如下样式
<?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:layout_margin="10dp"
android:orientation="vertical">
<ImageView
android:id="@+id/iv_name"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_marginHorizontal="10dp"
android:layout_marginTop="5dp"
android:scaleType="fitXY"
android:src="@mipmap/ic_launcher" />
<TextView
android:id="@+id/tv_img"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:layout_marginHorizontal="10dp"
android:gravity="center"
android:text="小机器人" />
</LinearLayout>
item效果
然后修Activity内部代码
package com.example.hxd.gittest;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends BaseActivity {
private List<WangZhe> wangZhes= new ArrayList<>();
private RecyclerView rvWZ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initWangZhe();
rvWZ= findViewById(R.id.rv_test);
//瀑布流管理器
StaggeredGridLayoutManager sglm = new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL);
rvFruit.setLayoutManager(sglm);
//将管理器设置给RecycleView
rvWZ.setLayoutManager(lm);
WangZheAdapter adapter = new WangZheAdapter (wangZhes);
rvWZ.setAdapter(adapter);
}
private void initWangZhe() {
for (int i = 0; i < 2; i++) {
WangZhe bianqu = new WangZhe (getRandomName("扁鹊"), R.mipmap.bianque);
wangZhes.add(bianqu);
WangZhe daji = new WangZhe (getRandomName("妲己"), R.mipmap.daji);
wangZhes.add(daji);
WangZhe diaochan = new WangZhe (getRandomName("貂蝉"), R.mipmap.diaochan);
wangZhes.add(diaochan);
WangZhe huamulan = new WangZhe (getRandomName("花木兰"), R.mipmap.huamulan);
wangZhes.add(huamulan);
WangZhe libai = new WangZhe (getRandomName("李白"), R.mipmap.libai);
wangZhes.add(libai);
WangZhe liubei = new WangZhe (getRandomName("刘备"), R.mipmap.liubei);
wangZhes.add(liubei);
WangZhe sunbin = new WangZhe getRandomName("孙膑"), R.mipmap.sunbin);
wangZhes.add(sunbin);
WangZhe sunshangxiang = new WangZhe (getRandomName("孙尚香"), R.mipmap.sunshangxiang);
wangZhes.add(sunshangxiang);
WangZhe yuji = new WangZhe (getRandomName("虞姬"), R.mipmap.yuji);
wangZhes.add(yuji);
WangZhe zhuangzhou = new WangZhe (getRandomName("庄周"), R.mipmap.zhuangzhou);
wangZhes.add(zhuangzhou);
}
}
//随机产生图片下标注内容
private String getRandomName(String name) {
Random random = new Random();
int length = random.nextInt(20) + 1;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++) {
sb.append(name);
}
return sb.toString();
}
}
是不是很简单,来看一下实现效果吧
瀑布流实现效果
当然也可以实现横向瀑布流和多列瀑布流只需要改变一行代码内部参数即可:
StaggeredGridLayoutManager sglm = new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL);
这行代码第一个参数控制列数(行数),如果横向瀑布流只需要将第二个参数改为
HORIZONTAL
即可。是不是很简单
四、RecycleView的点击事件
设计好了列表不能点击也是废物,所以嘛,老老实实实现RecycleView的点击事件吧,但是RecycleView并没有像ListView的一样的setOnItemClickListener点击事件,只能在adapter内部对每一项进行逐一设置点击事件,下面我们开始吧
package com.example.hxd.gittest;
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;
public classWangZheAdapter extends RecyclerView.Adapter<WangZheAdapter.ViewHolder> {
private List<WangZhe> wangZheList ;
public WangZheAdapter(List<WangZhe> wangZhes) {
wangZheList = wangZhes;
}
public class ViewHolder extends RecyclerView.ViewHolder {
ImageView ivWZ;
TextView tvWZ;
View view;
public ViewHolder(View itemView) {
super(itemView);
view=itemView;
ivWZ = itemView.findViewById(R.id.iv_name);
tvWZ = itemView.findViewById(R.id.tv_img);
}
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false);
ViewHolder viewHolder = new ViewHolder(view);
viewHolder.tvWZ.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int position = viewHolder.getAdapterPosition();
WangZhe wangZhe= wangZheList .get(position);
Toast.makeText(parent.getContext(), wangZhe.getName(), Toast.LENGTH_LONG).show();
}
});
viewHolder.ivWZ.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int position = viewHolder.getAdapterPosition();
WangZhe wangZhe= wangZheList .get(position);
Toast.makeText(parent.getContext(), wangZhe.getName(), Toast.LENGTH_LONG).show();
}
});
return viewHolder;
}
@Override
public void onBindViewHolder(WangZheAdaoter.ViewHolder holder, int position) {
wangZhefruit = wangZhList.get(position);
holder.ivWZ.setImageResource(wangZhe.getImageId());
holder.tvWZ.setText(wangZhe.getName());
}
@Override
public int getItemCount() {
return wangZheList.size();
}
}