Android_适配器(adapter)之SimpleAdapter
概述
SimpleAdapter是一种 简单的适配器,将静态数据映射到布局xml对应的视图上。它也是BaseAdapter的子类。
SimpleAdapter数据映射的组件有3类(从官网api或SimpleAdapter源码中的bindView方法中都能看出来):Checkable(e.g. CheckBox), TextView, ImageView。
下面的例子中就包含了这3类
构造说明
SimpleAdapter只有一个构造方法:
SimpleAdapter(Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to)
context:上下文
data:数据源,一个包含Map的数据集合
resource:item的布局文件
from:数据来源的key的数组,与data的Map里的key对应
to: from中的每一项数据源 对应到的 item布局中对应组件的 id。
四个参数的关系及表明了这种数据映射到布局的关系(如下绘制的简单示意图):data是数据源,包含所有数据,data中的每一项 是一个map;from是数据源中map中的key数组;to是item布局要填充的组件id的数组(这里的组件只能是上面提到的3种)。
通过SimpleAdapter,数据被映射到对应的组件中,显示出来。下一项具体示例中有更好的体现
具体示例说明
下面具体示例,很清晰的可以看出SimpleAdapter数据映射过程和效果。
先看下示例的效果图:
下面是具体的代码
activity布局:simple_adapter_act.xml
这里仅定义了一个ListView用于显示
<?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"> <ListView android:id="@+id/simple_adapter_lv" android:layout_width="match_parent" android:layout_height="match_parent" /> </RelativeLayout>
文本资源:
Strings: <array name="anime_name"> <item>海贼王</item> <item>进击的巨人</item> <item>火影忍者</item> <item>斩赤红之瞳</item> <item>秦时明月</item> <item>西游记</item> <item>葫芦娃</item> </array> <array name="anime_author"> <item>尾田荣一郎</item> <item>谏山创</item> <item>岸本齐史</item> <item>タカヒロ</item> <item>玄机科技</item> <item>央视</item> <item>上海美术电影</item> </array> Colors:/赤橙黄绿青蓝紫 <color name="love_red">#FF0000</color> <color name="love_orange">#FF7F00</color> <color name="love_yellow">#FFFF00</color> <color name="love_green">#00FF00</color> <color name="love_blue_green">#00FFFF</color> <color name="love_blue">#0000FF</color> <color name="love_purple">#8B00FF</color>
SimpleAdapter的resouce布局,及item layout: sasimple_adapter_item.xml
这里定义了5个组件,SimpleAdapter会将这些填充数据,2个TextView 2个ImageView 1个CheckBox.
<?xml version="1.0" encoding="utf-8"?> <!--android:descendantFocusability 避免CheckBox抢占焦点添加--> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:descendantFocusability="blocksDescendants" android:layout_width="match_parent" android:layout_height="70dp"> <ImageView android:id="@+id/anime_cover_img" android:layout_alignParentLeft="true" android:layout_centerVertical="true" android:layout_marginLeft="10dp" android:layout_width="60dp" android:scaleType="fitCenter" android:layout_height="60dp" /> <LinearLayout android:layout_toRightOf="@id/anime_cover_img" android:layout_width="150dp" android:layout_height="match_parent" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:orientation="vertical" > <TextView android:id="@+id/anime_name_txt" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center_vertical" android:textStyle="bold" android:layout_weight="1" /> <TextView android:id="@+id/anime_author_txt" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center_vertical" android:textStyle="italic" android:layout_weight="1"/> </LinearLayout> <ImageView android:id="@+id/anime_likecolor_img" android:layout_toLeftOf="@id/anime_checkbox" android:layout_width="60dp" android:layout_height="60dp" android:layout_centerVertical="true" android:layout_marginRight="10dp" /> <CheckBox android:id="@+id/anime_checkbox" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_centerVertical="true" /> </RelativeLayout>
最终的,SimpleAdapter的使用:SimpleAdapterActivity.java
package com.flx.adaptertest.simpleadapter; import android.app.Activity; import android.content.res.Resources; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.AdapterView; import android.widget.CheckBox; import android.widget.ListView; import android.widget.SimpleAdapter; import com.flx.adaptertest.R; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class SimpleAdapterActivity extends Activity { private static final String TAG = "SimpleAdapterActivity"; private static final String ANIME_NAME = "anime_name"; private static final String ANIME_AUTHOR = "anime_author"; private static final String ANIME_COVERIMG = "anime_coverimg"; private static final String ANIME_LIKECOLOR = "anime_likecolor"; private static final String ANIME_CHECKBOX = "anime_checkbox"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate( savedInstanceState ); setContentView( R.layout.simple_adapter_act ); ListView listView = findViewById( R.id.simple_adapter_lv ); listView.setOnItemClickListener( new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Log.d( TAG, "onItemClick: position="+ position + ";text=" + parent.getItemAtPosition(position).toString() +";CheckBox changed="+((CheckBox)view.findViewById(R.id.anime_checkbox)).isChecked()); } } ); List<Map<String, Object>> datas = new ArrayList<>(); Resources resources = this.getResources(); String[] anime_names = resources.getStringArray( R.array.anime_name ); String[] anime_authors = resources.getStringArray( R.array.anime_author ); int[] coverImgs = {R.drawable.hzw1, R.drawable.jjdjr1, R.drawable.hyrz1, R.drawable.zchzt1, R.drawable.qsmy1, R.drawable.xyj1, R.drawable.hlw1}; int[] senvenColors = {R.color.love_red, R.color.love_orange, R.color.love_yellow,R.color.love_green, R.color.love_blue_green, R.color.love_blue,R.color.love_purple}; boolean[] anime_checkbox = {true, true, false, false, true, false, true}; for (int i = 0; i < anime_names.length; i++) { Map<String, Object> map = new HashMap<>(); map.put(ANIME_COVERIMG, coverImgs[i]); map.put(ANIME_NAME, anime_names[i]); map.put(ANIME_AUTHOR, anime_authors[i]); map.put(ANIME_LIKECOLOR, senvenColors[i]); map.put(ANIME_CHECKBOX, anime_checkbox[i]); datas.add(map); } String[] from = {ANIME_COVERIMG, ANIME_NAME, ANIME_AUTHOR, ANIME_LIKECOLOR,ANIME_CHECKBOX}; int[] to = {R.id.anime_cover_img, R.id.anime_name_txt, R.id.anime_author_txt, R.id.anime_likecolor_img, R.id.anime_checkbox}; SimpleAdapter simpleAdapter = new SimpleAdapter( this, datas, R.layout.simple_adapter_item, from, to ); listView.setAdapter(simpleAdapter); } }
看下点击效果:
点击第一项看到log
2019-11-25 14:27:06.254 9363-9363/com.flx.adaptertest D/SimpleAdapterActivity: onItemClick: position=0;text={anime_name=海贼王, anime_likecolor=2131034168, anime_checkbox=true, anime_author=尾田荣一郎, anime_coverimg=2131165272};CheckBox changed=true
点击第一项中的checkbox,去掉勾选后,再点击第一项看到的log
2019-11-25 14:29:02.631 9363-9363/com.flx.adaptertest D/SimpleAdapterActivity: onItemClick: position=0;text={anime_name=海贼王, anime_likecolor=2131034168, anime_checkbox=true, anime_author=尾田荣一郎, anime_coverimg=2131165272};CheckBox changed=false
注意到CheckBox值的变化了吗,整个item中看到的anime_checkbox值并没有变化。个人理解是 将静态数据映射到视图,绑定到视图时已经值已经确定了,点击checkbox,视图数据并没有刷新,所以可以通过view获取checkbox获取状态。