使用LayoutManager來確定每一個(gè)item的排列方式舞丛。
為增加和刪除項(xiàng)目提供默認(rèn)的動(dòng)畫效果扩所。
你也可以定義你自己的LayoutManager和添加刪除動(dòng)畫菊值,RecyclerView項(xiàng)目結(jié)構(gòu)如下:
Adapter:使用RecyclerView之前抄淑,你需要一個(gè)繼承自RecyclerView.Adapter的適配器,作用是將數(shù)據(jù)與每一個(gè)item的界面進(jìn)行綁定馋记。
LayoutManager:用來確定每一個(gè)item如何進(jìn)行排列擺放号坡,何時(shí)展示和隱藏√菪眩回收或重用一個(gè)View的時(shí)候宽堆,LayoutManager會(huì)向適配器請(qǐng)求新的數(shù)據(jù)來替換舊的數(shù)據(jù),這種機(jī)制避免了創(chuàng)建過多的View和頻繁的調(diào)用findViewById方法(與ListView原理類似)茸习。
目前SDK中提供了三種自帶的LayoutManager:
LinearLayoutManager
GridLayoutManager
StaggeredGridLayoutManager
RecyclerView 最重要的是實(shí)現(xiàn)Adapter畜隶,adapter中必須實(shí)現(xiàn)的三個(gè)方法:
①onCreateViewHolder()
這個(gè)方法主要生成為每個(gè)Item inflater出一個(gè)View,但是該方法返回的是一個(gè)ViewHolder号胚。該方法把View直接封裝在ViewHolder中籽慢,然后我們面向的是ViewHolder這個(gè)實(shí)例,當(dāng)然這個(gè)ViewHolder需要我們自己去編寫猫胁。直接省去了當(dāng)初的convertView.setTag(holder)和convertView.getTag()這些繁瑣的步驟箱亿。
②onBindViewHolder()
這個(gè)方法主要用于適配渲染數(shù)據(jù)到View中。方法提供給你了一個(gè)viewHolder弃秆,而不是原來的convertView届惋。
③getItemCount()
這個(gè)方法就類似于BaseAdapter的getCount方法了,即總共有多少個(gè)條目菠赚。
———————————————————————————————
簡(jiǎn)單的RecyclerView使用方法
1盼樟、添加依賴
compile 'com.android.support:recyclerview-v7:24.2.1'
2、使用RecyclerView
<android.support.v7.widget.RecyclerView
android:id="@+id/rv"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
3锈至、創(chuàng)建適配器Adapter
private class MyAdapter extends RecyclerView.Adapter<MyHolder>{
private final List<String> list;
public MyAdapter(){
list = new ArrayList<String>();
for (int i = 0; i < 30; i++) {
list.add("商品記錄" + i)}
}
//OnCreateViewHolder用來給rv創(chuàng)建緩存的
public MyHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//參數(shù)3:判斷條件 true 1.是打氣 2.添加到parent
View view = LayoutInflater.from(getContext()).inflate(R.layout.main_recyclerview_item,parent,false);
MyHolder holder = new MyHolder(view);
return holder;
}
//給緩存控件設(shè)置數(shù)據(jù)
public void onBindViewHolder(MyHolder holder, int position) {
String item = list.get(position);
holder.textView.setText(item);
holder.icon.setImageResource(R.drawable.ic_default);
}
//獲取記錄數(shù)
public int getItemCount() {
return list.size();
}
4、創(chuàng)建HolderView
public class MyHolder extends RecyclerView.ViewHolder {
public ImageView icon;
public TextView textView;
//實(shí)現(xiàn)的方法
public MyHolder(View itemView) {
super(itemView);
icon= (ImageView) itemView.findViewById(R.id.item_iv_icon);
textView= (TextView) itemView.findViewById(R.id.item_tv_title);
}
}
5译秦、設(shè)置adpater和LayoutManager給Recycleview
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(linearLayoutManager);
initData();
MyHomeAdapter adapter = new MyHomeAdapter(list);
recyclerView.setAdapter(adapter);
private List<String> list = new ArrayList <String>();
// 初始化數(shù)據(jù)
public void initData(){
for (int i = 0; i < 30 ; i++) {
list.add("數(shù)據(jù)"+i);
}
}
- 封裝RecyclerView通用適配器
好處:1.數(shù)量動(dòng)態(tài) 2.類型不限 Map<Integer峡捡,View>
作用:封裝了Adapter編寫的冗余代碼击碗,提供簡(jiǎn)潔的基類
①封裝了BaseHolder
//抽取BaseHolder繼承RecyclerView.ViewHolder
public class BaseHolder extends RecyclerView.ViewHolder {
//不寫死控件變量,而采用Map方式
private HashMap<Integer, View> mViews = new HashMap<>();
public BaseHolder(View itemView) {
super(itemView);
}
/**
*獲取控件的方法
*/
public<T> T getView(Integer viewId){
//根據(jù)保存變量的類型 強(qiáng)轉(zhuǎn)為該類型
View view = mViews.get(viewId);
if(view==null){
view= itemView.findViewById(viewId);
//緩存
mViews.put(viewId,view);
}
return (T)view;
}
/**
*傳入文本控件id和設(shè)置的文本值们拙,設(shè)置文本
*/
public BaseHolder setText(Integer viewId, String value){
TextView textView = getView(viewId);
if (textView != null) {
textView.setText(value);
}
return this;
}
/**
* 傳入圖片控件id和資源id稍途,設(shè)置圖片
*/
public BaseHolder setImageResource(Integer viewId, Integer resId) {
ImageView imageView = getView(viewId);
if (imageView != null) {
imageView.setImageResource(resId);
}
return this;
}
//...還可以擴(kuò)展出各種控件。
//Fluent API 鏈?zhǔn)絘pi obj.setxxx().setyyy()....
}
②Holder封裝好之后砚婆,再封裝BaseAdapter
封裝的時(shí)候械拍,部分參數(shù)可以選擇由外部的構(gòu)造函數(shù)或者set方法
public class BaseAdapter<T> extends RecyclerView.Adapter<BaseHolder> {
private List<T> mList = new ArrayList<>();
private int layoutId;
public BaseAdapter(int layoutId,List<T> list){
this.layoutId=layoutId;
this. mList=list;
}
//onCreateViewHolder用來給rv創(chuàng)建緩存
@Override
public BaseHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//參數(shù)3 判斷條件 true 1.打氣 2.添加到paraent
// false 1.打氣 (參考parent的寬度)
View view = LayoutInflater.from(parent.getContext()).inflate(layoutId, parent, false);
BaseHolder holder = new BaseHolder(view);
return holder;
}
//onBindViewHolder給緩存控件設(shè)置數(shù)據(jù)
@Override
public void onBindViewHolder(BaseHolder holder, int position) {
T item = mList.get(position);
convert(holder,item);
}
protected void convert(BaseHolder holder, T item) {
//什么都沒有做
}
//獲取記錄數(shù)據(jù)
@Override
public int getItemCount() {
return mList.size();
}
}
③封裝之后,繼承實(shí)現(xiàn)
**
*1.extends 把父類的代碼繼承過來装盯。 可以少寫很多代碼坷虑。
*2.因?yàn)槭侨磕脕淼拇a,所以不是所有的代碼都適合當(dāng)前埂奈。對(duì)于不適合當(dāng)前的代碼(方法)
* 我們可選擇@Override 覆蓋|重寫
*/
public class MyHomeAdapter extends BaseAdapter<String> {
public MyHomeAdapter(List<String> list) {
super(R.layout.main_recyclerview_item, list);
}
@Override
protected void convert(BaseHolder holder, String item) {
holder.setText(R.id.item_tv_title,item).setImageResource(R.id.image,R.drawable.ic_ default);
}
}
④封裝之后迄损,代碼實(shí)現(xiàn)
public class MainActivity extends AppCompatActivity {
private List<String> list = new ArrayList <String>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RecyclerView recyclerView = (RecyclerView)findViewById(R.id.recycle_view);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(linearLayoutManager);
initData();
MyHomeAdapter adapter = new MyHomeAdapter(list);
recyclerView.setAdapter(adapter);
}
// 初始化數(shù)據(jù)
public void initData(){
for (int i = 0; i < 30 ; i++) {
list.add("數(shù)據(jù)"+i);
}
}
}