这几天学习了一下安卓的gridview和listview,其中难点感觉在适配器上,经过学习,感觉掌握了一些规律,今天打完球洗个澡,感觉状态刚刚好,总结一下作为我以后的笔记,如有不对,请指正。
适配器:我认为适配器就是一个类,在实例化适配器的过程中,将复杂的数据通过适配器有条理的在view中显示出来。

一、arrayadapter
这个适配器只能最简单只能显示一行字,一般用于spinner组件。数据源也很简单一般是string[]。上代码:

protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    setContentView(R.layout.ano2);
    s2=new Spinner(this);
    s2=(Spinner)findViewById(R.id.spinner1);
    s2.setOnItemSelectedListener(this);//为点击每一项加监听
    ArrayAdapter<CharSequence> array;
    array=ArrayAdapter.createFromResource(this, R.array.xl, android.R.layout.simple_dropdown_item_1line);//实例化一个构造器,参数意义:context,数据源,布局方式(这里我采用安卓默认布局)
array.setDropDownViewResource(android.R.layout.simple_dropdown_item_1line);//spinner组件(下拉菜单)的显示方式,采用默认布局
    s2.setAdapter(array);//将适配器与实例化的spinner组件绑定,从而将数据有规律的显示在spinner组件上。显示的数据每一行都是一个Textview,是一个组件。
}

数据源存放:

<string-array name="xl">
        <item>小花</item>
        <item>小明</item>
        <item>小翠</item>
    </string-array>

二、simpleadapter
说实话,这个适配器是我最喜欢的,感觉用起来非常舒服, 而且自由度挺高的(除了自定义适配器),可用于listview和gridview,重点是要记住实例化适配器时几个参数的意义。数据源为list。
这里以listview为例

public class Another1 extends Activity{
       private ListView lv;
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.another1);
        lv=(ListView)findViewById(R.id.listView1);

        //重点
        SimpleAdapter sa=new SimpleAdapter(this, getdata(), R.layout.another1one, new String[]{"img","t1","t2"}, new int[]{R.id.img,R.id.t1,R.id.t2});//参数意义:context,数据源,单个项布局, map里面填充K:V对时的K值,单个项布局时每个组件的位置
        lv.setAdapter(sa);
    }
//数据源,这里使用list里面包装map的形式,   
private List<Map<String, Object>> getdata() {
        // TODO Auto-generated method stub
    List<Map<String, Object>> l=new ArrayList<Map<String,Object>>();//实例化list

//不要问我为什么不用循环,因为I’m a loser
    Map<String, Object> m1=new HashMap<String, Object>();//实例化map
    m1.put("img", R.drawable.ic_launcher);//以k:v形式填充数据
    m1.put("t1", "loser");
    m1.put("t2", "you are");

    Map<String, Object> m2=new HashMap<String, Object>();
    m2.put("img", R.drawable.ic_launcher);
    m2.put("t1", "loser");
    m2.put("t2", "you are");

    Map<String, Object> m3=new HashMap<String, Object>();
    m3.put("img", R.drawable.ic_launcher);
    m3.put("t1", "loser");
    m3.put("t2", "you are");

    Map<String, Object> m4=new HashMap<String, Object>();
    m4.put("img", R.drawable.ic_launcher);
    m4.put("t1", "loser");
    m4.put("t2", "you are");

    Map<String, Object> m5=new HashMap<String, Object>();
    m5.put("img", R.drawable.ic_launcher);
    m5.put("t1", "loser");
    m5.put("t2", "you are");

    l.add(m1);//把map填充到list里
    l.add(m2);
    l.add(m3);
    l.add(m4);
    l.add(m5);
        return l;//返回填充好的数据源
    }
}

单个项的布局:

<?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" >

    <ImageView
        android:id="@+id/img"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_launcher" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="46dp"
        android:orientation="vertical" >

        <TextView
            android:id="@+id/t1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="TextView" />

        <TextView
            android:id="@+id/t2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="TextView"
            android:gravity="center" />

    </LinearLayout>

