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();
}
}