Android:SimpleCursorAdapter.bindView有时会为findViewById提供null

时间:2010-11-21 12:34:30

标签: android listview

我有一个从SimpleCursorAdapter扩展的自定义ListCursorAdapter。在列表的行中,有两个TextField和一个CheckBox。

快速滚动时,复选框的行为很奇怪;所选择的那些从一行“跳”到另一行,例如如果第三行包含一个选中的复选框并且我正在快速滚动,则突然选择另一行。

我发现有时,我的bindView方法中的findViewById返回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();
    }
}

即。我在“System.out.println()” - 部分。有人能告诉我为什么我有这种行为吗?经常调用bindView方法是否正确?不应该每行只调用一次吗?

非常感谢!

更新: 有两种不同的StackTraces: 当返回的CheckBox不为null(=当它工作时),StackTrace如下:

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]

当返回的对象为null时,StackTrace如下:

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]  

1 个答案:

答案 0 :(得分:0)

你可以注意到一些奇怪的行为 - 也就是说,当你在列表中上下滚动时,你会看到名字开始移动。 会发生的是,如果你没有实例化并在TextView中放置一些东西(基本上充当占位符),那么在你的bindView方法中,没有任何东西被绑定到某些TextView,从而转移。 所以基本上,如果你看到列表中的东西转移,那么这是一个很大的标志,以确保你在newView和bindView方法中绑定所有视图。

因此,请实例化所有视图,无论是在列表行中定义的文本/图像。滚动都会显示一些错误......