Adapter是什么

An Adapter object acts as a bridge between an AdapterView and the underlying data for that view. The Adapter provides access to the data items. The Adapter is also responsible for making a View for each item in the data set.
翻译过来,简单理解就是adapter是view和数据的桥梁。在一个ListView或者GridView中,你不可能手动给每一个格子都新建一个view,所以这时候就需要Adapter的帮忙,它会帮你自动绘制view并且填充数据。

1、ArrayAdapter

adapter在安卓中分为ArrayAdapter和baseAdapter;

其中简单的ArrayAdapter主要用于简单的文本字符串的实现,如ListView,SpinnerView

首先是我们必须清楚实现的步骤:
1、创建我们所需要的承载视图:Listview
2、创建数据源List
3、创建适配器并绑定数据源adapter

以下是最简单一个实例

1、界面代码

也就是创建我们所需要的承载视图


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

只需要一ListView即可。

2、建立字符串数组资源:

也就是创建数据源

在values里新建一个arrays.xml在<resources></resources>之间输入:


<string-array name="myarray">
<item>语文</item>
<item>数学</item>
<item>英语</item>
<item>物理</item>
<item>化学</item>
<item>生物</item>
</string-array>

 3、在代码中实现:

创建适配器并绑定数据源


//从资源文件获取要显示的数据
String[] strs = this.getResources().getStringArray(R.array.myarray);
//创建ArrayAdapter
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_expandable_list_item_1,strs);
//获取ListView对象,通过调用setAdapter方法为ListView设置Adapter设置适配器
ListView list_test = (ListView) findViewById(R.id.ListView);
list_test.setAdapter(adapter);

4、运行的效果:

二、SimpleAdapter

官方定义:

An easy adapter to map static data to views defined in an XML file.
一个简单的适配器,将静态数据映射到一个XML文件中定义的视图。

数据适配器的使用步骤:
1、新建数据适配器
2、添加数据源到适配器
3、视图加载适配器
首先要了解新建SimpleAdapter涉及到的参数:
构造函数的参数列表及含义:

  • context: 上下文
  • data: 数据源, 类型为Map组成的List集合,每一个Map对应ListView中的一个Item,Map中的所有String类型的key组成的一个字符串数组就是参数from,key的作用就是与item关联起来。
  • resource: item的布局文件,其中至少要有参数to数组中的所有视图
  • from: 将被添加到与每个Item相关联的映射的列名称列表,data参数中Map的String类型键名组成的字符串数组
  • to: 显示与from数组对应数据的视图ID,这些视图都存在于resource指定的Item布局文件中

以下是一个最简单的例子

1、  建立主布局文件


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

2、  建立一个行布局文件

右击Layout——new——Layout resource file 建立新的布局文件。

定义一个行布局,用来描述一行内控件的位置


<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:src="@drawable/a"
android:id="@+id/Image"/>
<TextView
android:layout_weight="2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="文本"
android:id="@+id/Text"
android:layout_gravity="center"
/>
</LinearLayout>

定义一行的布局,放一个ImageView显示图片,放一个TextView显示文本

3、建立字符串数组资源:

在values里新建一个arrays.xml在<resources></resources>之间输入:


 <string-array name="tianqi">
<item>字符1</item>
<item>字符2</item>
<item>字符3</item>
<item>字符4</item>
<item>字符5</item>
</string-array>

4、主要代码:


ListView listView=findViewById(R.id.ListView);
 String[] strs = this.getResources().getStringArray(R.array.tianqi);
 int[] images={R.drawable.a,R.drawable.b,R.drawable.c,R.drawable.d,R.drawable.e};
 List<Map<String,Object>> list_map = new ArrayList<Map<String,Object>>(); //定义一个适配器对象
 for(int i=0;i<strs.length;i++){
     Map<String,Object> items = new HashMap<String, Object>(); //创建一个键值对的Map集合,用来存放文字和字符
     items.put("Text",strs[i] );  //放入文本, 根据下标获取数组
     items.put("Image", images[i]);      //放入图片, 根据下标获取数组
     list_map.add(items);   //把这个存放好数据的Map集合放入到list中,这就完成类数据源的准备工作
 }
 //2、创建适配器
 SimpleAdapter simpleAdapter = new SimpleAdapter(
         SimpleAdapterActivity.this,/*传入一个上下文作为参数*/
         list_map,         /*传入相对应的数据源,这个数据源不仅仅是数据而且还是和界面相耦合的混合体。*/
         R.layout.line, /*设置具体某个items的布局,需要是新的布局,而不是ListView控件的布局*/
         new String[]{"Text","Image"}, /*传入上面定义的键值对的键名称,会自动根据传入的键找到对应的值*/
         new int[]{R.id.Text,R.id.Image});/*传入items布局文件中需要指定传入的控件,这里直接上id即可*/
 //3、为listView加入适配器
 listView.setAdapter(simpleAdapter);