</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" >

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

</LinearLayout>

感悟:这个用起来非常舒服,不考虑别的,只要加参数就可以了。

三、自定义适配器(基于baseadapter)
这个适配器灵活性最大,继承baseadapter类之后需要重写四个方法, 重点是getView方法,等下会介绍。我的感觉时能用simpleadapter不用自定义的,不好玩

public class Another6 extends Activity{
    private GridView gv;
 @Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    setContentView(R.layout.another6);
    gv=(GridView)findViewById(R.id.gridView6);
    liu l=new liu(this);//实例化适配器
    gv.setAdapter(l);
}

}
class liu extends BaseAdapter{//外部类要找到上下文,需要重写构造方法引入Another6
    private LayoutInflater lf=null;
    public liu(Another6 a6){
        this.lf=LayoutInflater.from(a6);
    }
    //获取数据的长度,即有几个数据项
    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return getdata().size();
    }

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

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

//重点,获取view组件的方法
    @Override
    public View getView(int arg0, View arg1, ViewGroup arg2) {//参数意义:position,convertview,父容器
        // TODO Auto-generated method stub
        viewholder2 vh;
        if (arg1==null) {//将布局中的包含关系在这里实例化
            arg1=lf.inflate(R.layout.another6one, null);
            //将布局文件用填充器实例化 ,作用类似于findviewbyid
            vh=new viewholder2();
            vh.iv=(TextView)arg1.findViewById(R.id.textView1);
            arg1.setTag(vh);//将每个组件实例化后以标签(tag)形式放到arg1中
        } else {
            vh=(viewholder2)arg1.getTag();//从tag中取出封转好的对象
        }
        vh.iv.setText((String)getdata().get(arg0).get("tit"));//将数据传给实例化的组件
        return arg1;
    }
//获得数据源的方法,与simpleadapter的一样
    private List<Map<String, Object>> getdata(){//采用simpleadapter中数据的存放方式
        List<Map<String, Object>> l=new ArrayList<Map<String,Object>>();
        Map<String, Object> m=new HashMap<String, Object>();
        for (int i = 0; i <15; i++) {
            m.put("tit", "刘六六");
            l.add(m);
        }
        return l;
    }
    class viewholder2{//用来存放组件地址,方便以后赋值不用再查找
        TextView iv;
    }
    }

单项布局:

<?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="match_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="14dp"
        android:text="TextView" />

</RelativeLayout>

绑定布局:

<?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" >

    <GridView
        android:id="@+id/gridView6"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:numColumns="3" >
    </GridView>

</LinearLayout>

当然自定义适配器还是有好处的,两个优化:
1、对于view的重复利用
利用convertview,只创建屏幕可见的加一个,这个原理类似于电梯原理(可见的阶梯12个,还有12个不可见,阶梯循环利用)这样的话,要是有1亿个view就只加载可见的,解决方法:

if (arg1==null) {//将布局文件在这里实例化
            arg1=lf.inflate(R.layout.another6one, null);
            //当没有时才加载
            vh=new viewholder2();
            vh.iv=(TextView)arg1.findViewById(R.id.textView1);
            arg1.setTag(vh);
        }

2、一个单项布局文件里可能有多个组件,每次为组件赋值就要查找一次,太麻烦了,我们可以先把组件实例化,放到实例化的布局文件里,每次只要取出赋值即可。解决方案:

class viewholder2{//用来存放组件地址,方便以后赋值不用再查找
        TextView iv;
    }
vh=new viewholder2();
            vh.iv=(TextView)arg1.findViewById(R.id.textView1);
            arg1.setTag(vh);//将每个组件实例化后以标签(tag)形式放到arg1中
        } else {
            vh=(viewholder2)arg1.getTag();//从tag中取出封转好的对象
        }
        vh.iv.setText((String)getdata().get(arg0).get("tit"));//将数据传给实例化的组件