android中CursorAdapter的bindview调用

huaping100 2010-05-08 09:12:01
由于自己写了一个CustomAdapter来继承CursorAdapter,要重写bindView和newView方法。
当一个ListActivity的启动时,onCreate方法中会setListAdapter为CustomAdapter。
当我打Log的时候发现每一个Item中bindView方法被调用了两次。也就是说,如果你有3个Item在List中,bindView就被调用了6次。
我想问一下CursorAdapter的bindView方法在什么时候被调用,为什么一个Item要调用两次bindView来显示?谢谢大家
这样的情形导致的问题是,有时候在查看List的时候,会发现字体出现明显的抖动,因为第一次刷新显示了所有了Item,但是后面又刷新显示了一次,这是因为每个Item两次调用bindView所致。当然,这种问题只有在数据量比较大的时候会出现延迟显示。不知道哪位高人能不能帮我解决一下。下面是简化的代码:
public class MyNotepad extends ListActivity {

private NotesDbAdapter mDbHelper;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.notes_list);
mDbHelper = new NotesDbAdapter(this);
mDbHelper.open();

fillData();

registerForContextMenu(getListView());
}

private void fillData() {
Cursor notesCursor = mDbHelper.fetchAllNotes();
startManagingCursor(notesCursor);

CustomAdapter adapter = new CustomAdapter (this, notesCursor);
setListAdapter(adapter);
}


final class CustomAdapter extends CursorAdapter{

public CustomAdapter (Context context, Cursor c) {
super(context, c);
// TODO Auto-generated constructor stub
}


@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
Log.i("huaping", "newView");
LayoutInflater li = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
return li.inflate(R.layout.notes_row, parent, false);
}


@Override
public void bindView(View view, Context context, Cursor cursor) {
// TODO Auto-generated method stub
Log.i("huaping", "bindView");
String title = cursor.getString(KEY_TITLE);
final TextView views = (TextView) view.findViewById(R.id.text1);
views.setText(title);
}
}

}
...全文
17227 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
songfantasy 2012-07-16
  • 打赏
  • 举报
回复
/**
* @see android.widget.ListAdapter#getView(int, View, ViewGroup)
*/
public View getView(int position, View convertView, ViewGroup parent) {
if (!mDataValid) {
throw new IllegalStateException("this should only be called when the cursor is valid");
}
if (!mCursor.moveToPosition(position)) {
throw new IllegalStateException("couldn't move cursor to position " + position);
}
View v;
if (convertView == null) {
v = newView(mContext, mCursor, parent);
} else {
v = convertView;
}
bindView(v, mContext, mCursor);
return v;
}

源码很清晰。。做了更多的工作。省去了很多自己写的代码
wangzhongyan726 2011-10-17
  • 打赏
  • 举报
回复
学习了
Alen_bj2010 2011-04-15
  • 打赏
  • 举报
回复
在newView方法中,判断一下当前是否有View存在,如果存在就调用存在的View。就不会出现楼主说的结果了
ReV_Fycd 2011-04-12
  • 打赏
  • 举报
回复
看这里:
http://stackoverflow.com/questions/3535074/getview-vs-bindview-in-a-custom-cursoradapter

或者去看android的CustomAdapter的源码.
CustomAdapter覆盖了BaseAdapter的getView方法,并在里面调用了newView()和bindView().所以你就知道这三个方法的调用关系了吧。

adapter的机制和list的机制有关,其实,无论你实际数据项有多少,显示在屏幕上的只有固定个数的item(取决于list的高或宽)。
在list滑动时,判断是否有Item已经滑出屏幕,滑出去的item被释放掉,加入新的item并显示。每次加入新的item就要调用getView()方法了。
打log的话,你会看到,只要你滑动的距离超过一个item项的高度,就会调用一次getView()
shybirdshy 2011-03-14
  • 打赏
  • 举报
回复
高手们说说adapter与这2个函数的调用过程吧!
number_pig 2010-09-21
  • 打赏
  • 举报
回复
bindView是google自己写的方法,就算对屏幕进行拖动动作都会不停的执行这个方法。你把对数据库的执行放在这个方法里明显会拖慢系统速度。
你可以在bindView里加段log,然后你轻轻拖动一下屏幕,你会发现你的Log简直多的可以用刷屏来形容,而你对数据库也是同样以刷屏般的频率执行着!
所以你要做的就是改变代码结构,将对数据库的操作放到别处,用一次性处理的方法也好还是什么其他方法,总之这个bindView方法中绝对不要放一些“重量级“动作。
Appoule 2010-05-18
  • 打赏
  • 举报
回复
listactivity中的每个item都是一个view, 是view就要牵扯到layout了,那么这些view是怎么根据adapter生成的呢?1,newview生成新的view并返回,2,新生成的view在bindview中和数据bind. 就说这么多了,自己去搜搜看吧。
关键字:Holder,listview.
zd7451676 2010-05-18
  • 打赏
  • 举报
回复
你试试在public void onResume(){
super.onResume();
fillData();
} 处理下看看,因该可以提高点速度
vclongking 2010-05-09
  • 打赏
  • 举报
回复
没具体重写过这个东西 也不太明白
关注 学习
mayonglong 2010-05-08
  • 打赏
  • 举报
回复
新手帮顶~~~~

80,354

社区成员

发帖
与我相关
我的任务
社区描述
移动平台 Android
androidandroid-studioandroidx 技术论坛(原bbs)
社区管理员
  • Android
  • yechaoa
  • 失落夏天
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