由于自己写了一个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);
}
}}
当一个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);
}
}}
关键字:Holder,listview.
super.onResume();
fillData();
} 处理下看看,因该可以提高点速度
你可以在bindView里加段log,然后你轻轻拖动一下屏幕,你会发现你的Log简直多的可以用刷屏来形容,而你对数据库也是同样以刷屏般的频率执行着!
所以你要做的就是改变代码结构,将对数据库的操作放到别处,用一次性处理的方法也好还是什么其他方法,总之这个bindView方法中绝对不要放一些“重量级“动作。
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()
* @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;
}源码很清晰。。做了更多的工作。省去了很多自己写的代码