BaseAdapter使用教程及方法詳解

BaseAdapter是最基礎(chǔ)的Adapter類,也是最實(shí)用最常用的一個類耸棒,但是相比于ArrayAdapter之類的绰更,對初學(xué)者來說卻比較難理解。所以在這里介紹一下BaseAdapter闷沥。


Adapter是什么

An Adapter object acts as a bridge between an AdapterView and the underlying data for that view. The Adapter provides access to the data items. The Adapter is also responsible for making a View for each item in the data set.
翻譯過來,簡單理解就是adapter是view和數(shù)據(jù)的橋梁咪鲜。在一個ListView或者GridView中狐赡,你不可能手動給每一個格子都新建一個view,所以這時候就需要Adapter的幫忙疟丙,它會幫你自動繪制view并且填充數(shù)據(jù)颖侄。


BaseAdapter是什么

從英文就可以知道了,最基礎(chǔ)的Adapter享郊,也就是說览祖,它可以做所有的事情。所以為什么說最實(shí)用最常用炊琉,原因就在于它的全能性展蒂,不會像ArrayAdapter等的封裝好的類有那么多局限性,但是這樣的話苔咪,使用起來自然會更加麻煩一點(diǎn)锰悼。但是這篇文章就會告訴你怎么熟練使用它。


BaseAdapter怎么用

在ListView团赏、GridView或者其他的view中箕般,使用setAdapter方法傳入我們的baseAdapter就可以用了。

listView.setAdapter(mBaseAdapter);

問題就出在這個mBaseAdapter要怎么寫了舔清。重點(diǎn)終于來了丝里。
可以新建一個java文件MyBaseAdapter,繼承自BaseAdapter体谒,并且實(shí)現(xiàn)它的4個基礎(chǔ)方法杯聚。

public class MyBaseAdapter 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;
    }
}

默認(rèn)實(shí)現(xiàn)這4個方法后,接下來我們就要重寫這4個方法了抒痒。那么具體這4個方法有什么用呢幌绍?我們在后面再講。
MyBaseAdapter這個類寫好后,我們就新建一個mBaseAdapter傀广,在setAdapter方法的時候傳進(jìn)去就好了痢虹。

MyBaseAdapter mBaseAdapter = new MyBaseAdapter();

這樣的三步法就可以實(shí)現(xiàn)BaseAdapter的使用了。
但是主儡,這當(dāng)然沒完。因?yàn)楝F(xiàn)在你還沒告訴你的BaseAdapter你要叫它干什么呢惨缆。所以接下來我們就要修改MyBaseAdapter了糜值。


BaseAdapter方法詳解

學(xué)會BaseAdapter其實(shí)只需要掌握四個方法:
getCount, getItem, getItemId, getView

  • getCount : 要綁定的條目的數(shù)目,比如格子的數(shù)量
  • getItem : 根據(jù)一個索引(位置)獲得該位置的對象
  • getItemId : 獲取條目的id
  • getView : 獲取該條目要顯示的界面

可以簡單的理解為坯墨,adapter先從getCount里確定數(shù)量寂汇,然后循環(huán)執(zhí)行g(shù)etView方法將條目一個一個繪制出來,所以必須重寫的是getCount和getView方法捣染。而getItem和getItemId是調(diào)用某些函數(shù)才會觸發(fā)的方法骄瓣,如果不需要使用可以暫時不修改。


接下來用一個簡單的demo來展示一下BaseAdapter耍攘。

首先在MyBaseAdapter中添加super()方法榕栏,用來將數(shù)據(jù)源傳入MyBaseAdapter中。其中this.data = data;的意思是將傳入的形參賦值給我們的私有變量以供使用蕾各。mContext是在后面要調(diào)用到扒磁,這里先不解釋。

private String[] data;
private Context mContext;
public MyBaseAdapter(Context mContext, String[] data) {
    super();
    this.mContext = mContext;
    this.data = data;
}

然后就可以將getCount的返回值修改為我們的數(shù)據(jù)源的長度式曲,要顯示幾個條目妨托,我們就傳入多長的數(shù)據(jù)源就可以了。

public int getCount() {
    return data.length;
}

接著將getView的方法改為顯示出我們數(shù)據(jù)源的字符串吝羞。

public View getView(int position, View convertView, ViewGroup parent) {
    TextView textView = new TextView(mContext);
    textView.setText(data[position]);
    return textView;
}

