自定义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
        }
    }

}

猜你喜欢

转载自blog.csdn.net/wcy9200/article/details/7906179