国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > Android > 正文

Android之自定義實現(xiàn)BaseAdapter(通用適配器一)

2019-12-12 05:36:32
字體:
供稿:網(wǎng)友

通過前面的優(yōu)化布局之后,我們接著來講如何打造一個通用的適配器,那么通用適配器能干嗎呢?很簡單,減少我們對代碼的書寫,下面開始上代碼了。

MyAdapter.java

public class MyAdapter extends BaseAdapter { private List<Student> data; public MyAdapter(List<Student> data) {  this.data = data; } @Override public int getCount() {  return data == null ? 0 : data.size(); } @Override public Object getItem(int position) {  return data.get(position); } @Override public long getItemId(int position) {  return position; } /**  *  * @param position  * @param convertView  * @param parent  * @return  */ @Override public View getView(int position, View convertView, ViewGroup parent) {  ViewHolder holder = null;  if(convertView == null){   //解析布局   convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item,null);   //創(chuàng)建ViewHolder持有類   holder = new ViewHolder();   //將每個控件的對象保存到持有類中   holder.tvName = (TextView)convertView.findViewById(R.id.mTv1);   holder.tvSex = (TextView)convertView.findViewById(R.id.mTv2);   //將每個convertView對象中設(shè)置這個持有類對象   convertView.setTag(holder);  }  //每次需要使用的時候都會拿到這個持有類  holder = (ViewHolder)convertView.getTag();  //然后可以直接使用這個類中的控件,對控件進行操作,而不用重復(fù)去findViewById了  holder.tvName.setText(data.get(position).getName());  holder.tvSex.setText(data.get(position).getSex());  return convertView; } /**  * 通過這個類來保存當(dāng)前所有的控件id  */ static class ViewHolder{  TextView tvName;  TextView tvSex; }}

在上面的代碼中,我們先看看有哪些代碼的格式或形式都是重復(fù)在使用的,首先不難看出,public int getCount() 、public long getItemId(int position) 、public long getItemId(int position)這三個方法是不是每次都要實現(xiàn)呢,由此我們可以先將這些代碼提取出來,放到MyBaseAdapter中,由于我們每次的重要部分是實現(xiàn)getView方法,所以這個方法我們不需要在這里面寫,直接將MyBaseAdapter設(shè)置為抽象類就可以了,然需要實現(xiàn)getView的類來繼承他即可,因此MyAdapter可以繼承MyBaseAdapter然后實現(xiàn)getView方法即可

MyBaseAdapter.java

public abstract class MyBaseAdapter extends BaseAdapter { protected List<Student> data; public MyBaseAdapter(List<Student> data){  this.data = data; } @Override public int getCount() {  return data == null ? 0 : data.size(); } @Override public Object getItem(int position) {  return data.get(position); } @Override public long getItemId(int position) {  return position; }}

MyAdapter.java

public class MyAdapter extends MyBaseAdapter { public MyAdapter(List<Student> data) {  super(data);  this.data = data; } @Override public View getView(int position, View convertView, ViewGroup parent) {  ViewHolder holder = null;  if(convertView == null){   convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item,null);   holder = new ViewHolder();   holder.tvName = (TextView)convertView.findViewById(R.id.mTv1);   holder.tvSex = (TextView)convertView.findViewById(R.id.mTv2);   convertView.setTag(holder);  }  holder = (ViewHolder)convertView.getTag();  holder.tvName.setText(data.get(position).getName());  holder.tvSex.setText(data.get(position).getSex());  return convertView; } static class ViewHolder{  TextView tvName;  TextView tvSex; }}

這樣,每次自定義只需要繼承MyBaseAdapter就可以了,不過還是那句話,沒有最優(yōu),只有更優(yōu),所以我們還要接著優(yōu)化,接著封裝,那么我們接著從上面的getView方法中看,還有哪些代碼是我們經(jīng)常重復(fù)使用到的代碼呢?其實你會發(fā)現(xiàn)每次我們都需要操作相同的這段代碼:

ViewHolder holder = null;  if(convertView == null){   convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item,null);   holder = new ViewHolder();   holder.tvName = (TextView)convertView.findViewById(R.id.mTv1);   holder.tvSex = (TextView)convertView.findViewById(R.id.mTv2);   convertView.setTag(holder);  }  holder = (ViewHolder)convertView.getTag();  holder.tvName.setText(data.get(position).getName());  holder.tvSex.setText(data.get(position).getSex());  return convertView; }

我們可以先再次理解下這段代碼,首先我們每次都要創(chuàng)建一個holder持有者對象,設(shè)置到對應(yīng)的converView的setTag中,然后,每次要拿到hoder對象,對hoder對象中的控件進行操作,對于上面的代碼我們可以直接將他簡化為以下幾個步奏

