J'ai un ListCursorAdapter personnalisé qui s'étend de SimpleCursorAdapter. Dans les lignes de la liste, il y a deux TextFields et un CheckBox. Lorsque vous faites défiler rapidement, le comportement des cases à cocher est bizarre; les "sélectionnés" sautent d'une rangée à l'autre, par ex. Si la troisième ligne contient une case à cocher sélectionnée et que je défile rapidement, une autre ligne est sélectionnée.Android: SimpleCursorAdapter.bindView fournit parfois null pour findViewById
je trouve que parfois, le findViewById dans mon Bindview méthode retourne 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();
}
}
dire que je suis à la "System.out.println()" - partie. Quelqu'un peut-il me dire pourquoi j'ai ce comportement? Et est-ce correct que la méthode bindView est appelée souvent? Ne devrait-il pas être appelé seulement une fois par rangée?
Merci beaucoup!
Mise à jour: Il y a deux stacktraces différentes: Lorsque la case retour est non nulle (= quand il travaille), le StackTrace est la suivante:
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]
Et quand l'objet retourné est nul, la StackTrace est le suivant:
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]
oui, Bindview doit être appelé une fois par ligne, mais aussi quand vous faites défiler la liste. –