Android学习笔记の六

Android学习笔记の六


ListView

说起来ListView是非常常见的控件,大家一定加过不少。你刷个微博啊,刷个朋友圈啊其实刷的都是它。

先整个简单点的。
在activity_main中添加ListView控件

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

在MainActivity中添加如下代码

public class MainActivity extends Activity {

    private String[]  data = {"Apple", "Banana", "Orange", "Watermelon", "pear", 
            "Grape", "Pineapple", "Strawberry", "Cherry", "Mango", "Lemon", "Papaya", "Blueberry" };


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ArrayAdapter adapter = new ArrayAdapter(
                MainActivity.this, android.R.layout.simple_list_item_1, data);
        ListView listview = (ListView)findViewById(R.id.list_view);
        listview.setAdapter(adapter);
    }
 }

我们将一些水果的名字添加到ListView中。数组中的数据是无法传给ListView的,必须借助适配器来实现。因为我们传入的都是字符串,所以将ArrayAapter的泛型指定为String。然后在构造函数中依次传入上下文,子布局和数据。这里我们用的子布局是android自带的一个只包含一个TextView的布局。最后用setAdapter的方法将适配器与adapter相连。
运行一下就会得到下面的结果。
Android学习笔记の六_第1张图片
可以拖动屏幕看到下面的数据。

如果Listview只能显示一个TextView,那可真是太单调了。不过根据你刷微博和朋友圈的经历应该能很快猜出,Listview的布局是可以定制的!
下面让我们给水果都配上图片吧~
(当然首先你要先有一组图片。。。请出门右转自行baidu

我们建一个fruit类,作为 Listview的适配器类型。

public class Fruit {
    private String name;
    private int imageId;

    public Fruit(String name, int imageId){
        this.name = name;
        this.imageId = imageId;
    }

    public String getName(){
        return name;
    }

    public int getImageId(){
        return imageId;
    }
}

再自定义一个Listview的子项布局


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/fruit_image"
        android:layout_width="50dp"
        android:layout_height="50dp" />

    <TextView 
        android:id="@+id/friut_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_marginLeft="10dp" />

LinearLayout>

接着,我们需要自定义个适配器,继承自ArrayAdapter。

public class FruitAdapter extends ArrayAdapter{

    private int resourceId;
    @SuppressWarnings("unchecked")
    public FruitAdapter(Context context, int resource, List objects) {
        super(context, resource, objects);
        // TODO Auto-generated constructor stub
        resourceId = resource;
    }

    public View getView(int postion, View convertView, ViewGroup parent){
        Fruit fruit = (Fruit) getItem(postion); //获取fruit实例
        View view = LayoutInflater.from(getContext()).inflate(resourceId, null);//加载传入的布局
        ImageView image = (ImageView)view.findViewById(R.id.fruit_image);
        TextView name = (TextView)view.findViewById(R.id.friut_name);
        image.setImageResource(fruit.getImageId());//设置图片和文字
        name.setText(fruit.getName());
        return view;//返回布局
    }

}

下面修改MainActivity中的代码

public class MainActivity extends Activity {

    private List fruitlist = new ArrayList();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        init();
        FruitAdapter adapter = new FruitAdapter(
                MainActivity.this, R.layout.fruit_item, fruitlist);
        ListView listview = (ListView)findViewById(R.id.list_view);
        listview.setAdapter(adapter);
    }

    private void init(){
        Fruit apple = new Fruit("Apple", R.drawable.apple_pg);
        fruitlist.add(apple);
        Fruit banana = new Fruit("Banana", R.drawable.banana_pg);
        fruitlist.add(banana);
        Fruit orange = new Fruit("Orange", R.drawable.orange_pg);
        fruitlist.add(orange);
        Fruit watermelon = new Fruit("WaterMelon", R.drawable.watermelon_pg);
        fruitlist.add(watermelon);
        Fruit pear = new Fruit("Pear", R.drawable.pear_pg);
        fruitlist.add(pear);
        Fruit grape = new Fruit("Grape", R.drawable.grape_pg);
        fruitlist.add(grape);
        Fruit pineapple = new Fruit("Pineapple", R.drawable.pineapple_pg);
        fruitlist.add(pineapple);
        Fruit strawberry = new Fruit("Strawberry", R.drawable.strawberry_pg);
        fruitlist.add(strawberry);
        Fruit cherry = new Fruit("Cherry", R.drawable.cherry_pg);
        fruitlist.add(cherry);
        Fruit mango = new Fruit("Mango", R.drawable.mango_pg);
        fruitlist.add(mango);
        Fruit lemon = new Fruit("Lemon", R.drawable.lemon_pg);
        fruitlist.add(lemon);
        Fruit papaya = new Fruit("Papaya", R.drawable.papaya_pg);
        fruitlist.add(papaya);
        Fruit blueberry = new Fruit("Blueberry", R.drawable.blueberry_pg);
        fruitlist.add(blueberry);
    }
}

run一下,我们的水果就有图片啦~

Android学习笔记の六_第2张图片

提高Listview的运行效率

很不幸,目前我们这个Listview的运行效率极低,因为在getView中我们每次都把布局重新加载了一遍。当Listview滚动非常快时,这就会成为性能的瓶颈。
在getView中有一个convertView参数,这个参数用于将之前加载好的布局进行缓存,以便日后使用。修改FruitAdapter的代码。

public View getView(int postion, View convertView, ViewGroup parent){
        Fruit fruit = (Fruit) getItem(postion); //获取fruit实例
        View view;
        if(convertView == null)
            view = LayoutInflater.from(getContext()).inflate(resourceId, null);//加载传入的布局
        else view = convertView;
        ImageView image = (ImageView)view.findViewById(R.id.fruit_image);
        TextView name = (TextView)view.findViewById(R.id.friut_name);
        image.setImageResource(fruit.getImageId());//设置图片和文字
        name.setText(fruit.getName());
        return view;//返回布局
    }

我们对convertView进行判断,如果为空,就去加载布局;否则重用convertView。

每次调用view的findViewById也是会降低性能的,我们借助一个ViewHolder来优化。

public View getView(int postion, View convertView, ViewGroup parent){
        Fruit fruit = (Fruit) getItem(postion); //获取fruit实例
        View view;
        ViewHolder viewholder = null;
        if(convertView == null){
            view = LayoutInflater.from(getContext()).inflate(resourceId, null);//加载传入的布局
            viewholder = new ViewHolder();
            viewholder.image = (ImageView)view.findViewById(R.id.fruit_image);
            viewholder.name = (TextView)view.findViewById(R.id.friut_name);
            view.setTag(viewholder);//将viewholder存在view中
        }else {
            view = convertView;
            viewholder = (ViewHolder)view.getTag();
        }
        viewholder.image.setImageResource(fruit.getImageId());//设置图片和文字
        viewholder.name.setText(fruit.getName());
        return view;//返回布局
    }
    class ViewHolder{
        ImageView image;
        TextView name;
    }

点击事件

我们的Listview决不只是花瓶,它也是可以相应点击事件的
修改MainActivity的代码,让Listview相应点击事件。

 protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        init();
        FruitAdapter adapter = new FruitAdapter(
                MainActivity.this, R.layout.fruit_item, fruitlist);
        ListView listview = (ListView)findViewById(R.id.list_view);
        listview.setAdapter(adapter);

        listview.setOnItemClickListener(new OnItemClickListener(){

            @Override
            public void onItemClick(AdapterView parent, View view,
                    int position, long id) {
                // TODO Auto-generated method stub
                Fruit fruit = fruitlist.get(position);
                Toast.makeText(MainActivity.this, fruit.getName(), Toast.LENGTH_SHORT).show();;
            }

        });
    }

我们给listview注册了一个监听器,当点击其中的一个子项时,就可以在这个方法中通过postion判断用户点击的是哪一个子项。然后获取相应的水果元素,显示出水果名。
Android学习笔记の六_第3张图片

想要代码或者获取图片的请戳这里 ( ̄∇ ̄) http://download.csdn.net/detail/u013750822/8516579

你可能感兴趣的:(android)