BaseAdapter 三重境界

什么是数据适配器

这里写图片描述

并且ListView内置缓存机制,显示在屏幕上的展示出来,不在屏幕上的缓存起来

  • 编写代码步骤。
    数据源:

    1:实体类的封装;
    2:初始化数据;

适配器:编写自定义适配器;

主页面:适配器与视图之间的绑定;

  • BaseAdapter的四个方法

这里写图片描述

主界面布局

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
    <ListView
        android:id="@+id/lv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />
</RelativeLayout>

item布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="50dp" 
    >
    <ImageView 
         android:id="@+id/iv"
        android:layout_alignParentLeft="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" 
         android:src="@drawable/ic_launcher"
        />
    <TextView 
        android:id="@+id/tv_show"
        android:layout_alignParentRight="true"
        android:layout_width="wrap_content"
        android:textSize="20sp"
       android:layout_height="wrap_content" 
       android:text="文本內容"

        />
</RelativeLayout>

MainActivity 代码

public class MainActivity extends Activity {

    private ListView lv;
    private ArrayList<ItemBean> list;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //模拟ListView的数据
        initData();

        lv = (ListView) findViewById(R.id.lv);
        //給ListView設置適配器
        lv.setAdapter(new MyAdapter());

    }

    /**
     * 模拟ListView的数据
     */
    private void initData() {

        list = new ArrayList<ItemBean>();
        for(int i=1;i<=50;i++){
            list.add(new ItemBean("我是标题"+i, R.drawable.ic_launcher));

        }

    }


    class MyAdapter extends BaseAdapter{

        //返回ListView条目的数量
        @Override
        public int getCount() {
            // TODO Auto-generated method stub
            return list.size();
        }

        @Override
        public Object getItem(int position) {
            return list.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        //返回ListView显示的条目
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {

            //..........

            return null;
        }

    }


}

在上面代码中我们写了一个内部类集成BaseAdapter,重写了里面的四个方法.其中最重要的就是 getView() 方法

接下来我们先来看BasaAdapter的三种境界

逗比式

//返回ListView显示的条目
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            //得到布局管理器
            LayoutInflater inflater = LayoutInflater.from(MainActivity.this);
            //..........
            //逗比式
            View view = inflater.inflate(R.layout.item, null);
            TextView tv= (TextView)view.findViewById(R.id.tv_show);
            ImageView iv = (ImageView)view.findViewById(R.id.iv);

            tv.setText(list.get(position).tv);
            iv.setImageResource(list.get(position).imageResourId);

            return view;
        }

效果如图;

这里写图片描述

可以看到listView每一项显示都是正确的,那我们为什么还要说它是逗比式呢.前面我们已经提到过,listView具有缓存机制,在getview() 方法所提供的参数中,有一个 convertView 就是listView为我们提供的一个缓存机制,但我们并没有用到,每次展示的view都是通过 View view = inflater.inflate(R.layout.item, null); 得到的.所以我们称这种方式为逗比式.

接下来我们做一些改进,

普通式

//返回ListView显示的条目
                @Override
                public View getView(int position, View convertView, ViewGroup parent) {
                    //得到布局管理器
                    LayoutInflater inflater = LayoutInflater.from(MainActivity.this);
                    //..........
                    //普通式
                    if(convertView==null){
                        convertView = inflater.inflate(R.layout.item, null);
                    }
                    TextView tv= (TextView)convertView.findViewById(R.id.tv_show);
                    ImageView iv = (ImageView)convertView.findViewById(R.id.iv);

                    tv.setText(list.get(position).tv);
                    iv.setImageResource(list.get(position).imageResourId);


                    return convertView;
                }

普通式其实就是运用listView给我们提供的缓存机制,也就是 convertView ,滑出屏幕的view都会被缓存在这个 convertView 中,当我们再次滑动让他们进入屏幕时,不必再通过 inflater.inflate(R.layout.item, null); 直接使用convertView即可,效果如图

这里写图片描述

其实到此我们还可以对listView做进一步的优化

文艺式

虽然我们已经对view进行了缓存,但是当listView快速滑动式 频繁的fingViewById() 方法也会浪费一些时间,我们可以 使用谷歌推荐的方法使用 ViewHolder 保存findViewById() 操作,避免频繁的 FindViewById(),节省时间,提高效率

//返回ListView显示的条目
                @Override
                public View getView(int position, View convertView, ViewGroup parent) {
                    ViewHolder holder;
                    //得到布局管理器
                    LayoutInflater inflater = LayoutInflater.from(MainActivity.this);
                    //..........
                    //文艺式
                    if(convertView==null){
                        convertView = inflater.inflate(R.layout.item, null);
                         holder = new ViewHolder();
                        holder.tv= (TextView)convertView.findViewById(R.id.tv_show);
                        holder.iv = (ImageView)convertView.findViewById(R.id.iv);

                        convertView.setTag(holder); //讲holder和缓存的view关联起来
                    }else{
                        holder = (ViewHolder) convertView.getTag();
                    }


                    holder.tv.setText(list.get(position).tv);
                    holder.iv .setImageResource(list.get(position).imageResourId);


                    return convertView;
                }

                class ViewHolder{
                    public TextView tv;
                    public ImageView iv;
                }

其实ViewHolder里面就是 item 的控件的引用,只有第一次展示view时才会findViewById(),之后都是从ViewHolder中取,当布局的嵌套层级比较深,比较复杂时,使用此方法会显著提高listView的滑动效率

效果图:

这里写图片描述

文艺式不仅利用了 ListView的缓存,更是通过ViewHolder类实现了显示视图数据的缓存,避免多次findViewById 寻找控件,提高了效率

作为一个有情怀的程序员,这才式最文艺的写法.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值