Android_适配器的使用

介绍适配器的使用,从浅到深,一共6步,这6步所用到的xml文件相同,就是下面这两个

<LinearLayout 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"
    tools:context="${relativePackage}.${activityClass}" >

    <ListView
        android:id="@+id/lv"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>
item1中第二个TextView只有在5和6中用到
<?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" >
    <ImageView
        android:id="@+id/item1_iv"
        android:layout_width="70dp"
        android:layout_height="70dp"
        android:layout_gravity="center_vertical"
        android:src="@drawable/h2" />

    <TextView
        android:id="@+id/item1_tv"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:text="ddddddd"
        android:gravity="center" />

    <CheckBox
        android:id="@+id/item1_cb"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical" />

</LinearLayout>

1.简单适配器的使用

package com.example.adapterdemo2;


import android.app.Activity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;

public class MainActivity2 extends Activity {
    ListView lv;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        lv=(ListView) findViewById(R.id.lv);
        MyAdapter ma=new MyAdapter();
        lv.setAdapter(ma);
    }
    class MyAdapter extends BaseAdapter{

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

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

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

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            // TODO Auto-generated method stub
            LayoutInflater                          layoutInflater=MainActivity2.this.getLayoutInflater();
            View view=layoutInflater.inflate(R.layout.item1, parent,false);
            return view;
        }

    }
}

这篇代码实现的功能比较简单,在activity_main.xml文件中创建一个组件ListView,设置相应的id.在MainActivity中findViewByid实例化这个控件.
创建一个子类继承BaseAdapter,实现抽象方法.在getCount()方法中设置条目数量,之后再getView()方法中实现下面的功能(MainActivity中没有以下注释)
这里写图片描述
之后的步骤就是创建子类的对象,然后通过setAdapter();方法将这个对象传进去,详情看代码

2.将集合数据传到条目中的适配器的使用

package com.example.adapterdemo2;

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;

public class MainActivity extends Activity {
    private ListView lv;
    private List<String>datas=new ArrayList<String>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        for(int i=0;i<40;i++){
            datas.add("我是数据------>"+i);
        }
        lv=(ListView) findViewById(R.id.lv);
        MyAdapter ma=new MyAdapter();
        lv.setAdapter(ma);
    }
    class MyAdapter extends BaseAdapter{

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

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

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

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            // TODO Auto-generated method stub
            LayoutInflater layoutInflater=MainActivity.this.getLayoutInflater();
            View view=layoutInflater.inflate(R.layout.item1, parent,false);
            TextView tv=(TextView)view.findViewById(R.id.item1_tv);
            tv.setText(getItem(position));
            return view;
        }
    }
}

和上面的适配器的使用基本一样,有几处需要注意的地方
(1)下面代码红色标注的地方,注意这里并不是activity_main中的组件,而是在上一行view对象中,上一行已经将相应的布局文件转换成View对象,而所加载的TextView就在这个布局中,所以在这里应该特别注意
这里写图片描述
(2)红线标注的方法,返回一个字符串,position是条目的位置,也可以将第二个横线位置,换成datas.get(position),也就是上面方法的返回值
这里写图片描述
3.适配器内部的优化使用(针对View对象)
这个适配器的使用效果和上的适配器使用的效果一样,但是内部进行了优化,使内存的使用的到了优化
getView() 方法会被反复调用很多次,加载不同位置的条目
当ListView初次展开时,getView方法调用多少次?
取决于当前界面展现了多少条目,不展现的条目暂时不加载 ——这就是BaseAdapter的内部优化机制

当上下滚动时,界面展现哪个条目,我们就调用getView方法加载哪一个条目
此时因为 重新调用了该位置的getView,所以会重新inflate一个新的view对象,那么之前我们旧的view对象就成为了垃圾对象 ,造成内存必要的消耗

所以,我们要针对此种情况进行优化 :复用view对象 使用参数converView
假如我们界面 可以展现5个条目 那么总共会有多少个view对象?会有7个,最上面的露一半,最下面的露一半.所以可能有7个
在这篇代码getView方法中有如下代码
这里写图片描述
在标签可以看出converView.hashCode()的值会被反复使用,而上一个适配器的使用converView.hashCode()所打印的完全不同.关于这里的优化问题在另一篇笔记适配器(2)中有介绍

4.适配器内部的优化使用(针对View和TextView对象)
针对View对象造成的内存浪费,在3中已经进行了优化,但是在每次调用getVeiw方法,更新TextView对象tv时,tv都会重新finViewById,而这个方法也会重新创建一个对象,也会造成内存的浪费,(在新版本的手机中这个问题已经在版本中进行了优化,不用开发者考虑,但是我们也需要知道这个原理和方法,主要针对没有进行优化的手机版本),问题和3中所说的问题相似,就不在赘述,只说一下解决方法.
这里写图片描述
我已开始是这么理解的:
这里写图片描述
convertView怎么解决,tv就怎么解决,这样的理解是错了,因为converView是缓存对象,是时刻存在的而TextView的对象tv不是,每次执行这个方法时,tv对象都需要重新创建,而converView不为空时,tv为空,所以既然convertView不会消失,那么就将tv存到converView中,于是就有了开始时候的解决办法了,通过setTag进行存储,getTag进行提取

5.多个TextView对象的适配器的使用
我一开始的理解是如果有两个TextView,是不是可以一个一个的使用,就和上面TextView对象tv一样,只是多了一个,事实是错的,因为convertView的setTag方法只能用一次,getTag也是同样的道理
所以应用java面向对象的思想,一个功能一个类,将多个TextView对象封装到一个类里面,对这个类对象进行操作即可,代码不难,理解思想

6.对CheckBox使用优化的适配器
这里写图片描述

因为convertView对象中没有储存CheckBox的状态,所以就算打上勾条目消失后,勾选状态也就消失了,所以应该想办法,留住相应位置的选中状态,可以用键值对来储存,也就是用Map集合,位置是Key,状态是Value.把CheckBox也封装到类里面(就是5中的 ViewHolder类)
图中红线:将位置存到CheckBox对象cb的Tag里
图中紫线:对cb进行监听(最好不要内名内部类,因为每次都会产生一个新对象)
图中蓝线:根据位置position(Key)取出是否被选中的状态(Value)
图中黄线:取出存储在cb中的位置

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值