5、运行的效果:

三、BaseAdapter

BaseAdapter,是最基础的Adapter,也就是说,它可以做所有的事情。所以为什么说最实用最常用,原因就在于它的全能性,不会像ArrayAdapter等的封装好的类有那么多局限性,但是这样的话,使用起来自然会更加麻烦一点。

学会BaseAdapter其实只需要掌握四个方法:
getCount, getItem, getItemId, getView

  • getCount : 要绑定的条目的数目,比如格子的数量
  • getItem : 根据一个索引(位置)获得该位置的对象
  • getItemId : 获取条目的id
  • getView : 获取该条目要显示的界面

可以简单的理解为,adapter先从getCount里确定数量,然后循环执行getView方法将条目一个一个绘制出来,所以必须重写的是getCount和getView方法。而getItem和getItemId是调用某些函数才会触发的方法,如果不需要使用可以暂时不修改。以下是一个最简单的实例。

1、  建立主布局界面


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

2、  建立布行布局界面


<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:src="@drawable/a"
android:id="@+id/Image"/>
<TextView
android:layout_weight="2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="文本"
android:id="@+id/Text"
android:layout_gravity="center"
/></LinearLayout>

3、  新建一个实体类,用来构造一行需要的数据


public class Line {
    private String text;
    private int mageId;
    public Line(String text, int mageId) {
        this.text = text;
        this.mageId = mageId;
    }
    public String getText() {
        return text;
    }
    public int getMageId() {
        return mageId;
    }
    public void setText(String text) {
        this.text = text;
    }
    public void setMageId(int mageId) {
        this.mageId = mageId;
    }
}

4、  建立所需的字符串资源


<string-array name="tianqi">
<item>字符1</item>
<item>字符2</item>
<item>字符3</item>
<item>字符4</item>
<item>字符5</item>
</string-array>

5、  新建一个自定义的adapter

继承自BaseAdapter,并且实现四个抽象方法,其中最主要的是getView方法。


public class MyAdapter extends BaseAdapter {
    private List lines;
    private Context context;
    public MyAdapter(List lines, Context context) {
        this.lines = lines;
        this.context = context;
    }

    @Override
    //ListView需要显示的数据数量
    public int getCount() {
        return lines.size();//传过来的list的长度
    }

    @Override
    //指定的索引对应的数据项
    public Object getItem(int position) {
        return lines.get(position);
    }

    @Override
    //指定的索引对应的数据项ID
    public long getItemId(int position) {
        return position;
    }

    @Override
    //返回每一项的显示内容
    public View getView(int position, View convertView, ViewGroup parent) {

        LayoutInflater layoutInflater = LayoutInflater.from(context);
        if(convertView == null) {
            convertView = layoutInflater.inflate(R.layout.line, null);
        }
            ImageView imageView=convertView.findViewById(R.id.iv);
            TextView textView=convertView.findViewById(R.id.Text);
            Line line=lines.get(position);
            imageView.setImageResource(line.getImg());
            textView.setText(line.getText());
            return convertView;
    }
}

6、  主要代码


ArrayList<Line> lines=new ArrayList<>();    //定义一个list用来存放数据
String[] strs = this.getResources().getStringArray(R.array.tianqi); //从资源文件中读取字符串到strs数组
int[] images={R.drawable.a,R.drawable.b,R.drawable.c,R.drawable.d,R.drawable.e};//从资源文件中读取字图片的ID到整形数组
for (int i = 0; i <strs.length ; i++) {  //利用循环将数组的内容写到list里
    lines.add(new Line(strs[i],images[i]));
}
//调用自定义的数据适配器,将list和上下文传入
MyAdapter myAdapter=new MyAdapter(lines,BaseAdapterActivity.this);
listView.setAdapter(myAdapter);//把数据填充到listView

7、  最后运行的效果


学习永不止步