ListView

一、ListView理解

  1、ListView是一种用来显示多个可滑动项(Item)列表的的ViewGroup

  2、需要使用Adapter将集合数据和每一个Item所对应的布局动态适配到ListView中显示

  3、显示列表: listView.setAdapter(adapter)

  4、更新列表: adapter.notifyDataSetChanged()

  

二、Adapter

  1、结构

    

    1)ArrayAdapter: 显示最简单的列表(文本) 集合数据为List<String>或String[]       

    2)SimpleAdapter: 显示复杂的列表 集合数据必须是List<Map<String,Object>>类型       

    3)BaseAdapter: 显示复杂的列表 集合数据可以是任意类型的集合List<自定义类型>        

    4)SimpleCursorAdapter: 显示复杂的列表 集合数据是数据库查询结果集

  2、ListView+ArrayAdapter  显示简单列表

     

      context: 上下文件对象, 一般为Acivity对象

      resource: Item的布局文件标识

      objects: 需要显示的数据集合(Array或List)

    1)新建一个ListView

      

     2)创建item布局

       

    3)准备数据设置Adapter显示列表

public class MainActivity extends Activity {
    //定义ListView
    private ListView lv_main;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //初始化ListView
        lv_main = (ListView)findViewById(R.id.lv_main);
        
        //准备集合数据
        String[] data = {"A","B","C","A","B","C","A","B","C","A","B","C","A","B","C"};
        //准备ArrayAdapter对象
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,R.layout.item_array_adpter,data);
        //设置Adapter显示列表
        lv_main.setAdapter(adapter);
    }
}

    4)运行结果

      

   2、ListView + SimpleAdapter  显示复杂列表

    

    context: 上下文件对象, 一般为Acivity对象

    data: 需要显示的数据集合

    resource: Item布局文件标识

    from: map对象中的key的数组, 用于得到对应的value

    to: Item布局文件中的子view的id的数组

      1)因为结构和上面一样,所以直接上代码

public class MainActivity extends Activity {
    //定义ListView
    private ListView lv_main;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //初始化ListView
        lv_main = (ListView)findViewById(R.id.lv_main);
        //准备集合数据
        List<Map<String,Object>> data = new ArrayList<Map<String,Object>>();
        Map<String,Object> map = new HashMap<String, Object>();
        map.put("icon", R.drawable.tou);
        map.put("name", "name-1");
        map.put("content", "name-1");
        data.add(map);
        
        map = new HashMap<String, Object>();
        map.put("icon", R.drawable.tou);
        map.put("name", "name-2");
        map.put("content", "name-2");
        data.add(map);
        
        map = new HashMap<String, Object>();
        map.put("icon", R.drawable.tou);
        map.put("name", "name-3");
        map.put("content", "name-3");
        data.add(map);
        
        map = new HashMap<String, Object>();
        map.put("icon", R.drawable.tou);
        map.put("name", "name-4");
        map.put("content", "name-4");
        data.add(map);
        
        map = new HashMap<String, Object>();
        map.put("icon", R.drawable.tou);
        map.put("name", "name-5");
        map.put("content", "name-5");
        data.add(map);
        //from:map对象中的key的数组, 用于得到对应的value
        String[] from = {"icon","name","content"};
        //to:Item布局文件中的子view的id的数组
        int[] to = {R.id.ig_simple,R.id.tv1_simple,R.id.tv2_simple};
        //准备SimplAdapter对象
        SimpleAdapter adapter = new SimpleAdapter(this, data, R.layout.item_simple_adapter, from, to);
        //设置Adapter显示列表
        lv_main.setAdapter(adapter);
    }
}

    结果

    

   3、ListView + BaseAdapter(抽象的) 显示复杂列表

    BaseAdapter是实现了ListAdapter和SpinnerAdapter两个接口,当然它也可以直接给ListView和Spinner等UI组件直接提供数据。

    int getCount();得到集合数据的个数,决定了能显示多少行

    Object getItem(int position):根据position得到对应的数据对象

    View getView(int position,View convertView,ViewGroup parrent){

      //根据position返回对应的带数据的Item视图对象

      position:下标

      conbertView:可复用的Item视图对象

        为null:没有可复用的,我们必须加载一个item的布局文件,并赋值给convertView

        不为null:直接使用此视图对象

        后面:找到子View,找到对应的数据,设置数据

        parent:ListView

    }

    给ListView的Item设置监听

      item的点击监听:listView.setOnItemClickListener(listener);

      item的长按监听:listView.setOnItemLongClickListener(listener);

  

    代码如下:

public class MainActivity extends Activity {
    //定义ListView
    private ListView lv_main;
    private List<ShowInfo> data;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //初始化ListView
        lv_main = (ListView)findViewById(R.id.lv_main);
        //准备集合数据
        data = new ArrayList<ShowInfo>();
        data.add(new ShowInfo(R.drawable.tou, "name-1", "name-2"));
        data.add(new ShowInfo(R.drawable.tou, "name-2", "name-3"));
        data.add(new ShowInfo(R.drawable.ic_launcher, "name-3", "name-4"));
        data.add(new ShowInfo(R.drawable.tou, "name-4", "name-5"));
        data.add(new ShowInfo(R.drawable.tou, "name-5", "name-6"));
        //准备BaseAdapter对象
       MyAdapter adapter = new MyAdapter();
        //设置Adapter显示列表
       lv_main.setAdapter(adapter);
    }
    //继承BaseAdapter
    class MyAdapter extends BaseAdapter{
        @Override
        //返回集合数据数量
        public int getCount() {
            return data.size();
        }
    
        @Override
        //返回指定下标对应对像
        public Object getItem(int position) {
            return data.get(position);
        }
        @Override
        public long getItemId(int position) {
            return 0;
        }
        @Override
        /**
         * 返回指定下标所对应的item的view对象
         * position:下标
         * convertView:可复用的缓存Item视图对象
         * parent:ListView对象
         */
        public View getView(int position, View convertView, ViewGroup parent) {
            //使用可复用的缓存优化ListView  
            if(convertView==null){
                //加载item的布局,得到view对象
                convertView = View.inflate(MainActivity.this, R.layout.item_simple_adapter, null);
            }
            //根据position设置对应的数据
                //得到当前的数据对象
            ShowInfo si = data.get(position);
            ImageView iv = (ImageView)convertView.findViewById(R.id.ig_simple);
            TextView tv = (TextView)convertView.findViewById(R.id.tv1_simple);
            TextView tv1 = (TextView)convertView.findViewById(R.id.tv2_simple);
            
            iv.setImageResource(si.getId());
            tv.setText(si.getName());
            tv1.setText(si.getContent());
            return convertView;
        }
    }
}

   注意ListView的优化问题

    内存中最多存在n+1个convertView对象

    只有当convertView为null时才去加载item的布局文件(当不断滑动加载item就会出现内存溢出的异常,程序强制停止)

    

      

posted @ 2016-11-25 16:29  asc  阅读(377)  评论(0编辑  收藏  举报