2013-04-24 50 views
0

我有一個適配器包裝CursorAdapter,原因是我需要顯示行中的項目(如在GridView),但也顯示細節關於每個項目如果點擊下面的面板(需要ListView)。因此,而不是一個CursorAdapter直接填充ListView,我有一個內轉接:CursorAdapter:getCount()== 0,mCu​​rsor.getCount()== 6

public class ChallengeAdapter extends BaseAdapter { 

    class ChallengeDataAdapter extends CursorAdapter { 

     private BaseAdapter mChallengeAdapter; 

     public ChallengeDataAdapter(Context context, Cursor cursor, BaseAdapter a) { 
      super(context, cursor, CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER); 
      mChallengeAdapter = a; 
     } 

     @Override 
     public void bindView(View arg0, Context arg1, Cursor arg2) { 
      // TODO Auto-generated method stub 

     } 

     @Override 
     public View newView(Context arg0, Cursor arg1, ViewGroup arg2) { 
      // TODO Auto-generated method stub 
      return null; 
     } 

     @Override 
     protected void onContentChanged() { 
      super.onContentChanged(); 
      mChallengeAdapter.notifyDataSetChanged(); 
     } 

    } 

    private ChallengeDataAdapter mDataAdapter; 

    public ChallengeAdapter(Context context, Cursor cursor) { 
     mDataAdapter = new ChallengeDataAdapter(context, cursor, this); 
    } 

    @Override 
    public int getCount() { 
     return (mDataAdapter.getCount() + ChallengeMultiTile.ROW_SIZE - 1)/ChallengeMultiTile.ROW_SIZE; //integer divide rounds down 
    } 

    @Override 
    public Object getItem(int position) { 
     Challenge[] output = new Challenge[ChallengeMultiTile.ROW_SIZE]; 
     int min = position * ChallengeMultiTile.ROW_SIZE; 
     int max = Math.min(position * ChallengeMultiTile.ROW_SIZE + ChallengeMultiTile.ROW_SIZE, mDataAdapter.getCount()); 
     for(int i=min; i<max; ++i) { 
      output[i-min] = Challenge.get((Cursor) mDataAdapter.getItem(i)); 
     } 
     return output; 
    } 

    @Override 
    public long getItemId(int position) { 
     return position; 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     if(convertView==null) { 
      convertView = new ChallengeMultiTile(parent.getContext()); 
     } 
     ((ChallengeMultiTile) convertView).populate((Challenge[]) getItem(position)); 
     convertView.setBackgroundColor(0xfffffff); 
     return convertView; 
    } 

    public void swapCursor(Cursor cursor) { 
     mDataAdapter.swapCursor(cursor); 
     notifyDataSetChanged(); 
    } 

} 

這工作簡單,但隨後的ChallengeDataAdapter開始有零的getCount()。但是,我在那裏放了一個斷點,ChallengeDataAdapter#mCursor.getCount()是6.我將這個陷入了onContentChanged()方法中,但我不知道它是在哪裏發生的。

爲什麼CursorAdapter的內部遊標計數爲6時計數爲零?

回答

2

當你在CursorAdapter的源代碼,你會看到getCount將()和onContentChanged()以下:

public int getCount() { 
    if (mDataValid && mCursor != null) { 
     return mCursor.getCount(); 
    } else { 
     return 0; 
    } 
} 

protected void onContentChanged() { 
    if (mAutoRequery && mCursor != null && !mCursor.isClosed()) { 
     if (false) Log.v("Cursor", "Auto requerying " + mCursor + " due to update"); 
     mDataValid = mCursor.requery(); 
    } 
} 

因此,儘管mCursor.getCount()可能返回6,getCount將()可能返回如果查詢失敗,則返回0。 爲什麼查詢失敗是另一個問題,而不是我可以從您發佈的代碼中回答的問題。

順便說一句,您不需要在ChallengeDataAdapter類中保留對ChallengeAdapter的引用。 ChallengeDataAdapter是一個內部類,它與它的封閉類的一個實例相關聯,並且可以直接訪問該對象的方法和字段。而不是調用mChallengeAdapter.notifyDataSetChanged()你可以做一個ChallengeAdapter.this.notifyDataSetChanged();

+0

我剛剛發現或多或少都是一樣的東西;我會去看看,謝謝! – 2013-04-24 16:44:27

+0

我從'Loader'運行。關掉重新查詢似乎已經解決了這個問題。 – 2013-04-24 16:46:14

+0

在LoaderManager中使用CursorLoader,您不必再擔心查詢。它會爲你做(其中包括像保留方向變化等光標) – 2013-04-24 16:50:28