开发者

Android: SimpleCursorAdapter.bindView sometimes delivers null for findViewById

开发者 https://www.devze.com 2023-01-26 07:56 出处:网络
I\'ve got a custom ListCursorAdapter extending from SimpleCursorAdapter. In the list\'s rows, there are two TextFields and one CheckBox.

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...

0

精彩评论

暂无评论...
验证码 换一张
取 消