Adapter
Adapter是用來幫助顯示資料的中間橋樑,簡單的說就是將各種數據以合適的形式顯示到View上,提供給用戶看。
繼承結構圖
BaseAdapter:抽像類別,實際開發中我們會繼承這個類並且重寫相關方法,用得最多的一個Adapter!
ArrayAdapter:支持泛型操作,最簡單的一個Adapter,只能顯示一行文字
SimpleAdapter:同樣具擴展性的一個Adapter,可以自定義多種效果。
基本的BaseAdapter架構
public class ListAdapter extends BaseAdapter
{
private Context mContext;
private LayoutInflater mInflater;
private List<Object> mItemList;
public ListAdapter(Context context, List< Object> itemList)
{
mContext = context;
mInflater = (LayoutInflater)
context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mItemList = itemList;
}
@Override
public int getCount()
{
//取得 ListView 列表 Item 的數量
return mItemList.size();
}
@Override
public Object getItem(int position)
{
//取得 ListView 列表於 position 位置上的 Item
return mItemList.get(position);
}
@Override
public long getItemId(int position)
{
//取得 ListView 列表於 position 位置上的 Item 的 ID
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
//設定與回傳 convertView 作為顯示在這個 position 位置的 Item 的 View。
View view = mInflater.inflate(R.layout.list_view_item, parent, false);
TextView txtTitle = (TextView) view.findViewById(R.id.title);
TextView txtInfo = (TextView) view.findViewById(R.id.info);
txtTitle.setText(mItemList.get(position).title);
txtInfo.setText(mItemList.get(position).info);
return view;
}
}
由於ListView的每個Item顯示時,都會呼叫一次getView函式,函式中的view都會重新建立一個實例,對於效能會有很大的影響。改善的方法為透過convertView+ViewHolder來實現,ViewHolder為一個靜態類別,使用ViewHolder 的好處是暫存顯示View,加快了UI 的反應速度,使用範例如下:
//先定義一個靜態類別,包含Item的顯示元件
static class ViewHolder
{
public TextView txtTitle;
public TextView txtInfo;
}
//改寫原本的getView內的流程
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(convertView == null)
{
//若無實例,則建立一個新的
holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.list_view_item, parent, false);
holder.txtTitle = (TextView) convertView.findViewById(R.id.title);
holder.txtInfo = (TextView) convertView.findViewById(R.id.info);
convertView.setTag(holder);
} else {
//已產生實例,由convertView取出ViewHolder
holder = (ViewHolder)convertView.getTag();
}
holder.txtTitle.setText(mItemList.get(position).title);
holder.txtInfo.setText(mItemList.get(position).info);
return convertView;
}
由於Adapter的設計方式會影響到ListView的顯示效率,在Android 5.0之後推出了新的元件RecyclerView,其中包含了新的RecyclerView.Adapter,已經將ViewHolder封裝好了,例子如下:
public class MyRecyclerViewAdapter extends
RecyclerView.Adapter<MyRecyclerViewAdapter.MyViewHolder> {
private LayoutInflater mInflater;
private Context mContext;
private List<Object> mItemList;
public MyRecyclerViewAdapter (Context context, List<Object> itemList) {
mContext = context;
mInflater = LayoutInflater.from(context);
mItemList = itemList;
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
return new MyViewHolder(mLayoutInflater.inflate
(R.layout.list_view_item, parent, false));
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.txtTitle.setText(mItemList.get(position).title);
holder.txtInfo.setText(mItemList.get(position).info);
}
@Override
public int getItemCount() {
return mTitles == null ? 0 : mTitles.size();
}
public static class MyViewHolder extends RecyclerView.ViewHolder {
TextView txtTitle;
TextView txtInfo;
MyViewHolder (View view) {
super(view);
txtTitle = (TextView) view.findViewById(R.id.title);
txtInfo = (TextView) view.findViewById(R.id.info);
}
}
ListView的數據更新
使用notifyDataSetChanged()方法