Android 之 ListView 绑定数据源
在 android 开发中 ListView 是比较常用的组件,它以列表的形式展示具体内容,并且能够根据数据的长度自适应显示。
ListView 列表显示需要的三个元素:
ListView 中用来显示每列数据的 View 。
填充 View 的数据或者图片等。
链接数据与 ListView 的适配器
首先要了解什么是适配器(Adapter)。适配器是一个连接数据和 AdapterView(ListView 就是一个典型的 AdapterView)的桥梁,通过它能有效地实现数据与 AdapterView 的分离设置,使 AdapterView 与数据的绑定更加简便,修改更加方便。
下面介绍几种常用的适配器:
BaseAdapter:通用的基础适配器。
ArrayAdapter:用来绑定一个数组,支持泛型操作。最为简单,只能显示一行数据。
SimpleAdapter:用来绑定在 xml 中定义的控件对应的数据。扩充性较好,可以自定义各种效果。
SimpleCursorAdapter:用来绑定游标得到的数据。可以认为是 SimpleAdapter 对数据库的简单结合,可以方面的把数据库的内容以列表的形式展示出来。
下面分别介绍几种常用绑定数据的方法:
1、最简单的绑定数据方法:通过android:entries
属性绑定数据源
<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"
tools:context="${relativePackage}.${activityClass}" >
<ListView
android:id="@+id/listView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:entries="@array/arrayname" >
</ListView>
</RelativeLayout>
xlm文件配置:res–>values–>array.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="arrayname">
<item>张三</item>
<item>李四</item>
<item>王五</item>
<item>赵六</item>
</string-array>
</resources>
运行结果如图:
2、ArrayAdapter 绑定数组资源
<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"
tools:context="${relativePackage}.${activityClass}" >
<ListView
android:id="@+id/listView1"
android:layout_width="match_parent"
android:layout_height="match_parent">
</ListView>
</RelativeLayout>
下面内容是自定义一个数组绑定到 ListView 上面,当然数组可以是各种资源。下面以字符串数组为例说明:
public class ArrayAdapterActivity extends Activity implements OnItemClickListener {
private ArrayAdapter<String> adapter;
private ListView mListView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_array_adapter);
String[] names = {"测试ArrayAdapter1", "测试ArrayAdapter2", "测试ArrayAdapter3", "测试ArrayAdapter4"};
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, names);
mListView = (ListView)findViewById(R.id.listView1);
mListView.setAdapter(adapter);
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// TODO Auto-generated method stub
Toast.makeText(this, "你点击的是第:" + position + "个", 2000).show();
}
}
运行结果如图:
3、SimpleAdapter 绑定数据相对灵活一些,可以自定义各种样式绑定不同的数据源
<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"
tools:context="${relativePackage}.${activityClass}" >
<ListView
android:id="@+id/listView1"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</ListView>
</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:padding="10dp"
android:gravity="center_vertical"
android:orientation="horizontal" >
<ImageView
android:id="@+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="TextView" />
<ImageView
android:id="@+id/imageView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/arrow_content" />
</LinearLayout>
一下数据源也可以是 xml 文件等数据源,当然也可以是网络请求数据。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_simple_adapter);
SimpleAdapter adapter = new SimpleAdapter(this, getData(), R.layout.list_item,
new String[] {"title", "img"},
new int[] {R.id.textView1, R.id.imageView1});
ListView mListView = (ListView)findViewById(R.id.listView1);
mListView.setAdapter(adapter);
mListView.setOnItemClickListener(this);
}
private List<Map<String, Object>> getData() {
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
Map<String, Object> map = new HashMap<String, Object>();
map.put("title", "测试SimpleAdapter1");
map.put("img", R.drawable.ic_launcher);
list.add(map);
map = new HashMap<String, Object>();
map.put("title", "测试SimpleAdapter2");
map.put("img", R.drawable.ic_launcher);
list.add(map);
map = new HashMap<String, Object>();
map.put("title", "测试SimpleAdapter3");
map.put("img", R.drawable.ic_launcher);
list.add(map);
return list;
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
// TODO Auto-generated method stub
Map<String, Object> map = (Map<String, Object>)parent.getItemAtPosition(position);
Toast.makeText(this, "你点击的是第:" + position + "个 ," + map.get("title"), 2000).show();
}
4、自定义 Adapter,这也是最为灵活的方法,下面仍然用菜单列表为例:
<?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:background="@color/bgMainColor"
android:orientation="vertical" >
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="@dimen/dp20" />
</LinearLayout>
后台代码
public class MeFragment extends Fragment implements OnItemClickListener {
private ListView mListView;
private MenuAdapter menuAdapter;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_me, null);
mListView = (ListView) view.findViewById(R.id.listView);
mListView.setDivider(new ColorDrawable(Color.LTGRAY));
mListView.setDividerHeight(1);
menuAdapter = new MenuAdapter(getActivity(), getDataList());
mListView.setAdapter(menuAdapter);
mListView.setOnItemClickListener(this);
return view;
}
/**
* 获得菜单数据
* @return
*/
public List<MenuBean> getDataList() {
List<MenuBean> menuList = new ArrayList<>();
MenuBean bean = new MenuBean("手机号变更", HelpActivity.class);
menuList.add(bean);
bean = new MenuBean("修改登录密码", HelpActivity.class);
menuList.add(bean);
bean = new MenuBean("设置/修改交易密码", HelpActivity.class);
menuList.add(bean);
bean = new MenuBean("设置/修改支付宝账号", HelpActivity.class);
menuList.add(bean);
bean = new MenuBean("我的钱包", HelpActivity.class);
menuList.add(bean);
return menuList;
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
// TODO Auto-generated method stub
MenuBean item = (MenuBean) parent.getItemAtPosition(position);
Intent intent = new Intent();
intent.setClass(getActivity(), item.getCls());
startActivity(intent);
}
/**
* 菜单栏
* @author mategnfei
*/
public class MenuBean implements Serializable {
private static final long serialVersionUID = 1L;
private Integer icon;
private String title;
private String separator = null;//空-菜单组之间的上下间隔;默认false,没有间隔
private Class<?> cls = null;//点击跳转的Activity
public MenuBean() {
}
public Integer getIcon() {
return icon;
}
public void setIcon(Integer icon) {
this.icon = icon;
}
public MenuBean(Integer icon, String title, String separator, Class<?> cls) {
super();
this.icon = icon;
this.title = title;
this.separator = separator;
this.setCls(cls);
}
public MenuBean(String title, String separator, Class<?> cls) {
super();
this.title = title;
this.separator = separator;
this.setCls(cls);
}
public MenuBean(String title, Class<?> cls) {
super();
this.title = title;
this.setCls(cls);
}
public String getTitle() {
return title;
}
public void setName(String title) {
this.title = title;
}
public String getSeparator() {
return separator;
}
public void setSeparator(String separator) {
this.separator = separator;
}
public Class<?> getCls() {
return cls;
}
public void setCls(Class<?> cls) {
this.cls = cls;
}
}
/**
* 菜单栏适配器
* @author matengfei
*/
public class MenuAdapter extends BaseAdapter {
private ViewHolder holder;
private List<MenuBean> menuList;
private Context context;
private MenuBean bean;
public MenuAdapter(Context context, List<MenuBean> mList) {
this.context = context;
this.menuList = mList;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return menuList.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return menuList.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) {
if(convertView == null) {
holder = new ViewHolder();
convertView = LayoutInflater.from(context).inflate(R.layout.item_menu, null);
holder.ivIcon = (ImageView) convertView.findViewById(R.id.iv_icon);
holder.tvTitle = (TextView)convertView.findViewById(R.id.tv_title);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
bean = menuList.get(position);
if(bean != null) {
if(bean.getSeparator() != null) {
return LayoutInflater.from(context).inflate(R.layout.item_null, null);
}
if (bean.getIcon() == null) {
holder.ivIcon.setVisibility(View.GONE);
} else {
holder.ivIcon.setBackgroundResource(bean.getIcon());
}
holder.tvTitle.setText(bean.getTitle());
}
return convertView;
}
private static class ViewHolder {
ImageView ivIcon;
TextView tvTitle;
}
}
运行结果如图:
(完)