不管是android还是iOS,列表视图应该是最复杂的控件了。android中的listview从命名能够看出是个一维数组,而iOS中的tableview则是二维数组。但事实上须要注意的地方是差点儿相同的。都是重用机制。这是考量你对listview是否能掌握的最好的方法。

常见的listview的初始化以及设置适配器的代码例如以下:

ListView listView;
MyAdapter listAdapter;
ArrayList<String> listString;
listView = (ListView)this.findViewById(R.id.listview);
listString = new ArrayList<String>();
for(int i = 0 ; i < 100 ; i++)
{
listString.add(Integer.toString(i));
}
listAdapter = new MyAdapter(this);
listView.setAdapter(listAdapter);
} class MyAdapter extends BaseAdapter{ Context mContext;
LinearLayout linearLayout = null;
LayoutInflater inflater; public MyAdapter(Context context) {
// TODO Auto-generated constructor stub
mContext = context;
inflater = LayoutInflater.from(mContext);
} @Override
public int getCount() {
// TODO Auto-generated method stub
return listString.size();
} @Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return listString.get(arg0);
} @Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
public final class ViewHolder{
public ImageView img;
public TextView title;
public TextView info;
public Button viewBtn;
} public class MyAdapter extends BaseAdapter{ private LayoutInflater mInflater; public MyAdapter(Context context){
this.mInflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return mData.size();
} @Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return null;
} @Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return 0;
} @Override
public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder = null;
if (convertView == null) { holder=new ViewHolder(); convertView = mInflater.inflate(R.layout.vlist2, null);
holder.img = (ImageView)convertView.findViewById(R.id.img);
holder.title = (TextView)convertView.findViewById(R.id.title);
holder.info = (TextView)convertView.findViewById(R.id.info);
holder.viewBtn = (Button)convertView.findViewById(R.id.view_btn);
convertView.setTag(holder); }else { holder = (ViewHolder)convertView.getTag();
} holder.img.setBackgroundResource((Integer)mData.get(position).get("img"));
holder.title.setText((String)mData.get(position).get("title"));
holder.info.setText((String)mData.get(position).get("info")); holder.viewBtn.setOnClickListener(new View.OnClickListener() { @Override
public void onClick(View v) {
showInfo();
}
}); return convertView;
} }

当中setAdapter是主要用来设置数据的。我们不防看一下ListView(源代码在此)的setAdapter源代码

@Override
public void setAdapter(ListAdapter adapter) {
if (null != mAdapter) {
mAdapter.unregisterDataSetObserver(mDataSetObserver);
} resetList();
mRecycler.clear(); if (mHeaderViewInfos.size() > 0|| mFooterViewInfos.size() > 0) {
mAdapter = new HeaderViewListAdapter(mHeaderViewInfos, mFooterViewInfos, adapter);
} else {
mAdapter = adapter;
} mOldSelectedPosition = INVALID_POSITION;
mOldSelectedRowId = INVALID_ROW_ID;
if (mAdapter != null) {
mAreAllItemsSelectable = mAdapter.areAllItemsEnabled();
mOldItemCount = mItemCount;
mItemCount = mAdapter.getCount();
checkFocus(); mDataSetObserver = new AdapterDataSetObserver();
mAdapter.registerDataSetObserver(mDataSetObserver); mRecycler.setViewTypeCount(mAdapter.getViewTypeCount()); int position;
if (mStackFromBottom) {
position = lookForSelectablePosition(mItemCount - 1, false);
} else {
position = lookForSelectablePosition(0, true);
}
setSelectedPositionInt(position);
setNextSelectedPositionInt(position); if (mItemCount == 0) {
// Nothing selected
checkSelectionChanged();
} } else {
mAreAllItemsSelectable = true;
checkFocus();
// Nothing selected
checkSelectionChanged();
} if (mCheckStates != null) {
mCheckStates.clear();
} requestLayout();
}

从以上代码能够看出其分为两步,第一步是当前adapter不为空的话。先清空本地adapter数据。然后是设置新的数据到listview。

当中里面有个重要的类

AdapterDataSetObserver

是用来存储数据的,我们看一下里面的代码,有个成员变量

mDataSetObserver
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">就是这个对象申明在listview的父类AbsListView(<a target=_blank href="http://grepcode.com/file_/repository.grepcode.com/java/ext/com.google.android/android/2.2_r1.1/android/widget/AbsListView.java/?v=source">源代码在此</a>)中</span>

那么这个AdapterDataSetObserver到底是个什么东西呢,我们还是到AbsListView的父类AdapterView(源代码在此)中一探到底吧。

class AdapterDataSetObserver extends DataSetObserver {

        private Parcelable mInstanceState = null;

        @Override
public void onChanged() {
mDataChanged = true;
mOldItemCount = mItemCount;
mItemCount = getAdapter().getCount(); // Detect the case where a cursor that was previously invalidated has
// been repopulated with new data.
if (AdapterView.this.getAdapter().hasStableIds() && mInstanceState != null
&& mOldItemCount == 0 && mItemCount > 0) {
AdapterView.this.onRestoreInstanceState(mInstanceState);
mInstanceState = null;
} else {
rememberSyncState();
}
checkFocus();
requestLayout();
} @Override
public void onInvalidated() {
mDataChanged = true; if (AdapterView.this.getAdapter().hasStableIds()) {
// Remember the current state for the case where our hosting activity is being
// stopped and later restarted
mInstanceState = AdapterView.this.onSaveInstanceState();
} // Data is invalid so we should reset our state
mOldItemCount = mItemCount;
mItemCount = 0;
mSelectedPosition = INVALID_POSITION;
mSelectedRowId = INVALID_ROW_ID;
mNextSelectedPosition = INVALID_POSITION;
mNextSelectedRowId = INVALID_ROW_ID;
mNeedSync = false;
checkSelectionChanged(); checkFocus();
requestLayout();
} public void clearSavedState() {
mInstanceState = null;
}
}

从以上代码能够看出,这个类事实上是继承自DataSetObserver(源代码在此)。

使用的是观察者模式,用于listview的数据处理。

这是一个抽象类,不多说了。

未完待续。

。。

最新文章

  1. 如何在移动设备上调试html5开发的网页
  2. linux test 命令使用
  3. angularjs compile和link
  4. kbengine里如何使用git快速下载项目?
  5. windows一个目录下最大文件数目
  6. RabbitMQ基本概念和使用
  7. iOS单元测试(作用及入门提升)
  8. 一次触摸,Android到底干了啥
  9. Centos6.4三种更改hostname的方法之间的对比
  10. R语言学习——矩阵
  11. Word 2017 快捷键
  12. 无线渗透wpa加密路由器
  13. Android多国语言的value文件夹命名方式
  14. Android-上下文菜单Menu
  15. 推荐算法之 slope one 算法
  16. Shell中, 退出整个脚本
  17. Writing your first academic paper
  18. 如何偷懒地用 PHP 搭建一个班级网站
  19. yii2 页面加载警告框
  20. 【HLSDK系列】怎么增加一种新实体

热门文章

  1. [ TJOI 2012 ] 防御
  2. python中os模块中文帮助
  3. PSP需求分析文档
  4. 由DB2分页想到的,关于JDBC ResultSet 处理大数据量
  5. win7 中使用NFS共享
  6. 基于Crypto++的aes 字符串加解密实现
  7. Python学会之后,一般能拿到多少工资?
  8. 40条常见的移动端Web页面问题解决方案
  9. UVA - 11214 Guarding the Chessboard(迭代加深搜索)
  10. radis入门