小试牛刀---自定义listView及其adapter动态刷新
3234 点击·0 回帖
![]() | ![]() | |
![]() | 本文主要探讨自定义的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.atcpu.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 } } } | |
![]() | ![]() |