成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

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

2023-06-28 08:05:46

場景vue3自定義

2015-02-12 15:33:43

微信SDK

2010-02-07 14:02:16

Android 界面

2023-06-27 15:02:47

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源碼自定義控件

2018-09-28 05:18:41

2014-12-17 09:46:30

AndroidListView最佳實踐
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 一级欧美视频 | 一区二区三区高清不卡 | 久久久国产视频 | 精品久久久一区 | 国产精品视频一二三区 | 色伊人网| 中文字幕在线电影观看 | 嫩呦国产一区二区三区av | 欧美福利视频一区 | 日韩欧美一区二区三区免费观看 | 成人免费观看男女羞羞视频 | 欧美成人在线影院 | 好好的日在线视频 | 久久免费精品 | 国产欧美日韩一区二区三区在线观看 | 国产精品伦一区二区三级视频 | 亚洲国产精品久久久久婷婷老年 | 日韩在线免费视频 | 亚洲精品日韩精品 | 麻豆久久久9性大片 | 欧美色a v | 91免费在线播放 | 黄网站在线播放 | 免费成人高清在线视频 | 亚洲国产成人久久综合一区,久久久国产99 | 欧美日韩在线一区二区 | 久久国产一区二区三区 | 在线播放国产视频 | 亚洲欧美在线一区 | 国产精品成人69xxx免费视频 | 特级丰满少妇一级aaaa爱毛片 | 99视频在线免费观看 | 99久久婷婷国产综合精品电影 | 欧美13videosex性极品 | 国产电影一区二区在线观看 | 日韩精品一区二区三区视频播放 | 日韩成人在线播放 | 国产精品大全 | 综合久久一区 | 午夜av电影| 99热在线播放 |