Android ListView筆記

1 AdapterView和Adapter

AdapterView的子類有ListView,GridView,可通過繼承自它們來自定義此類型的view,並通過實現AdapterView.OnItemClickListener接口來響應AdapterView中每一項上的點擊事件,佈局文件中對應等標籤爲:<ListView>、<GridView>。

Adapter充當數據源與AdapterView之間的橋樑,Adapter將數據與其佈局綁定,並將每條數據轉換爲AdapterView中的一條項目。

2 Adapter

Adaper的子類有ArrayAdapter,SimpleCursorAdapter等,當數據源比較複雜時,可以通過繼承BaseAdapter類來實現。

(1)ArrayAdapter:數據源爲數組時使用此適配器;

ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, myStringArray);
// 構造函數的參數:context,每個項目的佈局,數據數組  
ListView listView = (ListView) findViewById(R.id.listview);
listView.setAdapter(adapter);

(2)SimpleCursorAdapter:數據來自Cursor類時使用此適配器;當使用ContentResolver或從SQLite請求數據時,就將返回cursor對象。

String[] fromColumns = {ContactsContract.Data.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER};
int[] toViews = {R.id.display_name, R.id.phone_number};
// SimpleCursorAdapter會使用提供的佈局,將每個fromColumns項插入對應的toViews視圖,爲Cursor中的每個行創建一個視圖
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.person_name_and_number, cursor, fromColumns, toViews, 0);
ListView listView = getListView();
listView.setAdapter(adapter);

3 ListView的優化

(1)使用convertView和ViewHolder

(2)getView()方法裏不要有耗時任務

(3)異步加載數據

(4)滑動時停止加載(避免滑動時加載數據造成開銷太大,停止滑動時再加載數據),分頁加載(每次只加載一部分數據),通過實現AbsListView.OnScrollListener接口,並實現onScrollStateChanged(),onScroll()方法來實現;

(5)硬件加速:<listview>設置屬性android:hardwareAccelerate="true";

android:scrollingCache="false"默認開啓,會消耗大量內存

android:animationCache="false"

(6)item層級不要太高

4 convertView和ViewHolder

ListView的getView()方法中,會調用inflater.inflater(...)來加載每個item的佈局來獲得view,重用convertview可避免每次獲得view都去新建一個view;

當需要獲取某個view時,使用findViewById()耗時較大,可使用內部靜態內ViewHolder,並用過setTag,getTag來獲取view。

public View getView(int position, View convertView, ViewGroup parent) {
      ViewHolder viewHolder;
      //判斷是否有緩存
      if (convertView == null) {
          //通過LayoutInflate實例化佈局
          viewHolder = new ViewHolder();
          convertView = mInflater.inflate(R.layout.item_layout, parent, false);
          viewHolder.ivIcon = (ImageView) convertView.findViewById(R.id.iv_icon);
          viewHolder.tvTitle = (TextView) convertView.findViewById(R.id.tv_title);
          viewHolder.tvContent = (TextView) convertView.findViewById(R.id.tv_content);
          convertView.setTag(viewHolder);
      } else {
         //通過tag找到緩存的佈局
          viewHolder = (ViewHolder) convertView.getTag();
      }
      return convertView;
  }
內部靜態類ViewHolder:

static class ViewHolder {
  TextView text;
  TextView timestamp;
  ImageView icon;
  ProgressBar progress;
  int position;
}

5 異步加載

(1)新建一個線程,使用Handler方式來執行加載數據的任務;

(2)使用AysncTask類,在doInBackground()中加載數據,並重寫onPostExecute(Bitmap result);

(3)使用加載器;

6 加載器

1 加載器相關API

LoaderManager:用於管理一個或多個 Loader 實例;

LoaderManager.LoaderCallbacks:回調接口,用於客戶端通過LoaderManager管理Loader時會回調該接口中的方法;

Loader:執行異步數據加載的加載器類;

AsyncTaskLoader:提供AysncTask來執行工作的抽象加載器;

CursorLoader:AsyncTaskLoader的子類,它將查詢ContentResolver並返回一個Cursor;

此外,您可以通過繼承自AsyncTaskLoader來異步加載自定義的數據源。

2 LoaderManager 將自動管理加載器的生命週期。LoaderManager 將根據需要啓動和停止加載,並維護加載器的狀態及其相關內容。LoaderManager 將自動管理加載器的生命週期。您不必直接使用Loader的引用。當特定事件發生時,通常會使用LoaderManager.LoaderCallbacks方法干預加載進程。

3 LoaderManager常用方法

(1)啓動加載器:getLoaderManager().initLoader(0,null, this);

第1個參數是標識加載器的唯一ID,第2個參數是可選參數,第三個參數是LoaderManager.LoaderCallbacks實現,LoaderManager將調用此實現來報告加載器事件。將觸發LoaderManager.LoaderCallbacks的方法onCreateLoader();

(2)重啓加載器:getLoaderManager().restartLoader(0,null, this);

4 LoaderManager.LoaderCallbacks 包括以下方法:

onCreateLoader():針對指定的 ID 進行實例化並返回新的Loader,可以在此方法中創建新加載器;

onLoadFinished() :將在先前創建的加載器完成加載時調用;

onLoaderReset():將在先前創建的加載器重置且其數據因此不可用時調用;


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章