什么是数据适配器?
下图展示了数据源、适配器、ListView等数据展示控件之间的关系。我们知道,数据源是各种各样的,而ListView所展示数据的格式则是有一定的要求的。数据适配器正是建立了数据源与ListView之间的适配关系,将数据源转换为ListView能够显示的数据格式,从而将数据的来源与数据的显示进行解耦,降低程序的耦合性。这也体现了Android的适配器模式的使用。对于ListView、GridView等数据展示控件有多种数据适配器,本文讲解最通用的数据适配器——BaseAdapter。
Recycler缓存机制
这些适配器使用相同组件动态绑定数据的方式进行优化。为什么需要优化呢?因为如果我们有大量的数据要显示怎么办?为每个数据创建一个新视图?这不可能,因为内存有限制。实际上Android为你缓存了视图。Android中有个叫做Recycler的构件,下图是它的工作原理:
接口函数
public int getCount()
public Object getItem(int position)
public long getItemId(int position)
public View getView(int position, View convertView, ViewGroup parent)
简略流程图:
public int getCount()
获取我们将要绘制的item数目,这个数目不能大于总item数目,但可以小于总item数目。例如我们adapter管理的item总数有10个,而我们通过getCount()返回的只有6个,那么最终GridView绘制出来的将只有6个。
、
、
public Object getItem(int position)
getItem方法不是在Baseadapter类中被调用的,而是在Adapterview.getItemAtPosition(position) 中被调用的。getItemAtPosition(position) 是在setOnItemClickListener、setOnItemLongClickListener、setOnItemSelectedListener的点击选择处理事件中方便地调用来获取当前行数据的。
、
、
public long getItemId(int position)
该方法的返回值决定第position处的列表项的ID,某些方法有id这个参数,而这个id参数就是取决于getItemId()这个返回值,如:
mRecordLed.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {}
});
、
、
public View getView(int position, View convertView, ViewGroup parent)
通过传入的参数position,加工成我们想要的View并返回,最终供GridView使用。position是指当前dataset的位置,通过getCount和getItem来使用。如果list向下滑动的话那么就是最低端的item的位置,如果是向上滑动的话那就是最上端的item的位置。convertView是指可以重用的视图,即刚刚出队的视图(在上面已经重点讲过)。parent应该就是显示数据的视图(如ListView、GridView等)。
getItem()和getItemId()有什么用呢?我们知道,GridView将View以方格的方式展示出来之后是要与用户交互的(比如点击某张图片),为了更好的相应用户的动作,我们就要用到这两个函数了。
示例
private class flashAdapter extends BaseAdapter {
private Context mContext;
private ArrayList<String> mMode; // String可替换成一个自定义的item对象
private ViewHolder mViewHolder;
public flashAdapter(Context mContext, ArrayList<String> mMode) {
this.mContext = mContext;
this.mMode = mMode;
}
@Override
public int getCount() {
return mMode.size();
}
@Override
public Object getItem(int position) {
return mMode.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (null == convertView) {
// 对ViewHolder的属性进行赋值
LayoutInflater layoutInflater = LayoutInflater.from(mContext);
convertView = layoutInflater.inflate(R.layout.led_item, parent, false);
mViewHolder = new ViewHolder();
mViewHolder.mImageView = (ImageView) convertView.findViewById(R.id.ledImage);
mViewHolder.mTextView = (TextView) convertView.findViewById(R.id.ledMode);
convertView.setTag(mViewHolder);
} else {// 如果缓存池中有对应的view缓存,则直接通过getTag取出viewHolder
mViewHolder = (ViewHolder) convertView.getTag();
}
// 设置控件的数据
mViewHolder.mImageView.setImageResource(R.drawable.record_camera_flash_led);
mViewHolder.mTextView.setText(mMode.get(position));
mViewHolder.mTextView.setTextSize(12);
return convertView;
}
// ViewHolder用于缓存控件
public class ViewHolder {
public ImageView mImageView;
public TextView mTextView;
}
}
参考:
https://www.cnblogs.com/caobotao/p/5061627.html
https://www.cnblogs.com/tjudzj/p/4371326.html