這里為每一個條目新建一個TextView用來顯示字符串兰伤,新建的時候就需要傳入一個Context,就用到了我們之前的mContext钧排。
這樣我們就可以使用MyBaseAdapter來顯示一個字符串?dāng)?shù)組了敦腔。不過還需要在前面修改一下,在新建mBaseAdapter的時候要傳入context和數(shù)據(jù)源卖氨。

String[] strings = {"a","b","c"}; 
MyBaseAdapter mBaseAdapter = new MyBaseAdapter(getApplicationContext(),strings);

接下來貼一下完整的代碼吧会烙。ListView的新建我就不講了。

  • MainActivity部分
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ListView;
public class MainActivity extends AppCompatActivity {
    private ListView listView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        listView = (ListView) findViewById(R.id.listView);
        String[] strings = {"a","b","c"};
        MyBaseAdapter mBaseAdapter = new MyBaseAdapter(getApplicationContext(),strings);
        listView.setAdapter(mBaseAdapter);
    }
}
  • MyBaseAdapter部分
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
public class MyBaseAdapter extends BaseAdapter {
      private String[] data;
      private Context mContext;
      public MyBaseAdapter(Context mContext, String[] data) {
          super();
          this.mContext = mContext;
          this.data = data;
      }
      @Override
      public int getCount() {
          return data.length;
      }
      @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) {
          TextView textView = new TextView(mContext);
          textView.setText(data[position]);
          return textView;
      }
}

BaseAdapter進(jìn)階使用

當(dāng)然一個TextView顯然滿足不了我們的需要筒捺,這也完全不能顯示BaseAdapter的全能性柏腻。那接下來,就來展示一下如何用BaseAdapter顯示一個自定義布局系吭。

  • 首先新建一個layout五嫂,我命名為item,這個就是我們每個條目要展示的布局
<?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"
      android:orientation="horizontal" android:layout_width="match_parent"
      android:layout_height="match_parent">
      <ImageView
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          app:srcCompat="@mipmap/ic_launcher"
          android:id="@+id/imageView" />
      <Button
          android:text="Button"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:id="@+id/button" />
      <TextView
          android:text="TextView"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:id="@+id/textView" />
</LinearLayout>
  • 接下來修改getView方法,讓它顯示我們這個item布局
public View getView(int position, View convertView, ViewGroup parent) {
      LayoutInflater inflater = LayoutInflater.from(mContext);
      View view = inflater.inflate(R.layout.item,null);
      final TextView textView = (TextView) view.findViewById(R.id.textView);
      Button button = (Button) view.findViewById(R.id.button);
      ImageView imageView = (ImageView) view.findViewById(R.id.imageView);
      imageView.setImageResource(R.mipmap.ic_launcher);
      button.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View v) {
              textView.append("!");
          }
      });
      textView.setText(data[position]);
      return view;
}

主要講解一下前兩句沃缘。LayoutInflater是用來加載布局的躯枢,用LayoutInflater的inflate方法就可以將你的item布局繪制出來。其中g(shù)etView方法中的三個參數(shù)槐臀,position是指現(xiàn)在是第幾個條目锄蹂;convertView是舊視圖,就是繪制好了的視圖水慨;parent是父級視圖得糜,也就是ListView之類的。
用inflate方法繪制好后的view最后return返回給getView方法就可以了晰洒。


BaseAdapter的優(yōu)化使用

上面的convertView是舊視圖是什么意思呢朝抖?就是listview如果超出了屏幕,滑動的時候會隱藏掉一部分谍珊,這時候就將隱藏掉的部分保存到convertView中治宣。那么如果是我們之前的寫法,每次返回的時候就沒有使用convertView砌滞,重新創(chuàng)建了一個View侮邀,這樣子浪費(fèi)了系統(tǒng)資源。那要怎么利用convertView優(yōu)化呢布持?
同樣我們還是對getView進(jìn)行進(jìn)一步修改豌拙。

  • 首先定義一個類ViewHolder,用來標(biāo)記我們的控件
