天天看点

android ListView详解,你不知道的事 (后附焦点解决方法)

对于android开发者来说,ListView无疑是最为常见的一个控件之一,android系统给我们提供了一些ArrayAdapter(文字),SimpleAdapter(图文),CursorAdapter(数据库数据)。这些毕竟是局限的,那么可以通过自己的喜好来设置ListView吗?当然可以,接下来介绍自定义ListView的具体使用。

在开始正文之前,我们应该会想这些Adapter的目的是什么,他们是一个桥梁,将数据和视图搭建起来。那么适配器肯定是ListView的关键因素。我们应该解决两个关键性的问题,数据在哪里,还有就是怎么显示数据。下面从4个方面详解ListView。

1.获取ListView控件对象

首先在布局文件中定义ListView的控件属性

<ListView
        android:id="@+id/lv_main"
        android:layout_height="wrap_content"
        android:layout_width="fill_parent"/>
           

在MainActivity中获取控件

// 获取ListView对象
        ListView listview = (ListView)findViewById(R.id.lv_main);
           

2.准备数据源

这里模拟了一些数据,这些数据通过键值对的形式存储到集合中(数据来源)

List<Map<String,Object>> list = new ArrayList<Map<String,Object>>();
        Map<String,Object> map = new HashMap<String, Object>();
        map.put("logo", R.drawable.ic_10);
        map.put("title", "千千静听");
        map.put("version", "版本: 8.4.0");
        map.put("size", "大小: 32.81M");
        list.add(map);

        map = new HashMap<String, Object>();
        map.put("logo", R.drawable.ic_2);
        map.put("title", "时空猎人");
        map.put("version", "版本: 2.4.1");
        map.put("size", "大小: 84.24M");
        list.add(map);

        map = new HashMap<String, Object>();
        map.put("logo", R.drawable.ic_4);
        map.put("title", "360新闻");
        map.put("version", "版本: 6.2.0");
        map.put("size", "大小: 11.74M");
        list.add(map);

        map = new HashMap<String, Object>();
        map.put("logo", R.drawable.ic_15);
        map.put("title", "捕鱼达人2");
        map.put("version", "版本: 2.3.0");
        map.put("size", "大小: 45.53M");
        list.add(map);
           

3.准备适配器

这里通过构造器传入了一个上下文对象和list集合(数据源)

//3. 准备适配器Adapter
        MyAdapter adapter=new MyAdapter(this,list);
           

之后新建一个MyAdapter.java类,继承BaseAdapter,这时会实现getCount,getItem,getItemId,getView这4个方法,重写getView,这里解决怎么去显示数据。

public class MyAdapter extends BaseAdapter{
    List<Map<String, Object>> list;
    Context context;
    public MyAdapter(Context context,List<Map<String, Object>> list){
        this.list = list;
        this.context=context;
    }

    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return list.size();
    }

    @Override
    public Object getItem(int position) {
        // TODO Auto-generated method stub
        return list.get(position);
    }

    @Override
    public long getItemId(int position) {
        // TODO Auto-generated method stub
        return position;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup arg2) {
        LayoutInflater inflater=LayoutInflater.from(context);
        View view=inflater.inflate(R.layout.item, null);
        ImageView logo=(ImageView) view.findViewById(R.id.logo);
        TextView title=(TextView) view.findViewById(R.id.title);
        TextView version=(TextView) view.findViewById(R.id.version);
        TextView size=(TextView) view.findViewById(R.id.size);
        Button btn=(Button) view.findViewById(R.id.btn);
        Map map=list.get(position);
        logo.setImageResource((Integer) map.get("logo"));
        title.setText((String) map.get("title"));
        version.setText((String) map.get("version"));
        size.setText((String) map.get("size"));


        return view;
    }

}
           

在这里需要去设置自己喜爱的ListView行布局,然后将布局反射成View对象。新建一个item.xml布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:layout_marginLeft="5dp"
    android:layout_marginTop="5dp"
    android:layout_marginRight="5dp"
    android:gravity="center_vertical"
    android:padding="5dp"
    android:descendantFocusability="blocksDescendants">
    <!-- 用上面代码抢回焦点 -->


        <ImageView
            android:id="@+id/logo"
            android:src="@drawable/ic_10"
            android:layout_width="70dp"
            android:layout_height="70dp"
            />
        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:layout_marginLeft="5dp"
            android:orientation="vertical">
            <TextView
                android:id="@+id/title"
                android:text="天天静听"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textSize="16sp"
                android:layout_marginTop="2dp"/>
            <TextView
                android:id="@+id/version"
                android:text="版本: 8.4.0"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textSize="12sp"
                android:textColor="#999"
                android:layout_marginTop="6dp"/>
            <TextView
                android:id="@+id/size"
                android:text="大小: 32.81M"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textSize="12sp"
                android:textColor="#999"
                android:layout_marginTop="6dp"/>
        </LinearLayout>

        <Button
            android:focusable="false"
            android:id="@+id/btn"
            android:text="安装"
            android:textColor="#fff"
            android:textSize="14sp"
            android:layout_width="66dp"
            android:layout_height="30dp"
            android:background="@drawable/btn_selector"
            android:layout_marginRight="5dp"/>
</LinearLayout>
           

4.设置适配器

将适配器和ListView关联起来

//4. 将适配器关联到ListView
        listview.setAdapter(adapter);
           

这里小插曲一下,关于ListView点击事件不能点击的情况,是因为焦点被button按钮抢占了,要想解决此问题,简单的说两个方法。

(1)抢回焦点

(2)设置Button属性

这样大概自定义ListView就基本完成了,放一下效果图

android ListView详解,你不知道的事 (后附焦点解决方法)

继续阅读