中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

ListView中怎么使用泛型適配器

發布時間:2021-06-12 18:51:43 來源:億速云 閱讀:168 作者:Leah 欄目:移動開發

這篇文章給大家介紹ListView中怎么使用泛型適配器,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

1.先創建好我們今天需要的控件、源數據以及Bean類。

控件只有一個ListView

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  tools:context=".activities.MainActivity">
  <ListView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/mlv"/>
</LinearLayout>

beans方法模擬了一個假數據

private void beans() {
  list = new ArrayList<>();
  for (int i = 0; i < 16; i += 4) {
    list.add(new Student("同學" + i, "男", 15 + i, R.drawable.a, true));
    list.add(new Student("同學" + (i + 1), "男", 15 + i, R.drawable.b, false));
    list.add(new Student("同學" + (i + 2), "男", 15 + i, R.drawable.c, false));
    list.add(new Student("同學" + (i + 3), "男", 15 + i, R.drawable.d, true));
  }
}

這是bean類

package zy.pers.homework_20.bean;
public class Student {
  private String name;
  private String sex;
  private int age;
  private int imgId;
  private boolean isOver;
  public Student(String name, String sex, int age, int imgId,boolean isOver) {
    this.name = name;
    this.sex = sex;
    this.age = age;
    this.imgId = imgId;
    this.isOver = isOver;
  }
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }
  public String getSex() {
    return sex;
  }
  public void setSex(String sex) {
    this.sex = sex;
  }
  public int getAge() {
    return age;
  }
  public void setAge(int age) {
    this.age = age;
  }
  public int getImgId() {
    return imgId;
  }
  public void setImgId(int imgId) {
    this.imgId = imgId;
  }
  @Override
  public String toString() {
    return "Student{" +
        "name='" + name + '\'' +
        ", sex='" + sex + '\'' +
        ", age=" + age +
        ", imgId=" + imgId +
        '}';
  }
  public boolean isOver() {
    return isOver;
  }
  public void setOver(boolean over) {
    isOver = over;
  }
}

2.創建MyBaseAdapter繼承BaseAdapter

public class MyBaseAdapter<T> extends BaseAdapter {
  @Override
  public int getCount() {
    return 0;
  }
  @Override
  public Object getItem(int position) {
    return null;
  }
  @Override
  public long getItemId(int position) {
    return 0;
  }
  @Override
  public View getView(int position, View convertView, ViewGroup parent) {
    return null;
  }
}

3.我們說通用適配器傳入布局id和源數據,所以我們定義這兩個量接收傳入的數據。

private List<Student> list;
private int mLayRes;
public MyBaseAdapter(List<Student> list, int mLayRes) {
  this.list= list;
  this.mLayRes = mLayRes;
}

4.重寫我們的前三個方法

前三個方法應該算是比較簡單的了,

@Override
public int getCount() {
  return list != null ? list.size() : 0;
}
@Override
public T getItem(int position) {
  return list.get(position);
}
@Override
public long getItemId(int position) {
  return position;
}

第一個一個簡單的判斷,返回list的大小。第二個跟第三個和以前適配器一樣,只是getItem的返回值寫成了泛型。

5.寫Viewholder類,這個是很麻煩的,我們先創建出來Viewholder,之后的方法我們一步一步添加。

public static class ViewHolder {
  private SparseArray<View> mViews = new SparseArray<>();
  private Context mContext;
  private int position;
  private int layRes;
  private View itemView;
 private ViewHolder(Context context, ViewGroup parent, int layRes) {
  this.mContext = context;
  this.layRes= layRes;
  this.itemView = LayoutInflater.from(context).inflate(layRes, parent, false);
  this.itemView.setTag(this);
 }
 public static ViewHolder bind(int position, View convertView, ViewGroup parent, int layRes, Context context) {
  ViewHolder holder;
  if (convertView == null) {
    holder = new ViewHolder(context, parent, layRes);
  } else {
    holder = (ViewHolder) convertView.getTag();
    holder.itemView = convertView;
  }
  holder.position = position;
  return holder;
}

東西有點多,我們順著邏輯慢慢看:

1)首先是通過單例來實現,所以我們需要一個私有化構造方法,里面有三個參數,分別是上下文,ViewGroup和布局id,這三個屬性是我們必須要用到的,我們傳入上下文獲取inflater,把布局id傳進去,然后把holder傳入我們的itemView中。

