今年用了Android Studio后才認識到RecyclerView......略菜.....編寫完成后現(xiàn)在去看又感覺不太懂了....所以今天想要總結(jié)下,讓自己以后回顧的時候可以快一點...
PS:recyclerView網(wǎng)上有很多大神的資料寫的很屌汽畴,菜如我只取了一瓢
- 先上個效果圖吧:
以上的圖標請自找恤筛。膀篮。猖凛。
- 列出下程序的目錄(黑框框中的都是,其它的請自動忽略)
如上圖所示:
MyItemClickListener : 列表行點擊事件的接口盏缤,實現(xiàn)后用于響應列表點擊事件
MyItemLongClickListener:列表行長按事件的接口砰蠢,實現(xiàn)后用于響應列表長按事件
ContentViewHolder:列表行視圖容器,對應的section_item.xml中控件都綁定在此唉铜,實現(xiàn)一個容器的顯示台舱,也就是列表的一行
FootViewHolder:列表尾視圖容器,對應的section_footer.xml中控件都綁定在此潭流,實現(xiàn)一行列表尾的顯示
HeadViewHolder:列表頭視圖容器竞惋,對應的section_header.xml中控件都綁定在此,實現(xiàn)一行列表頭的顯示
MainActivity:實現(xiàn)activity_main.xml中recyclerView的綁定和顯示
-
其中:
- 每個ViewHolder對應一個xml(如ContentViewHolder對應section_item)
- 每個ViewHolder都會在MyRecycViewAdapter中初始化灰嫉,并實現(xiàn)控件的賦值
- 生成列表只需要以下幾步:
- 1拆宛、在activity_main.xml中創(chuàng)建一個RecyclerView的控件,并在MainAcitivity中綁定
- 2讼撒、創(chuàng)建一個MyRecyclerVIewAdapter的對象浑厚,并且把你需要顯示的數(shù)據(jù)傳遞給它
- 3股耽、使用RecyclerView.setAdapter(MyRecyclerVIewAdapter對象)實現(xiàn)列表的顯示
- 4、若需要更新钳幅,使用MyRecyclerVIewAdapter對象.notifyDataSetChanged()
下面就附上代碼
MyItemClickListener 列表行點擊事件接口
public interface MyItemClickListener {
public void MyItemClick(View view, int position);
}
MyItemLongClickListener 列表行長按事件接口
public interface MyItemLongClickListener {
public void MyItemLongClick(View view, int position);物蝙、
}
ContentViewHolder 繼承自RecyclerView.ViewHolder,section_item.xml中的控件都綁定于此敢艰,我們可以通過ContentViewHolder對象來獲取其中的控件诬乞,進而賦值(如:ContentViewHolder對象.tv.setText( "xxxx");)
public class ContentViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
//xml中的控件盖矫,由于要在會在MyRecyclerViewAdapter中調(diào)用丽惭,所以不能為私有
TextView tv;
View cutLine;
ImageView icon;
//點擊事件和長按事件
private MyItemClickListener mItemClickListener;
private MyItemLongClickListener mItemLongClickListener;
//這個是ContentViewHolder的構造函數(shù),會在MyRecyclerViewAdapter中調(diào)用辈双,生成ContentViewHolder一個對象
public ContentViewHolder(View itemView,MyItemClickListener mItemClickListener,MyItemLongClickListener mItemLongClickListener) {
super(itemView);
tv = (TextView)itemView.findViewById(R.id.tv);
cutLine = (View)itemView.findViewById(R.id.cutLine);
icon = (ImageView)itemView.findViewById(R.id.icon);
this.mItemClickListener = mItemClickListener;
this.mItemLongClickListener = mItemLongClickListener;
itemView.setOnClickListener(this);
itemView.setOnLongClickListener(this);
}
//短按
@Override
public void onClick(View v) {
if(mItemClickListener != null){
mItemClickListener.MyItemClick(v,getPosition()); //若不為空則調(diào)用MyItemClickListener的MyItemClick方法
}
}
//長按
@Override
public boolean onLongClick(View v) {
if(mItemLongClickListener != null){
mItemLongClickListener.MyItemLongClick(v,getPosition()); //若不為空則調(diào)用MyItemLongClickListener的MyItemLongClick方法
}
return true;
}
}
section_item.xml 包涵一個圖標责掏,文字和一條分割線
<?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:orientation="vertical">
<RelativeLayout
android:id="@+id/column"
android:layout_width="match_parent"
android:layout_height="50dp">
<ImageView
android:id="@+id/icon"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginLeft="5dp"
android:layout_marginTop="5dp"
/>
<TextView
android:id="@+id/tv"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_toRightOf="@+id/icon"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:text="mxy"
android:gravity="center_vertical"
/>
</RelativeLayout>
<View
android:id="@+id/cutLine"
android:layout_width="match_parent"
android:layout_height="0.3dp"
android:background="@color/black"/>
</LinearLayout>
FootViewHolder 列表尾viewholder,列表尾也可以像ContentViewHolder一樣放入很多控件湃望,我只放了一個TextView
public class FootViewHolder extends RecyclerView.ViewHolder {
TextView footer_tv;
public FootViewHolder(View itemView) {
super(itemView);
footer_tv = (TextView)itemView.findViewById(R.id.footer_tv);
}
}
section_footer.xml 列表尾xml
<?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">
<TextView
android:id="@+id/footer_tv"
android:layout_width="match_parent"
android:layout_height="20dp"
android:text="footer_tv"
android:gravity="center"
android:background="#30696969"
/>
</LinearLayout>
HeadViewHolder列表頭viewholder
public class HeadViewHolder extends RecyclerView.ViewHolder {
TextView header_tv;
public HeadViewHolder(View itemView) {
super(itemView);
header_tv = (TextView)itemView.findViewById(R.id.header_tv);
}
}
section_header.xml 列表頭xml
<?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"
>
<TextView
android:id="@+id/header_tv"
android:layout_width="match_parent"
android:layout_height="20dp"
android:text="header_tv"
android:gravity="center"
android:background="#30696969"
/>
</LinearLayout>
MyRecyclerViewAdapter 這個是核心换衬,看上去很長,但其實層次感很強证芭,主要分為以下4部分
- 1 ViewHolder的Create
- 2 ViewHolder的賦值
- 3 列表的行數(shù)
- 4 其他部分
- 4.1 因為我有三個ViewHolder分別表示content瞳浦,head,foot所以我需要在getItemViewType中判斷
- 4.2 因為我有點擊事件废士,所以需要點擊方法
public class MyRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final int TYPE_HEADER = 0; //表格頭
private static final int TYPE_CONTENT = 1; //表格內(nèi)容
private static final int TYPE_FOOTER = 2; //表格尾
private LayoutInflater inflater;
private List<String> slist; //標識叫潦,標識是頭還是尾,還是內(nèi)容
private List<contentData> cList; //頭或尾或內(nèi)容的數(shù)據(jù)
MyItemClickListener mItemClickListener;
MyItemLongClickListener mItemLongClickListener;
public MyRecyclerViewAdapter(Context context,List<allData> list){
this.slist = list.get(0).getSlist();
this.cList =list.get(0).getMlist();
inflater=LayoutInflater. from(context);
}
/************************************此處區(qū)分viewholder類型***************************************/
//這里判斷viewType類型官硝,到底是header還是footer還是content
@Override
public int getItemViewType(int postion){
if(slist.get(postion).equals("head")){return TYPE_HEADER;}
else if (slist.get(postion).equals("foot")){return TYPE_FOOTER;}
else{return TYPE_CONTENT;}
// if(postion == 0){return TYPE_HEADER;} //header
// else if(postion == getItemCount()-1){return TYPE_FOOTER;} //footer
// else{return TYPE_CONTENT;} //content
}
/************************************點擊事件的方法***************************************/
//表格行點擊方法
public void setOnItemClickListener(MyItemClickListener listener){
this.mItemClickListener = listener;
}
//表格行長按方法
public void setOnItemLongClickListener(MyItemLongClickListener listener){
//listener為MainAcitivity傳遞進來的listener
this.mItemLongClickListener = listener;
}
/************************************create部分***************************************/
//此函數(shù)中根據(jù)xml生成View對象矗蕊,并傳遞進入對應的ViewHolder構造函數(shù),生成對應的Viewholder對象氢架,并返回
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if(viewType == TYPE_CONTENT){ //表格內(nèi)容
View view = inflater.inflate(R.layout.section_item,parent, false); //根據(jù)xml生成View對象
ContentViewHolder viewholder = new ContentViewHolder(view,mItemClickListener,mItemLongClickListener);
return viewholder;
}else if(viewType == TYPE_HEADER){//表格頭
View view = inflater.inflate(R.layout.section_header,parent, false);
HeadViewHolder headholder = new HeadViewHolder(view);
return headholder;
}else{//表格尾
View view = inflater.inflate(R.layout.section_footer,parent, false);
FootViewHolder footholder = new FootViewHolder(view);
return footholder;
}
}
/************************************為ViewHolder中的控件賦值部分***************************************/
//此函數(shù)中holder即為onCreateViewHolder返回的的holder傻咖,根據(jù)這些holder獲取對應的控件,進行賦值
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if(holder instanceof ContentViewHolder){ // content 表格內(nèi)容
ContentViewHolder contentholder = (ContentViewHolder) holder;
contentholder.tv.setText(cList.get(position).getDescrib());
contentholder.icon.setImageResource(cList.get(position).getIconID());
}else if(holder instanceof HeadViewHolder){ //header 表格頭
HeadViewHolder headholder = (HeadViewHolder) holder;
headholder.header_tv.setText(cList.get(position).getDescrib());
}else{ //footer 表格尾
FootViewHolder footholder = (FootViewHolder) holder;
footholder.footer_tv.setText(cList.get(position).getDescrib());
}
}
/************************************列表行數(shù)***************************************/
//此處返回表格的行數(shù)岖研,也就是數(shù)據(jù)的size
@Override
public int getItemCount() {
return slist.size();
}
}
MainAcitvity主要分為數(shù)據(jù)的生成卿操,和設置recyclerView的適配
public class MainActivity extends AppCompatActivity implements MyItemClickListener, MyItemLongClickListener {
private RecyclerView recyclerView;
private MyRecyclerViewAdapter recycleAdapter;
private List<String> slist =new ArrayList<String>();
private List<contentData> clist = new ArrayList<contentData>();
private List<allData> mylist = new ArrayList<allData>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initData();
recyclerView = (RecyclerView)this.findViewById(R.id.recyclerView);
recycleAdapter = new MyRecyclerViewAdapter(this,mylist);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
//設置為垂直布局,這也是默認的
layoutManager.setOrientation(OrientationHelper.VERTICAL);
//設置布局管理器
recyclerView.setLayoutManager(layoutManager);
//設置Adapter
recyclerView.setAdapter(recycleAdapter);
//設置增加或刪除條目的動畫
recyclerView.setItemAnimator(new DefaultItemAnimator());
//分割線
// recyclerView.addItemDecoration(new RecyclerDivideLine(Main.this,LinearLayoutManager.VERTICAL));
// recycleAdapter.setOnItemClickListener(this);
// recycleAdapter.setOnItemLongClickListener(this);
recycleAdapter.setOnItemClickListener(this);
recycleAdapter.setOnItemLongClickListener(this);
}
//數(shù)據(jù)初始化孙援,其中在slist中add的是標識符害淤,head就說明這行是表格頭,body說明這行是表格內(nèi)容拓售,
//而clist中add的有兩個一個是圖片的ID窥摄,一個是文字的說明,而head和foot沒有圖片ID
private void initData(){
clist.add(new contentData(1,"this is head1"));slist.add("head");
clist.add(new contentData(R.drawable.ins,"儀表說明"));slist.add("body");
clist.add(new contentData(R.drawable.handle,"操作說明"));slist.add("body");
clist.add(new contentData(1,"this is head2"));slist.add("head");
clist.add(new contentData(R.drawable.vision,"版本說明"));slist.add("body");
clist.add(new contentData(R.drawable.err,"報錯指南"));slist.add("body");
// clist.add(new contentData(5,"footer1"));slist.add("foot");
clist.add(new contentData(1,"this is head3"));slist.add("head");
clist.add(new contentData(R.drawable.buy,"業(yè)務咨詢"));slist.add("body");
clist.add(new contentData(R.drawable.fix,"售后返修"));slist.add("body");
clist.add(new contentData(1,"this is head4"));slist.add("head");
clist.add(new contentData(R.drawable.sms,"短信發(fā)送"));slist.add("body");
clist.add(new contentData(5,"this is foot1"));slist.add("foot");
mylist.add(new allData(clist,slist));
}
//列表行的點擊在此響應
@Override
public void MyItemClick(View view, int position) {
Toast.makeText(this, ""+position, Toast.LENGTH_SHORT).show();
}
//列表行的長按在此響應
@Override
public void MyItemLongClick(View view, int position) {
Toast.makeText(this, ""+position, Toast.LENGTH_SHORT).show();
}
}
acitivity_main.xml
<?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"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.myapplication.MainActivity">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true">
</android.support.v7.widget.RecyclerView>
</RelativeLayout>
contentData包括兩個參數(shù)邻辉,一個是icon也就是圖標的ID溪王,一個是describe也就是文字說明
public class contentData {
public int getIconID() {
return iconID;
}
public void setIconID(int iconID) {
this.iconID = iconID;
}
private int iconID;
public String getDescrib() {
return describ;
}
public void setDescrib(String describ) {
this.describ = describ;
}
private String describ;
public contentData(int iconID,String describ){
this.iconID = iconID;
this.describ =describ;
}
}
allData 其中mlist為內(nèi)容數(shù)據(jù)模型,slist為描述數(shù)據(jù)模型
public class allData {
private List<contentData> mlist;
private List<String> slist;
public allData(List<contentData> mlist,List<String> slist){
this.mlist = mlist;
this.slist = slist;
}
public List<String> getSlist() {
return slist;
}
public void setSlist(List<String> slist) {
this.slist = slist;
}
public List<contentData> getMlist() {
return mlist;
}
public void setMlist(List<contentData> mlist) {
this.mlist = mlist;
}
}