深入ListView

我们接着上一篇博客,对ListView进行更加深入的了解。

属性

android:cacheColorHint=”@color/white” 设置ListView滚动时的背景色
android:divider=”@color/red” 设置ListView分割线的颜色
android:dividerHeight=”1dp” 设置ListView分割线的高度

设置点击列表的背景

更改listview点击背景与更改Button点击背景和RadioButton选择图标的方法类似。
①在drawable文件夹下新建xml文档list_background.xml

<?xml version="1.0" encoding="utf-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android" >    <item android:drawable="@color/red" android:state_pressed="true"/>     <item android:drawable="@color/white"/></selector>

②在自定义的布局中加入属性background

android:background="@drawable/list_background"

提升ListView的运行效率

  1. 在上一篇博客中,StudentAdapter的getView()方法,每次都将布局重新加载了一遍,当ListView快速滚动的时候这就会成为性能的瓶颈。我们注意到getView()方法中还有一个参数convertView,这个参数用于将之前加载好的布局进行缓存,以便之后可以进行重用。
    我们在getView()方法中进行了判断,如果convertView为空,则使用inflater去加载布局,如果不为空则直接对convertView进行重用
  2. 我们每次在getView()方法中还是会调用View的findViewById()方法来获取一次控件的实例。此时可以借助一个ViewHolder来对这部分性能进行优化。
    新增一个内部类ViewHolder,用于对控件的实例进行缓存。当convertView为空,创建一个ViewHolder对象,并将控件的实例都存放在ViewHolder里,然后调用View的setTag()方法,将ViewHolder对象存储在View中。当convertView不为空时则调用View的getTag()方法,将ViewHolder重新取出
    优化后的代码:
@Overridepublic View getView(int position, View convertView, ViewGroup parent) {    Stuent student = arraylist.get(position);    View view;    ViewHolder viewHolder;    if (convertView == null) {        view = inflater.inflate(R.layout.simpleadapter_layout, null);        viewHolder=new ViewHolder();        viewHolder.image = (ImageView) view.findViewById(R.id.imageview);        viewHolder.textview_name = (TextView) view.findViewById(R.id.textview_name);        viewHolder.textview_age = (TextView) view.findViewById(R.id.textview_age);        viewHolder.textview_sex = (TextView) view.findViewById(R.id.textview_sex);        viewHolder.textview_hobby = (TextView) view.findViewById(R.id.textview_hobby);        view.setTag(viewHolder);//将viewHolder存储在view中        }else{            view=convertView;            viewHolder=(ViewHolder) view.getTag();//重新获取viewHolder        }       viewHolder.textview_name.setText(student.getName());    viewHolder.textview_age.setText(student.getAge());    viewHolder.textview_sex.setText(student.getSex());    viewHolder.textview_hobby.setText(student.getHobby());    viewHolder.image.setImageResource(student.getImage());    return view;}class ViewHolder{    ImageView image;    TextView textview_name;    TextView textview_age;    TextView textview_sex;    TextView textview_hobby;}

ListView其他常见的用法

在ListView加入其他点击控件

当我们在ListView中加入了其他的点击控件,如CheckBox,Button,RadioButton等,就会抢夺ListView的焦点,这时我们点击ListView就没有反应。
我们有两种办法可以解决这个问题:
①在ListView中设置屏蔽子控件抢夺ListView的焦点

android:descendantFocusability="blocksDescendants"  

②在子控件本身设置焦点属性为false。

android:focusable="false"

添加HeaderView和FooterView

  1. 首先我们要新建HeaderView或FooterView的布局xml文件
  2. 然后用LayoutInflater加载布局,生成View对象
  3. 最后调用addHeaderView()或addFooterView(),传入View对象即可。
    注意:当我们在ListView中添加了HeaderView之后,使用ListView点击事件时,ListView中item的索引要减1。

综合的代码示例

定义一个实体类 Fruit

public class Fruit {    private int image;    private String name;    private boolean isChecked;    public Fruit(int image, String name) {        this.image = image;        this.name = name;    }    public int getImage() {        return image;    }    public void setImage(int image) {        this.image = image;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public boolean isChecked() {        return isChecked;    }    public void setChecked(boolean isChecked) {        this.isChecked = isChecked;    }   }

为listview的子项指定自定义的布局

?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="match_parent" android:orientation="horizontal" >    <CheckBox android:id="@+id/checkbox" android:layout_width="wrap_content" android:layout_height="wrap_content" android:focusable="false" android:text="选择水果"/>    <ImageView android:id="@+id/fruit" android:layout_width="wrap_content" android:layout_height="wrap_content"/>    <TextView android:id="@+id/textview" android:layout_width="wrap_content" android:layout_height="wrap_content"/>  </LinearLayout>

自定义适配器FruitAdapter.java

mport java.util.ArrayList;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.CheckBox;import android.widget.CompoundButton;import android.widget.CompoundButton.OnCheckedChangeListener;import android.widget.ImageView;import android.widget.TextView;public class FruitAdapter extends BaseAdapter {    private LayoutInflater inflater;    private ArrayList<Fruit> list;    public FruitAdapter(LayoutInflater inflater, ArrayList<Fruit> list) {        this.inflater = inflater;        this.list = list;    }    /** * 全选 */    public void checkAll() {        for (int i = 0; i < list.size(); i++) {            list.get(i).setChecked(true);        }        notifyDataSetChanged();    }    /** * 反选 */    public void reverse() {        for (int i = 0; i < list.size(); i++) {            selectItem(i);        }    }    /** * 点击ListView可以勾选住CheckBox * * @param position 当前ListView的位置 */    public void selectItem(int position) {        boolean isChecked = list.get(position).isChecked();        isChecked = !isChecked;        list.get(position).setChecked(isChecked);        notifyDataSetChanged();// 刷新界面    }    @Override    public int getCount() {        return list.size();    }    @Override    public Object getItem(int arg0) {        return arg0;    }    @Override    public long getItemId(int arg0) {        return arg0;    }    @Override    public View getView(final int position, View convertView, ViewGroup arg2) {        Fruit fruit = list.get(position);        View view;        ViewHolder viewHolder;        if (convertView == null) {            view = inflater.inflate(R.layout.fruit_layout, null);            viewHolder = new ViewHolder();            viewHolder.checkbox = (CheckBox) view.findViewById(R.id.checkbox);            viewHolder.image = (ImageView) view.findViewById(R.id.fruit);            viewHolder.name = (TextView) view.findViewById(R.id.textview);            view.setTag(viewHolder);        } else {            view = convertView;            viewHolder = (ViewHolder) view.getTag();        }        viewHolder.image.setImageResource(fruit.getImage());        viewHolder.name.setText(fruit.getName());        viewHolder.checkbox                .setOnCheckedChangeListener(new OnCheckedChangeListener() {                    @Override                    public void onCheckedChanged(CompoundButton buttonView,                            boolean isChecked) {                        list.get(position).setChecked(isChecked);//如果勾选,将该项设为true                    }                });        viewHolder.checkbox.setChecked(fruit.isChecked());//将ViewHolder中的实例重新设置为false        return view;    }    class ViewHolder {        CheckBox checkbox;        ImageView image;        TextView name;    }}

HeaderView和FooterView的布局文件

<?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="match_parent" android:orientation="vertical" >    <Button android:id="@+id/button_quan" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="全选"/></LinearLayout>
<?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="match_parent" android:orientation="vertical" >    <Button android:id="@+id/button_fan" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="反选"/></LinearLayout>

MainActivity

import java.util.ArrayList;import android.os.Bundle;import android.view.LayoutInflater;import android.view.View;import android.view.View.OnClickListener;import android.widget.AdapterView;import android.widget.Button;import android.widget.Toast;import android.widget.AdapterView.OnItemClickListener;import android.widget.ListView;import android.app.Activity;public class MainActivity extends Activity {    private LayoutInflater inflater;    private FruitAdapter adapter;    private ArrayList<Fruit> list;    private View fruitHeaderView;    private View fruitFooterView;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        list = new ArrayList<Fruit>();        for (int i = 0; i < 5; i++) {            Fruit apple = new Fruit(R.drawable.apple, "苹果");            Fruit banana = new Fruit(R.drawable.banana, "香蕉");            Fruit grape = new Fruit(R.drawable.grape, "葡萄");            Fruit strawberry = new Fruit(R.drawable.strawberry, "草莓");            list.add(apple);            list.add(banana);            list.add(grape);            list.add(strawberry);        }        inflater = getLayoutInflater();        adapter = new FruitAdapter(inflater, list);        ListView listView = (ListView) findViewById(R.id.listview_fruit);        fruitHeaderView = inflater.inflate(R.layout.fruit_header, null);        listView.addHeaderView(fruitHeaderView);        Button button_quan = (Button) fruitHeaderView                .findViewById(R.id.button_quan);        button_quan.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View arg0) {                adapter.checkAll();// 全选            }        });        fruitFooterView = inflater.inflate(R.layout.fruit_footer, null);        listView.addFooterView(fruitFooterView);        Button button_fan = (Button) fruitFooterView                .findViewById(R.id.button_fan);        button_fan.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View arg0) {                adapter.reverse();// 反选            }        });        listView.setAdapter(adapter);        //点击listview,勾选中当前checkbox        listView.setOnItemClickListener(new OnItemClickListener() {            @Override            public void onItemClick(AdapterView<?> arg0, View view,                    int position, long id) {                // 因为加了HeaderView,所以索引要减1                adapter.selectItem(position - 1);// 调用点击lsitview选择checkbox的方法                Toast.makeText(MainActivity.this,                        "选择的水果为:" + list.get(position - 1).getName(),                        Toast.LENGTH_SHORT).show();            }        });    }}

运行结果:

点击ListView,会勾选CheckBox

点击全选,则全部选中

点击反选,则去掉之前选中的其余部分

更多相关文章

  1. 浅谈Java中Collections.sort对List排序的两种方法
  2. Python list sort方法的具体使用
  3. python list.sort()根据多个关键字排序的方法实现
  4. android上一些方法的区别和用法的注意事项
  5. 三、安卓UI学习(1)
  6. Android(安卓)环境搭建
  7. android实现字体闪烁动画的方法
  8. android studio调试c/c++代码
  9. Android中dispatchDraw分析

随机推荐

  1. relativelayout常用属性
  2. Android:CoordinatorLayout使用详解
  3. Android之TabHost
  4. Android--边距(margin)与内边距(padding)
  5. LinearLayout按下(pressed)或获取焦点(foc
  6. 推荐几个比较好的android客户端开发教程
  7. Android(安卓)UI(8)Building Apps with U
  8. 新浪微博Android客户端学习记录四:完成OAu
  9. android 9.0 SD卡权限问题 文件管理器没
  10. 四十六、android中的Bitmap