介紹擴充卡的使用,從淺到深,一共6步,這6步所用到的xml檔案相同,就是下面這兩個
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="${relativePackage}.${activityClass}" >
<ListView
android:id="@+id/lv"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
item1中第二個TextView隻有在5和6中用到
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<ImageView
android:id="@+id/item1_iv"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_gravity="center_vertical"
android:src="@drawable/h2" />
<TextView
android:id="@+id/item1_tv"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="ddddddd"
android:gravity="center" />
<CheckBox
android:id="@+id/item1_cb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical" />
</LinearLayout>
1.簡單擴充卡的使用
package com.example.adapterdemo2;
import android.app.Activity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
public class MainActivity2 extends Activity {
ListView lv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lv=(ListView) findViewById(R.id.lv);
MyAdapter ma=new MyAdapter();
lv.setAdapter(ma);
}
class MyAdapter extends BaseAdapter{
@Override
public int getCount() {
// TODO Auto-generated method stub
return ;
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return ;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
LayoutInflater layoutInflater=MainActivity2.this.getLayoutInflater();
View view=layoutInflater.inflate(R.layout.item1, parent,false);
return view;
}
}
}
這篇代碼實作的功能比較簡單,在activity_main.xml檔案中建立一個元件ListView,設定相應的id.在MainActivity中findViewByid執行個體化這個控件.
建立一個子類繼承BaseAdapter,實作抽象方法.在getCount()方法中設定條目數量,之後再getView()方法中實作下面的功能(MainActivity中沒有以下注釋)
之後的步驟就是建立子類的對象,然後通過setAdapter();方法将這個對象傳進去,詳情看代碼
2.将集合資料傳到條目中的擴充卡的使用
package com.example.adapterdemo2;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
public class MainActivity extends Activity {
private ListView lv;
private List<String>datas=new ArrayList<String>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
for(int i=;i<;i++){
datas.add("我是資料------>"+i);
}
lv=(ListView) findViewById(R.id.lv);
MyAdapter ma=new MyAdapter();
lv.setAdapter(ma);
}
class MyAdapter extends BaseAdapter{
@Override
public int getCount() {
// TODO Auto-generated method stub
return datas.size();
}
@Override
public String getItem(int position) {
// TODO Auto-generated method stub
return datas.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
LayoutInflater layoutInflater=MainActivity.this.getLayoutInflater();
View view=layoutInflater.inflate(R.layout.item1, parent,false);
TextView tv=(TextView)view.findViewById(R.id.item1_tv);
tv.setText(getItem(position));
return view;
}
}
}
和上面的擴充卡的使用基本一樣,有幾處需要注意的地方
(1)下面代碼紅色标注的地方,注意這裡并不是activity_main中的元件,而是在上一行view對象中,上一行已經将相應的布局檔案轉換成View對象,而所加載的TextView就在這個布局中,是以在這裡應該特别注意
(2)紅線标注的方法,傳回一個字元串,position是條目的位置,也可以将第二個橫線位置,換成datas.get(position),也就是上面方法的傳回值
3.擴充卡内部的優化使用(針對View對象)
這個擴充卡的使用效果和上的擴充卡使用的效果一樣,但是内部進行了優化,使記憶體的使用的到了優化
getView() 方法會被反複調用很多次,加載不同位置的條目
當ListView初次展開時,getView方法調用多少次?
取決于目前界面展現了多少條目,不展現的條目暫時不加載 ——這就是BaseAdapter的内部優化機制
當上下滾動時,界面展現哪個條目,我們就調用getView方法加載哪一個條目
此時因為 重新調用了該位置的getView,是以會重新inflate一個新的view對象,那麼之前我們舊的view對象就成為了垃圾對象 ,造成記憶體必要的消耗
是以,我們要針對此種情況進行優化 :複用view對象 使用參數converView
假如我們界面 可以展現5個條目 那麼總共會有多少個view對象?會有7個,最上面的露一半,最下面的露一半.是以可能有7個
在這篇代碼getView方法中有如下代碼
在标簽可以看出converView.hashCode()的值會被反複使用,而上一個擴充卡的使用converView.hashCode()所列印的完全不同.關于這裡的優化問題在另一篇筆記擴充卡(2)中有介紹
4.擴充卡内部的優化使用(針對View和TextView對象)
針對View對象造成的記憶體浪費,在3中已經進行了優化,但是在每次調用getVeiw方法,更新TextView對象tv時,tv都會重新finViewById,而這個方法也會重新建立一個對象,也會造成記憶體的浪費,(在新版本的手機中這個問題已經在版本中進行了優化,不用開發者考慮,但是我們也需要知道這個原理和方法,主要針對沒有進行優化的手機版本),問題和3中所說的問題相似,就不在贅述,隻說一下解決方法.
我已開始是這麼了解的:
convertView怎麼解決,tv就怎麼解決,這樣的了解是錯了,因為converView是緩存對象,是時刻存在的而TextView的對象tv不是,每次執行這個方法時,tv對象都需要重新建立,而converView不為空時,tv為空,是以既然convertView不會消失,那麼就将tv存到converView中,于是就有了開始時候的解決辦法了,通過setTag進行存儲,getTag進行提取
5.多個TextView對象的擴充卡的使用
我一開始的了解是如果有兩個TextView,是不是可以一個一個的使用,就和上面TextView對象tv一樣,隻是多了一個,事實是錯的,因為convertView的setTag方法隻能用一次,getTag也是同樣的道理
是以應用java面向對象的思想,一個功能一個類,将多個TextView對象封裝到一個類裡面,對這個類對象進行操作即可,代碼不難,了解思想
6.對CheckBox使用優化的擴充卡
因為convertView對象中沒有儲存CheckBox的狀态,是以就算打上勾條目消失後,勾選狀态也就消失了,是以應該想辦法,留住相應位置的選中狀态,可以用鍵值對來儲存,也就是用Map集合,位置是Key,狀态是Value.把CheckBox也封裝到類裡面(就是5中的 ViewHolder類)
圖中紅線:将位置存到CheckBox對象cb的Tag裡
圖中紫線:對cb進行監聽(最好不要内名内部類,因為每次都會産生一個新對象)
圖中藍線:根據位置position(Key)取出是否被選中的狀态(Value)
圖中黃線:取出存儲在cb中的位置