這一步我們應該比較熟悉吧,我們以前是在getView中實現這一步的。

2)然后我們看下面的bind方法,他的參數有五個。其實有三個參數我們很熟悉,就是我們getView中的三個參數。在這基礎上我們又添加了兩個參數,布局id和上下文。

然后為了優化我們先判斷當前的convertView是否為空,如果為空就新建一個Viewholder,讓convertView在私有構造器中加載;如果不為空,直接通過getTag拿到。

注意我們要對holder中的兩個參數進行修改,一個是itemView,一個是position。因為我們優化過后,如果convertView不為空,他里面是有之前的數據的,其他的幾個屬性我們不用管,但是這兩個還是儲存著上一個的內容。我們需要讓他重新指向當前的convertView和position,給大家畫一張圖就很明白了:

ListView中怎么使用泛型適配器

索引什么的畫的可能不準確,但是主要就是這么個意思,大家領會精神哈。

最后返回holder。

3)我們還需要返回我們加載完成的convertView,

public View getItemView() {
  return itemView;
}

現在我們Viewholder基本框架寫完了,我們暫時不管他了,去寫getView。

6.重寫方法getView:

我們剛才說了,在adapter中寫一個抽象方法,然后通過回調方法,實現多類型適配,也就是說這個抽象方法是寫我們給具體控件添加數據的,我們在這里面傳遞兩個參數,一個是我們的Viewholder,另一個是對應位置的數據,類型為泛型。

public abstract void bindView(ViewHolder holder,T obj);

因為我們出現了抽象方法,所以我們的MyBaseAdapter需要變成抽象類,

public abstract class MyBaseAdapter<T> extends BaseAdapter {

這是我們的getView

@Override
public View getView(int position, View convertView, ViewGroup parent) {
  ViewHolder holder = ViewHolder.bind(position,convertView,parent,mLayRes,parent.getContext());
  bindView(holder,list.get(position));
  return holder.getItemView();
}

現在我們的適配器已經完成百分之九十了,還差一點,我們需要寫幾個輔助方法,為了方便我們等會進行適配。

1.獲取指定控件

public <T extends View> T getView(int id){
  T t = (T) mViews.get(id);
  if(t == null){
    t = itemView.findViewById(id);
    mViews.put(id,t);
  }
  return t;
}

在Viewholder中寫一個getView方法,通過控件id來獲取指定控件。

2.TextView控件輸入數據

public ViewHolder setText(int id,CharSequence text){
  View view = getView(id);
  if(view instanceof View){
    ((TextView)view).setText(text);
  }
  return this;
}

3.ImageView輸入圖片

public ViewHolder setImg(int id,int resId){
  View view = getView(id);
  if(view instanceof View){
    ((ImageView)view).setImageResource(resId);
  }else
    view.setBackgroundResource(resId);
  return this;
}

4.復選框輸入選定狀態

public ViewHolder setCheckable(int id,boolean checkable){
  View view = getView(id);
  if(view instanceof View){
    ((CheckBox)view).setChecked(checkable);
  }
  return this;
}

好啦,先在我們的適配器完全寫完了,我們來看一下效果吧。

private void initTools() {
  ListView mLv = (ListView) findViewById(R.id.mlv);
  adapter = new MyBaseAdapter<Student>(list,R.layout.item_one) {
    @Override
    public void bindView(ViewHolder holder, Student obj) {
      holder.setText(R.id.name,obj.getName())
          .setText(R.id.age,obj.getAge() + "")
          .setText(R.id.sex,obj.getSex())
          .setImg(R.id.head,obj.getImgId())
          .setCheckable(R.id.mc,obj.isOver());
    }
  };
  mLv.setAdapter(adapter);
}

關于ListView中怎么使用泛型適配器就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

星子县| 池州市| 巴楚县| 开江县| 广南县| 达日县| 方山县| 荥经县| 龙川县| 东明县| 沭阳县| 黑山县| 清河县| 玉田县| 山阳县| 凤山县| 临颍县| 玉环县| 隆化县| 景洪市| 淅川县| 五峰| 吐鲁番市| 河间市| 韶山市| 运城市| 瑞金市| 屯昌县| 阿拉善左旗| 敦煌市| 霍山县| 清新县| 洛浦县| 太和县| 漳州市| 赤城县| 南和县| 黑山县| 七台河市| 南乐县| 长汀县|