小試牛刀---自定義listView及其adapter動態刷新


本文主要探討自定義的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成員變量中
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
}
}

}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM