适配器(Adpater)在Android发开中占有非常重地位,你可以理解它是一个从“数据源”通向“视图控件”的桥梁,下面一张图非常直观的说明了“数据源”、“适配器”、“视图控件”三者间的关系

    Android为我们提供了很多类型的适配器

    从中可以看到,我们之前常用ArrayAdpater、SimpleAdpater等类型的适配器,都是继承于BaseAdapter。BaseAdapter是一个抽象类,我们在使用它的使用它的时候,需要自定义一个类继承它并重写它的一些方法,它的特点是具有较高的灵活性。这里我们还是用ListView来作为今天这个小例子的显示控件。    1.因为ListView中每一个Item都是一个视图,所以我们先新建一个Item的布局:

item.xml

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="wrap_content">    <ImageView        android:id="@+id/image"         android:layout_width="60dp"        android:layout_height="60dp"        android:src="@drawable/ic_launcher"        />    <TextView         android:id="@+id/title"        android:text="标题"        android:textSize="25sp"        android:gravity="center"        android:layout_width="match_parent"        android:layout_height="30dp"        android:layout_toEndOf="@+id/image"                />    <TextView         android:id="@+id/text"        android:text="内容"        android:textSize="20sp"        android:gravity="center_vertical"        android:layout_width="match_parent"        android:layout_height="30dp"        android:layout_toEndOf="@+id/image"         android:layout_below="@+id/title"               />RelativeLayout>
    效果:

    2.创建一个ItemBean类,它抽象了Item中的所有控件对应的数据源
package com.example.baseadapter_test;/** * 将ListView要显示的Item抽象成一个类 */public class ItemBean {    public int Item_ImageResId;    public String Item_Title;    public String Item_Text;    public ItemBean(int Item_ImageResId,String Item_Tilie,String Item_Text) {        this.Item_ImageResId = Item_ImageResId;        this.Item_Text = Item_Text;        this.Item_Title = Item_Tilie;    }   }
    3.MainActivity
package com.example.baseadapter_test;import java.util.ArrayList;import java.util.List;import android.app.Activity;import android.os.Bundle;import android.view.Menu;import android.view.MenuItem;import android.widget.ListView;public class MainActivity extends Activity {    private List itemBeansList = new ArrayList();    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        //创建数据源        for (int i = 0; i < 20; i++) {            itemBeansList.add(new ItemBean(R.drawable.ic_launcher, "我是标题" + i, "我是内容容" + i));        }        //初始化控件        ListView listView = (ListView)findViewById(R.id.listview);        //设置适配器        listView.setAdapter(new MyAdapter(this, itemBeansList));    }}
    4.自定义一个MyAdapter类继承BaseAdapter并重写它的一些方法:
package com.example.baseadapter_test;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;public class MAdpater extends BaseAdapter{    private List itemBeansList;    //LayoutInflater作用是将layout的xml布局文件实例化为View类对象    private LayoutInflater inflater;     public MyAdapter(Context context,List itemBeansList) {        this.itemBeansList = itemBeansList;        inflater = LayoutInflater.from(context);    }    /**     * 返回数据的总数,它的值决定了ListView一共显示多少行     */    @Override    public int getCount() {        return itemBeansList.size();    }    /**     * 获取数据源中与指定索引对应的数据项     */    @Override    public Object getItem(int position) {        return itemBeansList.get(position);    }    /**     * 获取在ListView中与指定索引对应的行id     */    @Override    public long getItemId(int position) {        return position;    }    /**     * 返回每个Item(每一行)的显示内容     */    @Override    public View getView(int position, View convertView, ViewGroup parent) {        return null;    }}
    今天的重点来了~~!!!这里我要重点的说一下public View getView(......)这个方法,它会直接影响到ListView的性能。    在这之前,我们必须先来了解一下ListView的工作原(摘自http://www.cnblogs.com/xiaowenji/archive/2010/12/08/1900579.html):    1.ListView 针对List中每个item,要求 adapter “给我一个视图” (getView)。    2.一个新的视图(被创建然后)被返回并显示    如果我们要显示很多个item,我们肯定不能一直通过重新创建View并返回,因为这样会极大的消耗内存!怎么办呢?Android中有个叫做Recycler的构件,用来缓存视图,下图是他的工作原理:

    (1).如果你有10亿个项目(item),其中只有可见的项目存在内存中,其他的在Recycler中。    (2).ListView先请求一个type1视图(getView)然后请求其他可见的项目。convertView在getView中是空(null)的。    (3).当item1滚出屏幕,并且一个新的项目从屏幕低端上来时,ListView再请求一个type1视图。convertView此时不是空值了,它的值是item1。你只需设定新的数据然后返回convertView,不必重新创建一个视图。    了解了ListView缓存机制后,我们就开始愉快的重写public View getView(......)吧!|_( ̄▽ ̄)_|

重写方式一之“逗比式”:

@Override    public View getView(int position, View convertView, ViewGroup parent) {        //将布局文件转化成View对象        View view = inflater.inflate(R.layout.item, null);        //在已创建的View查找控件        ImageView imageView = (ImageView)view.findViewById(R.id.image);        TextView text = (TextView)view.findViewById(R.id.text);        TextView title = (TextView)view.findViewById(R.id.title);        //将数据添加到控件中        ItemBean bean = itemBeansList.get(position);        imageView.setImageResource(bean.Item_ImageResId);        text.setText(bean.Item_Text);        title.setText(bean.Item_Title);        return view;    }
    该方式通过不停的创建View并返回,没有利用到ListView的缓存机制,不但效率低,且非常浪费内存资源,如果你用这钟方式去做开发,我只想说你是个逗比!

重写方式一之“普通式”:

@Override    public View getView(int position, View convertView, ViewGroup parent) {        //判断convertView是否被缓存(如果已经被创建,就直接使用缓存的convertView,不需要重新创建convertView)        if(convertView == null){            //实例化一个布局            convertView = inflater.inflate(R.layout.item, null);        }        ImageView imageView = (ImageView)convertView.findViewById(R.id.image);        TextView text = (TextView)convertView.findViewById(R.id.text);        TextView title = (TextView)convertView.findViewById(R.id.title);        //将数据添加到控件中        ItemBean bean = itemBeansList.get(position);        imageView.setImageResource(bean.Item_ImageResId);        text.setText(bean.Item_Text);        title.setText(bean.Item_Title);        return convertView;    }
    该方式充分利用了ListView的缓存特性,极大提升了ListView的性能。。。唉哟~不错哦!

更多相关文章

  1. Android(安卓)Layout 布局
  2. LinearLayout中组件右对齐
  3. Android(Xamarin)之旅(三)
  4. android 机顶盒开发-----GridView
  5. Android属性动画上手实现各种动画效果,自定义动画,抛物线等
  6. Android(安卓)主流屏幕以及适配
  7. Android学习笔记17:中级视图组件DatePicker和TimePicker
  8. Android工具HierarchyViewer 代码导读
  9. Android(安卓)UI系列之3D星体旋转效果

随机推荐

  1. MySQL索引下推详细
  2. 解决MySql8.0 查看事务隔离级别报错的问
  3. MySQL主从同步原理及应用
  4. MySQL UPDATE 语句一个“经典”的坑
  5. 一条SQL语句在MySQL中是如何执行的
  6. 一次现场mysql重复记录数据的排查处理实
  7. MyBatis 动态SQL全面详解
  8. MySQL中datetime时间字段的四舍五入操作
  9. 浅谈MySQL表空间回收的正确姿势
  10. mysql如何能有效防止删库跑路