前言
ListView 是Android的重要控件之一,可以提供多行数据的浏览;ListView可以实现复杂的布局;这边先从ListView简单的使用入手;
添加ListView控件
- 在activity_main.xml中添加控件ListView;
<ListView
android:id="@+id/lv_data_shower"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/rl_title"
android:layout_marginTop="@dimen/space_10"
/>
- 在MainActivity.java中获取ListView的实例;
mLVDataShower = (ListView)findViewById(R.id.lv_data_shower);
- 为ListView添加Adapter;
mAdapter = new DataShowerAdapter(getApplicationContext());
mLVDataShower.setAdapter(mAdapter);
- 为ListView设置点击事件监听;
getItem
可以从Adapter中获取一条里绑定的数据对象,前提是Adapter中覆写了getItem
并返回对象;
mLVDataShower.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
ItemBean itemBean = (ItemBean) mAdapter.getItem(position);
itemAlert(itemBean);
}
});
Adapter的实现
Adapter可以用来给ListView提供数据和布局;
- 在res->layout 中创建 data_shower_item.xml文件,用来为ListView每个item提供布局;这里只提供两个TextView;
<?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">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="@dimen/list_item_height">
<TextView
android:id="@+id/tv_sms"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/colorPrimaryDark"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:textSize="@dimen/text_size_15"
/>
<TextView
android:id="@+id/tv_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/colorPrimaryDark"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:textSize="@dimen/text_size_15"
/>
</RelativeLayout>
</LinearLayout>
- 继承
BaseAdapter
,覆写必须要实现的抽象方法;
public class DataShowerAdapter extends BaseAdapter {
@Override
public int getCount() {
return 0;
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
return null;
}
}
- 创建构造方法;将上下文传入;新建数据库helper对象,从数据库中获取要显示的数据;获取LayoutInflater对象,以便稍后获取布局对象;
public DataShowerAdapter(Context context) {
this.mContext = context;
this.mItemsDBHelper = new ItemsDBHelper(this.mContext);
this.mItems = mItemsDBHelper.loadItems();
this.mInflater = LayoutInflater.from(context);
}
- 设置ListVeiw要显示的条数;
@Override
public int getCount() {
return this.mItems.size();
}
- 设置每一条在ListView中的位置;
@Override
public long getItemId(int position) {
return position;
}
- 设置每一条返回的数据对象;
@Override
public Object getItem(int position) {
return this.mItems.get(position);
}
- 设置每一条的布局;
DataShowerHolder
用来缓存每一条中控件,防止不断的new造成的卡顿或OOM;
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
DataShowerHolder holder;
if(convertView == null){
convertView = mInflater.inflate(R.layout.data_shower_item, null);
holder = new DataShowerHolder();
holder.tvSms = (TextView)convertView.findViewById(R.id.tv_sms);
holder.tvNumber = (TextView)convertView.findViewById(R.id.tv_number);
convertView.setTag(holder);//绑定ViewHolder对象
} else {
holder = (DataShowerHolder)convertView.getTag();//取出ViewHolder对象
}
holder.tvSms.setText(mItems.get(position).getSms());
holder.tvNumber.setText(mItems.get(position).getNumber());
return convertView;
}
- 创建内部类
DataShowerHolder
,用来做ListView 的控件缓存;
private class DataShowerHolder {
public TextView tvSms;
public TextView tvNumber;
}
- 现在Adapter看起来是这样子的;
package com.youli.feiyu.fynotification.adapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import com.youli.feiyu.fynotification.R;
import com.youli.feiyu.fynotification.bean.ItemBean;
import com.youli.feiyu.fynotification.utility.ItemsDBHelper;
import java.util.ArrayList;
/**
* Created by Sean on 16/2/23.
*/
public class DataShowerAdapter extends BaseAdapter {
private Context mContext;
private LayoutInflater mInflater;
private ArrayList<ItemBean> mItems;
private ItemsDBHelper mItemsDBHelper;
public DataShowerAdapter(Context context) {
this.mContext = context;
this.mItemsDBHelper = new ItemsDBHelper(this.mContext);
this.mItems = mItemsDBHelper.loadItems();
this.mInflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
return this.mItems.size();
}
@Override
public Object getItem(int position) {
return this.mItems.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
DataShowerHolder holder;
if(convertView == null){
convertView = mInflater.inflate(R.layout.data_shower_item, null);
holder = new DataShowerHolder();
holder.tvSms = (TextView)convertView.findViewById(R.id.tv_sms);
holder.tvNumber = (TextView)convertView.findViewById(R.id.tv_number);
convertView.setTag(holder);//绑定ViewHolder对象
} else {
holder = (DataShowerHolder)convertView.getTag();//取出ViewHolder对象
}
holder.tvSms.setText(mItems.get(position).getSms());
holder.tvNumber.setText(mItems.get(position).getNumber());
return convertView;
}
private class DataShowerHolder {
public TextView tvSms;
public TextView tvNumber;
}
}
ListView刷新数据
如果后来添加/删除/修改了一条数据ListView该如何刷新?
- 添加/删除/修改数据源,然后调用下
notifyDataSetChanged
;
public void deleteItem(ItemBean itemBean) {
mItems.remove(itemBean);
mItemsDBHelper.deleteItem(itemBean);
notifyDataSetChanged();
}
总结
- ListView的显示 ,需要设置好Adapter;
- Adapter是ListView的数据和布局来源;
- 在Adapter中要做好控件的缓存,避免卡顿和OOM;
- 调用Adapter的
notifyDataSetChanged
可以刷新ListView;