国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

Android自定義BaseAdapter最佳實踐

移動開發 Android
本文主要介紹如何將BaseAdapter的使用封裝為跟RecyclerView的Adapter使用方式一致。

雖然現在很多新的項目都在使用RecyclerView,但是很多開發者在一些場景中還是傾向使用ListView或者GridView,然后就是需要寫許多的Adapter。一次項目組在新啟動一個新項目的時候,有個同事拿來了一個網上說的***Adapter,在使用的時候發現即使在單個視圖類型一旦邏輯判斷比較復雜情況下非常不方便,更不用說在適配器Adapter中使用多視圖類型了,這里僅是個人觀點,也許沒有掌握到精華,這是有關***適配器Adapter的一片博文 Android 快速開發系列 打造***的ListView GridView 適配器 。

當然了隨著RecyclerView的使用,網上也有很多有關對RecyclerView多視圖類型Adapter封裝的博客,MultiType 3.0是一個大神寫的比較全面的Adapter,這篇博客Android 復雜的多類型列表視圖新寫法:MultiType 3.0有詳細的用法。***適配器Adapter自己使用不是很方便,于是就參看RecyclerView中Adapter的實現方式進行對BaseAdapter進行了簡單的封裝,封裝的目一是為了少寫代碼,另外一個就是讓邏輯看上去更清晰一些。我們知道在RecyclerView的Adapter實現中它將視圖創建與數據綁定進行了分離,同時將對View的查找創建也剝離開來了,本文就主要介紹如何將BaseAdapter的使用封裝為跟RecyclerView的Adapter使用方式一致。由于很多時候在Adapter中我們都是使用的簡單的視圖類型,即單類型視圖,因此本文將單視圖類型的Adapter單獨封裝了一下,比使用多視圖類型的Adapter使用了更嚴格的數據類型檢查,同時在使用上也方便了許多。

Android自定義BaseAdapter***實踐

Android自定義BaseAdapter***實踐

RecyclerView中Adapter的使用

在使用RecyclerView的Adapter的時候我們首先需要繼承RecyclerView的一個靜態內部類Adapter,然后重寫三個方法,實際上下面三個方法是必須要重寫的,因為都是抽象方法。

  • getItemCount()
  • onBindViewHolder(VH holder, int position)
  • onCreateViewHolder(ViewGroup parent, int viewType)

一般情況下重寫上面三個方法就可以,但是如果存在多視圖類型,在第三個方法

onCreateViewHolder()方法中我們也可以看到有一個參數是viewType,該參數作用就是針對不同的viewType需要創建不同的ViewHolder,因此還需要重寫一個方法getItemViewType(int position),針對多視圖類型同BaseAdapter實現方式倒是很像,在BaseAdapter中這是需要除此之外還要重寫一個方法getViewTypeCount(),但是在RecyclerView的Adapter中不需要該方法。

