自定義listView及其adapter動態重新整理
轉自:http://www.2cto.com/kf/201203/122878.html
本文主要探討自定義的adapter及其notifyDataSetChanged()方法的使用(無listView的監聽部分):
先上圖看下效果:(整個操作過程中,當前Activity未被pause或者stop, 豌豆莢截的圖真大....無語)
1,初始化狀態,共20個dataItem
2, 15秒後向下滑動,增加了一個text100的item:
3,點選新增後,向下滑動,增加了一個text200的item(每點一次新增按鈕就會增加一個text200的item):
4,點選刪除按鈕,上下滑動(每點一次,listView中的item就減少一個):
程式碼部分未貼完整,有簡要註釋,未考慮優化
adapter.xml:
<ListView
android:id="@+id/listview1"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:cacheColorHint="#00000000" />
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<Button
android:id="@+id/button_add"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="新增" >
</Button>
<Button
android:id="@+id/button_delete"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="刪除" >
</Button>
</LinearLayout>
<ListView/>標籤中屬性android:layout_height="0dp"和android:layout_weight="1"保證了Android平臺在佈局時會先計算其他元素(linearLayout)的寬高,再計算當前listView的寬高等屬性,因android:layout_weight="XXX"預設值為0, 1的優先順序要比0低(如果整個xml是RelativeLayout佈局,就easy了,有直接的屬性可以設定)
兩個<Button/>標籤中的屬性android:layout_weight="1"和android:layout_width="0dp",使得他們的父元素在佈局時,為他們平均分配空間,如果在其中一個<Button/>設定了間隔,如android:layout_marginLeft = "xxxdp",那麼父元素會先減去此間隔xxxdp,剩下空間依舊平均分配給兩個button按鈕
如圖:
adapter_item.xml:
<TextView
android:id="@+id/textview1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FF0000"
android:textSize="25dp" />
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="150dp"
android:focusable="false" />
Activity類AdapterActivity:
public class AdapterActivity extends Activity {
private ListView listView;
private List<HashMap<String, String>> data;
private ListViewAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.adapter);
listView = (ListView) findViewById(R.id.listview1);
Button addButton = (Button) findViewById(R.id.button_add);
Button deleteButton = (Button) findViewById(R.id.button_delete);
ButtonListener listener = new ButtonListener();
addButton.setOnClickListener(listener);
deleteButton.setOnClickListener(listener);
this.initListView();
Timer timer = new Timer();
timer.schedule(new TimerTask() {// 15秒後向data集合中增加一條資料
@Override
public void run() {
HashMap<String, String> map = new HashMap<String, String>();
map.put("text", "text100");
map.put("buttonText", "buttonText100");
data.add(map);
Log.i(Constant.TAG, "新增資料成功");
// adapter.notifyDataSetChanged(); 非UI執行緒報錯
Message msg = new Message();
msg.what = 1;
handler.sendMessage(msg);
}
}, 15000);
}
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
// super.handleMessage(msg);
switch (msg.what) {
case 1:
// UI執行緒中呼叫此方法通知觀察者(原始碼中關於adapter存在一個observer,未深究!)adapter資料已改變,重新整理view
adapter.notifyDataSetChanged();
// adapter.notifyDataSetInvalidated();// 與上面
// 效果相同,原始碼中除了註釋不同,執行的程式碼一樣,同樣未深究
// listView.postInvalidate();重新整理無效
break;
}
}
};
private void initListView() {
data = ViewApp.getData();// ViewApp是一個全域性的類,程式執行時data資料即載入完畢,這是隻是賦值到data成員變數中www.2cto.com
adapter = new ListViewAdapter(this, data, R.layout.adapter_item);
SimpleAdapter simpleAdapter = new SimpleAdapter(this, data,
R.layout.adapter_item, new String[] { "text", "buttonText" },
new int[] { R.id.textview1, R.id.button1 });
listView.setAdapter(adapter);
}
class ListViewAdapter extends BaseAdapter {
private List<HashMap<String, String>> data;
private int resource;
private LayoutInflater inflater;
private HashMap<String, String> itemData;
public ListViewAdapter(Context context,
List<HashMap<String, String>> data, int resource) {
// super(context, data, resource, from, to);
this.data = data;
this.resource = resource;
inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
return data.size();
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
// 渲染每一個item的資料,每次上下滑動顯示資料時都會呼叫此方法
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (null == convertView) {
convertView = inflater.inflate(resource, null);
}
// convertView.setTag("abc");
itemData = data.get(position);
TextView textView = (TextView) convertView
.findViewById(R.id.textview1);
textView.setText(itemData.get("text"));
final Button button = (Button) convertView
.findViewById(R.id.button1);
button.setText(itemData.get("buttonText"));
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(AdapterActivity.this, button.getText(),
Toast.LENGTH_SHORT).show();
}
});
return convertView;
}
}
class ButtonListener implements View.OnClickListener {
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button_add:
HashMap<String, String> map = new HashMap<String, String>();
map.put("text", "text200");
map.put("buttonText", "buttonText200");
data.add(map);
Log.i(Constant.TAG, "ADD");
break;
case R.id.button_delete:
Log.i(Constant.TAG, "DELETE");
data.remove(1);
break;
}
adapter.notifyDataSetChanged();// adapter更改後重新整理view
}
}
}