I've got a custom ListCursorAdapter extending from SimpleCursorAdapter. In the list's rows, there are two TextFields and one CheckBox.
When scrolling fast, the behaviour of the checkboxes is weird; the selected ones "hop" from on row to another, e.g. if the third row contains a selected checkbox and I'm scrolling fast, suddenly another row is selected.
I found out that sometimes, the findViewById in my bindView-method returns null:
@Override
public final View newView(final Context context, final Cursor cursor, final ViewGroup parent) {
final LayoutInflater inflater = LayoutInflater.from(context);
final View v = inflater.inflate(mLayout, null);
return v;
}
@Override
public final void bindView(final View v, final Context context, final Cursor cursor) {
int haltestelleCol = cursor.getColumnIndex("haltestelle");
int nameCol = cursor.getColumnIndex("name");
int linieCol = cursor.getColumnIndex("linie");
int startseiteCol = cursor.getColumnIndex("startseite");
int idCol = cursor.getColumnIndex("_id");
final String haltestelleString = cursor.getString(haltestelleCol);
final String nameString = cursor.getString(nameCol);
// Next set the haltestelle of the entry.
final TextView haltestelle = (TextView) v.findViewById(R.id.favorite_haltestelle);
if (haltestelle != null) {
if (nameString != null && !nameString.equals("")) {
haltestelle.setText(nameString);
} else {
haltestelle.setText(haltestelleString);
}
}
// next set the linie
final TextView linie = (TextView) v.findViewById(R.id.favorite_linie);
if (linie != null) {
linie.setText(cursor.getString(linieCol));
}
// set startseite-flag or not
final int startseite = cursor.getInt(startseiteCol);
final CheckBox startseiteCheckbox = (CheckBox) v.findViewById(R.id.favorite_startseite);
final int id = cursor.getInt(idCol);
if (startseiteCheckbox != null) {
if (startseite > 0) {
startseiteCheckbox.setChecked(true);
}
checkboxes.add(startseiteCheckbox);
startseiteCheckbox.setId(id);
startseiteCheckbox.setOnClickListener(new StartseiteClickListener(cursor.getPosition()));
} else {
System.out.println();
}
}
i.e. I'm at the "System.out.println()"-part. Can someone tell my why I've got this behaviour? And is it correct that the bindView-method is called often? Shouldn't it be called only once per row?
Thanks a lot!
Update: There are two different StackTraces: When the returned CheckBox is not null (= when it's working), the StackTrace is the following:
Thread [<3> main] (Suspended (breakpoint at line 110 in FavoriteListCursorAdapter))
FavoriteListCursorAdapter.bindView(View, Context, Cursor) line: 110
FavoriteListCursorAdapter(CursorAdapter).getView(int, View, ViewGroup) line: 186
ListView(AbsListView).obtainView(int) line: 1274
ListView.makeAndAddView(int, int, boolean, int, boolean) line: 1668
ListView.fillUp(int, int) line: 667
ListView.fillGap(boolean) line: 613
ListView(AbsListView).trackMotionScroll(int, int) line: 2531
ListView(AbsListView).onTouchEvent(MotionEvent) line: 2001
ListView.onTouchEvent(MotionEvent) line: 3234
ListView(View).dispatchTouchEvent(MotionEvent) line: 3709
ListView(ViewGroup).dispatchTouchEvent(MotionEvent) line: 852
LinearLayout(ViewGroup).dispatchTouchEvent(MotionEvent) line: 884
ViewFlipper(ViewGroup).dispatchTouchEvent(MotionEvent) line: 884
LinearLayout(ViewGroup).dispatchTouchEvent(MotionEvent) line: 884
FrameLayout(ViewGroup).dispatchTouchEvent(MotionEvent) line: 884
PhoneWindow$DecorView(ViewGroup).dispatchTouchEvent(MotionEvent) line: 884
PhoneWindow$DecorView.superDispatchTouchEvent(MotionEvent) line: 1659
PhoneWindow.superDispatchTouchEvent(MotionEvent) line: 1107
FavoritenActivity(Activity).dispatchTouchEvent(MotionEvent) line: 2061
PhoneWindow$DecorView.dispatchTouchEvent(MotionEvent) line: 1643
FrameLayout(ViewGroup).dispatchTouchEvent(MotionEvent) line: 884
LinearLayout(ViewGroup).dispatchTouchEvent(MotionEvent) line: 884
TabHost(ViewGroup).dispatchTouchEvent(MotionEvent) line: 884
FrameLayout(ViewGroup).dispatchTouchEvent(MotionEvent) line: 884
LinearLayout(ViewGroup).dispatchTouchEvent(MotionEvent) line: 884
PhoneWindow$DecorView(ViewGroup).dispatchTouchEvent(MotionEvent) line: 884
PhoneWindow$DecorView.superDispatchTouchEvent(MotionEvent) line: 1659
PhoneWindow.superDispatchTouchEvent(MotionEvent) line: 1107
Scout(Activity).dispatchTouchEvent(MotionEvent) line: 2061
PhoneWindow$DecorView.dispatchTouchEvent(MotionEvent) line: 1643
ViewRoot.handleMessage(Message) line: 1691
ViewRoot(Handler).dispatchMessage(Message) line: 99
Looper.loop() line: 123
ActivityThread.main(String[]) line: 4363
Method.invokeNative(Object, Object[], Class, Class[], Class, int, boolean) line: not available [native method]
Method.invoke(Object, Object...) line: 521
ZygoteInit$MethodAndArgsCaller.run() line: 860
ZygoteInit.main(String[]) line: 618
NativeStart.main(String[]) line: not available [native method]
And when the returned object is null, the StackTrace is the following:
Thread [<3> main] (Suspended (breakpoint at line 123 in FavoriteListCursorAdapter))
FavoriteListCursorAdapter.bindView(View, Context, Cursor) line: 123
FavoriteListCursorAdapter(CursorAdapter).getView(int, View, ViewGroup) line: 186
ListView(AbsListView).obtainView(int) line: 1256
ListView.makeAndAddView(int, int, boolean, int, boolean) line: 1668
ListView.fillUp(int, 开发者_运维知识库int) line: 667
ListView.correctTooHigh(int) line: 1289
ListView.fillGap(boolean) line: 609
ListView(AbsListView).trackMotionScroll(int, int) line: 2531
ListView(AbsListView).onTouchEvent(MotionEvent) line: 2001
ListView.onTouchEvent(MotionEvent) line: 3234
ListView(View).dispatchTouchEvent(MotionEvent) line: 3709
ListView(ViewGroup).dispatchTouchEvent(MotionEvent) line: 852
LinearLayout(ViewGroup).dispatchTouchEvent(MotionEvent) line: 884
ViewFlipper(ViewGroup).dispatchTouchEvent(MotionEvent) line: 884
LinearLayout(ViewGroup).dispatchTouchEvent(MotionEvent) line: 884
FrameLayout(ViewGroup).dispatchTouchEvent(MotionEvent) line: 884
PhoneWindow$DecorView(ViewGroup).dispatchTouchEvent(MotionEvent) line: 884
PhoneWindow$DecorView.superDispatchTouchEvent(MotionEvent) line: 1659
PhoneWindow.superDispatchTouchEvent(MotionEvent) line: 1107
FavoritenActivity(Activity).dispatchTouchEvent(MotionEvent) line: 2061
PhoneWindow$DecorView.dispatchTouchEvent(MotionEvent) line: 1643
FrameLayout(ViewGroup).dispatchTouchEvent(MotionEvent) line: 884
LinearLayout(ViewGroup).dispatchTouchEvent(MotionEvent) line: 884
TabHost(ViewGroup).dispatchTouchEvent(MotionEvent) line: 884
FrameLayout(ViewGroup).dispatchTouchEvent(MotionEvent) line: 884
LinearLayout(ViewGroup).dispatchTouchEvent(MotionEvent) line: 884
PhoneWindow$DecorView(ViewGroup).dispatchTouchEvent(MotionEvent) line: 884
PhoneWindow$DecorView.superDispatchTouchEvent(MotionEvent) line: 1659
PhoneWindow.superDispatchTouchEvent(MotionEvent) line: 1107
Scout(Activity).dispatchTouchEvent(MotionEvent) line: 2061
PhoneWindow$DecorView.dispatchTouchEvent(MotionEvent) line: 1643
ViewRoot.handleMessage(Message) line: 1691
ViewRoot(Handler).dispatchMessage(Message) line: 99
Looper.loop() line: 123
ActivityThread.main(String[]) line: 4363
Method.invokeNative(Object, Object[], Class, Class[], Class, int, boolean) line: not available [native method]
Method.invoke(Object, Object...) line: 521
ZygoteInit$MethodAndArgsCaller.run() line: 860
ZygoteInit.main(String[]) line: 618
NativeStart.main(String[]) line: not available [native method]
you can notice some weird behavior – namely, that you’ll see the names start shifting as you scroll up and down the list. What happens is that if you don’t instantiate and place something into your TextView (basically to act as a place holder) then in your bindView method nothing gets bound to some of the TextViews and thus the shifting. So basically, if you see stuff shifting around in your lists, then that’s a big flag for make sure you are binding things to all of your views in both your newView and bindView methods.
So, Do instantiate all of your views whether Text/Image defined in row of the list..else scrolling can show up some errors...
精彩评论