1.ViewHolder holder = 拿到holder //每次拿到對應(yīng)的holder對象即可
2.TextView tv = holder.getView() //拿到每個控件對應(yīng)的id
3. tv.setText() //對控件進行操作
4. return view //返回view即可

下面開始寫一個通用的ViewHolder通用類,來優(yōu)化我們的實現(xiàn),代碼如下:

ViewHolder.java

public class ViewHolder { //被點擊的當(dāng)前位置 private int position; //用一個map集合來保存每個控件的id,這個SparseArray是android提供的一個比map使用效率更高的一個 //集合,但是局限是,key只能是int類型,所以當(dāng)鍵值對涉及到key是int類型時,可以優(yōu)先考慮使用這個集合 private SparseArray<View> array; //復(fù)用的布局 private View convertView; //上下文 private Context context; //解析的布局資源id private int layout; public ViewHolder(){ } //帶三個構(gòu)造的方法,這里將構(gòu)造方法私有,防止外界去創(chuàng)建,通過自身的靜態(tài)方法去創(chuàng)建對象即可 private ViewHolder(ViewGroup parent,int position,int layout){  this.position = position;  this.context = parent.getContext();  //每次創(chuàng)建對象,就將布局解析出來  convertView = LayoutInflater.from(parent.getContext()).inflate(layout,null);  //然后將對象保存到convertView對應(yīng)的setTag中,方便每次該獲取  convertView.setTag(this);  array = new SparseArray<>(); } //通過這個方法,可以創(chuàng)建ViewHolder對象 public static ViewHolder getHolder(View convertView, ViewGroup parent, int position,int layout){  //每次判斷converView是否為空,如果為空就直接返回這個創(chuàng)建的對象  if(convertView == null){   return new ViewHolder(parent,position,layout);  }else{   //不為空的情況,就跟我們上面的代碼一樣,每次通過復(fù)用的控件拿到對應(yīng)的ViewHolder對象   ViewHolder holder = (ViewHolder)convertView.getTag();   //這里一定要更新下下標(biāo)的位置,雖然對象相同,但是我們每次都要更新現(xiàn)有的位置,   holder.position = position;   //返回已經(jīng)創(chuàng)建好的holder對象   return holder;  } } /** * 這個方法是通過控件id拿到對應(yīng)的控件 */ public <T extends View> T getView(int viewId){  //每次通過viewId鍵去拿到到對應(yīng)的控件  View view = array.get(viewId);  //如果為空,表示該集合中還沒有存入該控件  if(view == null){   //先要去通過converView拿到控件id   view = convertView.findViewById(viewId);   //保存到集合中,以便下次直接獲取   array.put(viewId,view);  }  //返回View的子類控件,采用泛型的方便是不需要強制轉(zhuǎn)換了  return (T)view; } //得到converView布局 public View getConvertView(){  return convertView; }

通過上面的代碼我們就已經(jīng)封裝好了一個通用的ViewHolder類了,下面我們的MyAdapter.java則可以更加簡單的只寫一下代碼了:

public class MyAdapter extends MyBaseAdapter { public MyAdapter(List<Student> data) {  super(data); } @Override public View getView(int position, View convertView, ViewGroup parent) {  ViewHolder holder = ViewHolder.getHolder(convertView,parent,position, R.layout.list_item);  TextView tvName = holder.getView(R.id.mTv1);  TextView tvSex = holder.getView(R.id.mTv2);  tvName.setText(data.get(position).getName());  tvSex.setText(data.get(position).getSex());  return holder.getConvertView(); }}

好了,上面的代碼是不更簡單了呢,其實我們這里只是封裝了ViewHolder類哦,還有更通用的等著我們?nèi)シ庋b呢,下次我們需要封裝的就是如何把getView中的代碼再一次進行封裝,已達到更優(yōu)。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持武林網(wǎng)。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 行唐县| 林芝县| 台江县| 奉贤区| 化州市| 弥勒县| 祁东县| 龙口市| 密云县| 牙克石市| 安乡县| 凯里市| 孟州市| 诏安县| 忻州市| 建宁县| 太仆寺旗| 曲靖市| 夏邑县| 桃园市| 尉犁县| 泗阳县| 苍溪县| 运城市| 安远县| 灯塔市| 新乡县| 白玉县| 和田市| 蒙阴县| 竹山县| 寻乌县| 东丰县| 刚察县| 台安县| 成都市| 安国市| 安康市| 沙河市| 平泉县| 东平县|