簡單類型Adapter

 

  1. private class MyAdapter extends RecyclerView.Adapter<MyViewHolder> { 
  2.  
  3.     @Override 
  4.     public int getItemCount() { 
  5.         return COUNT
  6.     } 
  7.  
  8.     @Override 
  9.     public void onBindViewHolder(MyViewHolder holder, int position) { 
  10.         holder.textView.setText("TEXT_" + position); 
  11.     } 
  12.  
  13.     @Override 
  14.     public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
  15.         View view = LayoutInflater.from(getApplicationContext()).inflate(R.layout.item_text, parent, false); 
  16.         MyViewHolder holder = new MyViewHolder(view); 
  17.         return holder; 
  18.     } 
  19.  
  20.  
  21. private static class MyViewHolder extends RecyclerView.ViewHolder { 
  22.     private TextView textView; 
  23.  
  24.     public MyViewHolder(View itemView) { 
  25.         super(itemView); 
  26.         textView = (TextView) itemView.findViewById(R.id.textView); 
  27.     } 

復雜類型Adapter

 

  1. private class MyAdapter extends RecyclerView.Adapter<ViewHolder> { 
  2.  
  3.     @Override 
  4.     public int getItemCount() { 
  5.         return COUNT
  6.     } 
  7.  
  8.     @Override 
  9.     public int getItemViewType(int position) { 
  10.         return position % 2 == 0 ? TYPE_IMAGE : TYPE_TEXT; 
  11.     } 
  12.  
  13.     @Override 
  14.     public void onBindViewHolder(ViewHolder holder, int position) { 
  15.         int type = getItemViewType(position); 
  16.         switch (type) { 
  17.         case TYPE_TEXT: 
  18.             ((MyTextHolder) holder).textView.setText("TEXT_" + position); 
  19.             break; 
  20.         case TYPE_IMAGE: 
  21.             ((MyImageHolder) holder).imageView.setImageResource(R.drawable.image); 
  22.             break; 
  23.         } 
  24.     } 
  25.  
  26.     @Override 
  27.     public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
  28.         View view
  29.         ViewHolder holder = null
  30.         switch (viewType) { 
  31.         case TYPE_TEXT: 
  32.             view = LayoutInflater.from(getApplicationContext()).inflate(R.layout.item_text, parent, false); 
  33.             holder = new MyTextHolder(view); 
  34.             break; 
  35.         case TYPE_IMAGE: 
  36.             view = LayoutInflater.from(getApplicationContext()).inflate(R.layout.item_image, parent, false); 
  37.             holder = new MyImageHolder(view); 
  38.             break; 
  39.         } 
  40.         return holder; 
  41.     } 
  42.  
  43. private class MyTextHolder extends RecyclerView.ViewHolder { 
  44.     private TextView textView; 
  45.  
  46.     public MyTextHolder(View itemView) { 
  47.         super(itemView); 
  48.         textView = (TextView) itemView.findViewById(R.id.textView); 
  49.     } 
  50.  
  51. private class MyImageHolder extends ViewHolder { 
  52.     private ImageView imageView; 
  53.  
  54.     public MyImageHolder(View itemView) { 
  55.         super(itemView); 
  56.         imageView = (ImageView) itemView.findViewById(R.id.imageView); 
  57.     } 

自定義BaseAdapter

在自定義基類之前,先簡單分析一下,我們需要自定義一個支持單種視圖的Adapter,還要自定義一個支持多種視圖類型的Adapter,兩個類都要繼承BaseAdapter,先將兩個類都公用的部分抽取出來定義為MyAdapter。

 

  1. public abstract class MyAdapter<T> extends BaseAdapter { 
  2.  
  3.     protected List<T> dataList = new ArrayList<>(); 
  4.     protected Context context; 
  5.     protected LayoutInflater inflater; 
  6.  
  7.     public MyAdapter(Context context) { 
  8.         this.context = context; 
  9.         inflater = LayoutInflater.from(context); 
  10.     } 
  11.  
  12.     public void setDataList(List<T> dataList) { 
  13.         this.dataList = dataList; 
  14.         notifyDataSetChanged(); 
  15.     } 
  16.  
  17.     @Override 
  18.     public int getCount() { 
  19.         if (null == dataList) { 
  20.             return 0; 
  21.         } 
  22.         return dataList.size(); 
  23.     } 
  24.  
  25.     @Override 
  26.     public T getItem(int position) { 
  27.         return dataList.get(position); 
  28.     } 
  29.  
  30.     @Override 
  31.     public long getItemId(int position) { 
  32.         return position; 
  33.     } 
  34.  

在RecyclerView的Adapter實現中是沒有getView()方法的,下面我們就分析一下getView()方法如何拆分,一般情況下我們在實現getView()方法都是如下流程。

 

  1. public View getView(int position, View convertView, ViewGroup parent) { 
  2.     ViewHolder holder = null
  3.     if (null == convertView) { 
  4.         //填充布局 
  5.         convertView=inflater.inflate(R.layout.item_layout, parent,false); 
  6.         holder = new ViewHolder(); 
  7.         //通過ID查詢控件 
  8.         holder.textView=(TextView)convertView.findViewById(R.id.textView); 
  9.         holder.imageView=(ImageView)convertView.findViewById(R.id.imageView); 
  10.         convertView .setTag(holder); 
  11.     } else { 
  12.         holder = (ViewHolder) convertView.getTag(); 
  13.     } 
  14.     //賦值邏輯 
  15.     return convertView; 
  16. //一個空的ViewHolder 
  17. public static class ViewHolder{ 
  18.     TextView textView; 
  19.     ImageView imageView; 

Java編程比較流行的一種編程方式不是說面向接口編程嗎,在Android開發中也有一個開發方式叫做面向Holder的編程,上面代碼是傳統的實現ViewHolder的方式,說句實現話就沒做什么事,就是作為一個載體承載著我們需要的控件。我們讓ViewHolder多做一些事情,讓它在convertView==null情況下需要做的多數邏輯都放到ViewHolder中去。

 

  1. public class ViewHolder { 
  2.     private final View itemView; 
  3.  
  4.     public ViewHolder(View itemView) { 
  5.         if (null == itemView) { 
  6.             throw new IllegalArgumentException("itemView must not be null"); 
  7.         } else { 
  8.             this.itemView = itemView; 
  9.             itemView.setTag(this); 
  10.         } 
  11.     } 
  12.  
  13.     public View getItemView() { 
  14.         return itemView; 
  15.     } 

在ViewHolder中的itemView就是getView()方法中的convertView,這里剛好是條目的根View,類似RecyclerView中ViewHolder構造方法中itemView。由于不同的視圖需要創建不同的ViewHolder,因此我們可以將創建ViewHolder的方法設置為抽象的方法暴露出去,另外賦值的時候我們也需要根據具體的業務進行賦值,同樣設置一個抽象方法。

 

  1. public abstract class SimpleAdapter<T,VH extends ViewHolder> extends MyAdapter<T> { 
  2.  
  3.     public SimpleAdapter(Context context) { 
  4.         super(context); 
  5.     } 
  6.  
  7.     public View getView(int position, View convertView, ViewGroup parent) { 
  8.         VH holder = null
  9.         if (null == convertView) { 
  10.             holder = onCreateViewHolder(parent); 
  11.             convertView = holder.getItemView(); 
  12.         } else { 
  13.             holder = (VH) convertView.getTag(); 
  14.         } 
  15.         onBindViewHolder(holder, position); 
  16.         return convertView; 
  17.     } 
  18.  
  19.     public abstract void onBindViewHolder(VH holder, int position); 
  20.  
  21.     public abstract VH onCreateViewHolder(ViewGroup parent); 
  22.  

在設置多視圖類型的Adapter的時候只需要在創建ViewHolder的時候多傳入一個viewType的參數即可。

 

  1. public abstract class MultiAdapter<T> extends MyAdapter<T> { 
  2.  
  3.     public MultiAdapter(Context context) { 
  4.         super(context); 
  5.     } 
  6.  
  7.     @Override 
  8.     public View getView(int position, View convertView, ViewGroup parent) { 
  9.         ViewHolder holder = null
  10.         if (null == convertView) { 
  11.             holder = onCreateViewHolder(parent, getItemViewType(position)); 
  12.             convertView = holder.getItemView(); 
  13.         } else { 
  14.             holder = (ViewHolder) convertView.getTag(); 
  15.         } 
  16.         onBindViewHolder(holder, position); 
  17.         return convertView; 
  18.     } 
  19.  
  20.     public abstract void onBindViewHolder(ViewHolder holder, int position); 
  21.  
  22.     public abstract ViewHolder onCreateViewHolder(ViewGroup parent, int viewType); 
  23.  

自定義BaseAdapter的使用

單視圖類型SimpleAdapter使用

 

  1. public class TextAdapter extends SimpleAdapter<String, TextAdapter.TextHolder> { 
  2.  
  3.     public TextAdapter(Context context) { 
  4.         super(context); 
  5.     } 
  6.  
  7.     @Override 
  8.     public void onBindViewHolder(TextHolder holder, int position) { 
  9.         holder.textView.setText(getItem(position)); 
  10.     } 
  11.  
  12.     @Override 
  13.     public TextHolder onCreateViewHolder(ViewGroup parent) { 
  14.         View convertView=inflater.inflate(R.layout.item_text, parent, false); 
  15.         return new TextHolder(convertView); 
  16.     } 
  17.  
  18.     static class TextHolder extends ViewHolder{ 
  19.  
  20.         public TextView textView; 
  21.  
  22.         public TextHolder(View itemView) { 
  23.             super(itemView); 
  24.             textView=(TextView) itemView.findViewById(R.id.textView); 
  25.         } 
  26.     } 

這里我們使用了兩個泛型,一個是ViewHolder中支持的數據類型String,另外一個就是我們需要創建的ViewHolder,這樣在onCreateViewHolder方法的返回值就會自動返回我們自定義的ViewHolder,有關泛型更多的知識可以參看Java泛型使用解析,單視圖類型Adapter的使用比RecyclerView的Adapter還要方便許多。

多視圖類型的使用

 

  1. public class RichAdapter extends MultiAdapter<String> { 
  2.  
  3.     private static final int TEXT = 0; 
  4.     private static final int PIC = 1; 
  5.  
  6.     public RichAdapter(Context context) { 
  7.         super(context); 
  8.     } 
  9.  
  10.     @Override 
  11.     public int getViewTypeCount() { 
  12.         return 2; 
  13.     } 
  14.  
  15.     @Override 
  16.     public int getItemViewType(int position) { 
  17.         if (position % 3 == 0) { 
  18.             return PIC; 
  19.         } else { 
  20.             return TEXT; 
  21.         } 
  22.     } 
  23.  
  24.     @Override 
  25.     public void onBindViewHolder(ViewHolder holder, int position) { 
  26.         switch (getItemViewType(position)) { 
  27.         case TEXT: 
  28.             TextHolder textHolder=(TextHolder) holder; 
  29.             textHolder.textView.setText(getItem(position)); 
  30.             break; 
  31.         case PIC: 
  32.             ImageHolder imageHolder=(ImageHolder) holder; 
  33.             imageHolder.imageView.setImageResource(R.drawable.image); 
  34.             break; 
  35.         } 
  36.     } 
  37.  
  38.     @Override 
  39.     public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
  40.         View itemView = null
  41.         ViewHolder holder = null
  42.         switch (viewType) { 
  43.         case TEXT: 
  44.             itemView = inflater.inflate(R.layout.item_text, parent, false); 
  45.             holder = new TextHolder(itemView); 
  46.             break; 
  47.         case PIC: 
  48.             itemView = inflater.inflate(R.layout.item_image, parent, false); 
  49.             holder = new ImageHolder(itemView); 
  50.             break; 
  51.         } 
  52.         return holder; 
  53.     } 
  54.  
  55.     private static class TextHolder extends ViewHolder { 
  56.         TextView textView; 
  57.  
  58.         public TextHolder(View itemView) { 
  59.             super(itemView); 
  60.             textView = (TextView) itemView.findViewById(R.id.textView); 
  61.         } 
  62.  
  63.     } 
  64.  
  65.     private static class ImageHolder extends ViewHolder { 
  66.         ImageView imageView; 
  67.  
  68.         public ImageHolder(View itemView) { 
  69.             super(itemView); 
  70.             imageView = (ImageView) itemView.findViewById(R.id.imageView); 
  71.         } 
  72.     } 

這里的使用情況跟RecyclerView的使用幾乎是一模一樣,唯一不一樣的地方就是多寫了一個getViewTypeCount()方法,在ListView或者GridView使用BaseAdapter實現多種類型視圖的時候該方法必須要重寫。

責任編輯:未麗燕 來源: 碼農網
相關推薦

2017-05-19 10:03:31

AndroidBaseAdapter實踐

2010-08-12 09:45:33

jQuery自定義事件

2023-12-21 09:00:21

函數React 組件useEffect

2016-12-26 15:25:59

Android自定義View

2016-11-16 21:55:55

源碼分析自定義view androi

2025-01-22 11:10:34

2013-04-01 14:35:10

Android開發Android自定義x

2025-05-15 07:11:51

2016-04-12 10:07:55

AndroidViewList

2010-02-07 14:02:16

Android 界面

2015-02-12 15:33:43

微信SDK

2023-06-27 15:02:47

2023-06-28 08:05:46

場景vue3自定義

2015-02-12 15:38:26

微信SDK

2013-01-09 17:22:38

Android開發Camera

2013-05-02 14:08:18

2014-12-10 10:37:45

Android自定義布局

2015-02-11 17:49:35

Android源碼自定義控件

2011-06-23 10:49:13

Qt 自定義信號

2018-09-28 05:18:41

點贊
收藏

51CTO技術棧公眾號

久久精品久久精品亚洲人| 九九久久九九久久| 成人国产一区二区三区精品麻豆| 亚洲激情六月丁香| 日韩精品第1页| 国产欧美激情| 99国产超薄丝袜足j在线观看| 国产在线播放精品| 久久视频精品在线| 欧美视频第一| 一个人看的www久久| 日本午夜大片a在线观看| 日韩欧美在线不卡| av黄色在线观看| 日韩欧美亚洲国产一区| 李宗瑞系列合集久久| 亚洲人精品午夜| 电影天堂爱爱爱爱| 尤物视频一区二区| 午夜免费啪视频观看视频| 亚洲色大成网站www久久九九| 午夜激情在线观看视频| 久久久一区二区三区| 国产日产欧美视频| 91免费国产在线| 老头吃奶性行交视频| 久久婷婷国产综合精品青草| 人妻熟女一二三区夜夜爱| 91美女片黄在线观看| 亚洲熟女乱色一区二区三区| 久久久美女毛片| www.com黄色片| 一区二区三区在线观看欧美| 超碰在线公开免费| 激情成人中文字幕| 91sp网站在线观看入口| 91精品国产综合久久香蕉麻豆| 国产激情在线| 亚洲欧美成人网| 亚洲综合资源| 欧美主播福利视频| 欧美精品播放| 亚洲自拍的二区三区| 国产精品亚洲一区二区三区在线 | 亚洲第一区第一页| yellow在线观看网址| 亚洲欧美中文日韩v在线观看| 欧美黄色a视频| 精品自拍视频在线观看| 日韩mv欧美mv国产网站| 成人xxxxx| 日韩国产精品91| 精品少妇在线视频| 一区二区三区四区国产精品| 69av亚洲| 中文字幕一区二区三区电影| 色爱综合av| 久久66热这里只有精品| 福利一区福利二区| 无套内精的网站| 欧美日韩在线播放三区四区| 日韩福利一区| 国产欧美精品xxxx另类| 日本最新不卡在线| 国产自偷自偷免费一区 | 成人亚洲精品777777大片| 婷婷国产在线综合| 黄色羞羞视频在线观看| 欧美激情视频播放| 午夜在线播放视频欧美| 91热这里只有精品| 欧美日韩一区二区三区免费看 | 日韩一区二区免费在线观看| 国产毛片精品久久| 91免费在线视频| 国产乱人伦精品一区二区在线观看| 又黄又爽毛片免费观看| 日韩欧美一级在线播放| a级日韩大片| 欧美aaaaa喷水| 欧美国产成人在线| 国产嫩草在线视频| 91精品久久久久久| 91色在线porny| 日本在线免费| 午夜精品久久久久久久99热| 久久视频一区| 精品国产凹凸成av人网站| 51漫画成人app入口| 国产精品成人v| 国产91对白在线观看九色| 欧美色综合一区二区三区| 日韩视频免费在线观看| 99精品视频免费观看| 亚洲激情久久| 中文字幕乱码日本亚洲一区二区 | 黄色在线观看网站| 国产精品丝袜视频| 国产精品三级av| 免费萌白酱国产一区二区三区| 亚洲字幕在线观看| 久久嫩草精品久久久精品| 婷婷精品在线| 中国一级特黄毛片大片| 性欧美xxxx| 美女视频黄免费的久久| 成人亚洲一区二区三区| 蜜桃成人在线| 欧美一性一乱一交一视频| 国产午夜精品理论片a级探花| 欧美午夜在线视频| 国产精品video| 亚洲片av在线| 风间由美一区二区三区在线观看| 欧美a大片欧美片| 国产一区在线播放| 亚洲一区二区三区四区不卡| 久久综合图片| 欧美日韩一二三四| 精品自拍视频| 尤物免费看在线视频| 欧美精品在欧美一区二区| 久久久一本精品99久久精品| 91国产美女在线观看| 欧美激情视频播放| 永久555www成人免费| 精品视频在线播放免| av中文一区二区三区| 国产成人精品免费| 伊人色**天天综合婷婷| 欧美草草影院在线视频| 99久久99热这里只有精品| 一路向西2在线观看| 第一会所sis001亚洲| 国产免费又粗又猛又爽| xxx一区二区| 国产成人精品综合在线观看| 日本乱理伦在线| 精品免费二区三区三区高中清不卡| 精品久久久久久久久国产字幕| 成人羞羞网站入口免费| 一本免费视频| 国产精品香蕉av| 欧美日韩综合视频网址| 欧美亚洲在线日韩| 午夜影院免费播放| 国产精品久久久久秋霞鲁丝| 午夜久久久久久| 欧美国产免费| 1769视频在线播放免费观看| 久久亚洲高清| 亚洲国产精品99| 国产a精品视频| 国产一区精品福利| 狠狠爱免费视频| 另类色图亚洲色图| 国产精品进线69影院| 成人激情诱惑| 97人人在线| 伊人久久大香线蕉午夜av| 国产亚洲欧洲在线| 久久免费电影网| 精品视频99| 激情影院在线观看| 97在线免费视频观看| 欧美激情视频给我| 亚洲高清免费一级二级三级| 一区在线视频| 欧美成人黑人| mm131国产精品| av激情久久| 亚洲性无码av在线| 亚洲精品视频免费观看| 雨宫琴音一区二区在线| 热三久草你在线| 成人免费淫片在线费观看| 亚洲va国产va天堂va久久| 日韩欧美高清一区| 久久无码av三级| 一本精品一区二区三区| 高清在线视频不卡| 日本a级片免费| 欧洲亚洲一区二区三区四区五区| 色哟哟网站入口亚洲精品| 一区二区三区国产豹纹内裤在线| 欧美久色视频| 欧美啪啪网站| 天堂中文字幕在线| 日本道在线视频| 国产不卡视频在线| 日韩美女视频一区二区在线观看| 成人不卡免费av| 久久久久久久久久久妇女| 乱人伦视频在线| 99免费看香蕉视频| 亚洲欧洲精品在线| 国产精品视频资源| 亚洲一区二区黄| 欧美午夜xxx| 国产亚洲一区字幕|