static class ViewHolder{
      TextView textView;
      ImageView imageView;
      Button button;
}
  • 接下來使用ViewHolder優(yōu)化
    在getView方法中题暖,Adapter先從xml中用inflate方法創(chuàng)建view對象按傅,然后在這個view找到每一個控件。這里的findViewById操作是一個樹查找過程胧卤,也是一個耗時的操作唯绍,所以這里也需要優(yōu)化,就是使用viewHolder枝誊,把每一個控件都放在Holder中况芒,當(dāng)?shù)谝淮蝿?chuàng)建convertView對象時,把這些控件找出來叶撒。然后用convertView的setTag將viewHolder設(shè)置到Tag中绝骚,以便系統(tǒng)第二次繪制ListView時從Tag中取出。當(dāng)?shù)诙沃赜胏onvertView時祠够,只需從convertView中g(shù)etTag取出來就可以压汪。
public View getView(int position, View convertView, ViewGroup parent) {
      LayoutInflater inflater = LayoutInflater.from(mContext);
      ViewHolder holder = null;
      if (convertView == null) {
          convertView = inflater.inflate(R.layout.item, null);
          holder = new ViewHolder();
          holder.button = (Button) convertView.findViewById(R.id.button);
          holder.textView = (TextView) convertView.findViewById(R.id.textView);
          holder.imageView = (ImageView) convertView.findViewById(R.id.imageView);
          convertView.setTag(holder);
      }    else {
          holder = (ViewHolder) convertView.getTag();
      }
      holder.imageView.setImageResource(R.mipmap.ic_launcher);
      holder.button.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View v) {
              Log.d("click","button");
          }
      });
      holder.textView.setText(data[position]);
      return convertView;
}

先判斷convertView是否為空,是的話就創(chuàng)建ViewHolder古瓤,不是的話就取出ViewHolder止剖,這樣就可以實(shí)現(xiàn)復(fù)用convertView了腺阳。

  • 最后,貼上源代碼穿香,這里就直接貼截圖就好了亭引。

這篇文章僅僅只是自己的理解,希望能夠幫助新手更好的理解BaseAdapter皮获,如果有意見歡迎指出焙蚓。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市洒宝,隨后出現(xiàn)的幾起案子主届,更是在濱河造成了極大的恐慌,老刑警劉巖待德,帶你破解...
    沈念sama閱讀 206,602評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異枫夺,居然都是意外死亡将宪,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評論 2 382
  • 文/潘曉璐 我一進(jìn)店門橡庞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來较坛,“玉大人,你說我怎么就攤上這事扒最〕笄冢” “怎么了?”我有些...
    開封第一講書人閱讀 152,878評論 0 344
  • 文/不壞的土叔 我叫張陵吧趣,是天一觀的道長法竞。 經(jīng)常有香客問我,道長强挫,這世上最難降的妖魔是什么岔霸? 我笑而不...
    開封第一講書人閱讀 55,306評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮俯渤,結(jié)果婚禮上呆细,老公的妹妹穿的比我還像新娘。我一直安慰自己八匠,他們只是感情好絮爷,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,330評論 5 373
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著梨树,像睡著了一般坑夯。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上劝萤,一...
    開封第一講書人閱讀 49,071評論 1 285
  • 那天渊涝,我揣著相機(jī)與錄音,去河邊找鬼。 笑死跨释,一個胖子當(dāng)著我的面吹牛胸私,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播鳖谈,決...
    沈念sama閱讀 38,382評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼岁疼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了缆娃?” 一聲冷哼從身側(cè)響起捷绒,我...
    開封第一講書人閱讀 37,006評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎贯要,沒想到半個月后暖侨,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,512評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡崇渗,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,965評論 2 325
  • 正文 我和宋清朗相戀三年字逗,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片宅广。...
    茶點(diǎn)故事閱讀 38,094評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡葫掉,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出跟狱,到底是詐尸還是另有隱情俭厚,我是刑警寧澤,帶...
    沈念sama閱讀 33,732評論 4 323
  • 正文 年R本政府宣布驶臊,位于F島的核電站挪挤,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏关翎。R本人自食惡果不足惜电禀,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,283評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望笤休。 院中可真熱鬧尖飞,春花似錦、人聲如沸店雅。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽闹啦。三九已至沮明,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間窍奋,已是汗流浹背荐健。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評論 1 262
  • 我被黑心中介騙來泰國打工酱畅, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人江场。 一個月前我還...
    沈念sama閱讀 45,536評論 2 354
  • 正文 我出身青樓纺酸,卻偏偏與公主長得像,于是被迫代替她去往敵國和親址否。 傳聞我的和親對象是個殘疾皇子餐蔬,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,828評論 2 345

推薦閱讀更多精彩內(nèi)容