2013-03-18 25 views
0

我收到了一個很奇怪的錯誤(情況)。 我使用ViewPager和FragmentStatePagerAdapter 與許多ListFragment(sqlite數據庫中的每個記錄一個)。每個ListFragment實現LoaderManager.LoaderCallbacks。 我將顯示 只有更重要的部分代碼段(據我所知)ViewPager。在SimpleCursorAdapter中獲取錯誤的光標

class EnglishDictStatePagerAdapter extends FragmentStatePagerAdapter { 

    private int records; 
    private Cursor cursor; 

    public EnglishDictStatePagerAdapter(FragmentManager fm) { 
     super(fm); 
     records = getCursor().getCount(); 
    } 

    @Override 
    public Fragment getItem(int position) { 
     Fragment fragment = new EnglishDictDetailFragment(); 
     getCursor().moveToPosition(position); 
     long wordId = cursor.getLong(1); 
     Bundle args = new Bundle(); 
     args.putLong(WORD_ID, wordId); 
     args.putInt(LANG_TYPE, getCurrentLangType()); 
     args.putInt(WORD_POSITION, position); 
     fragment.setArguments(args); 
     closeCursor(); 
     return fragment; 
    } 

    private Cursor getCursor() { 
     if (cursor == null) { 
      cursor = getContentResolver().query(getContentUri(), getProjection() ,null, null, null); 
     } 
     return cursor; 
    } 

    private void closeCursor() { 
     if (cursor != null) { 
      cursor.close(); 
     } 
     cursor = null; 
    } 

    @Override 
    public int getCount() { 
     return records; 
    } 
} 

這是ListFragment類的一部分

class EnglishDictDetailFragment extends SherlockListFragment implements 
     LoaderManager.LoaderCallbacks<Cursor> { 

private int mLangType; 
private int loaderId; 
private long mId; 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 
    return inflater.inflate(R.layout.english_dict_list, container, false); 
} 

@Override 
public void onActivityCreated(Bundle savedInstanceState) { 
    super.onActivityCreated(savedInstanceState); 
    registerForContextMenu(getListView()); 
    SimpleCursorAdapter mAdapter = new SimpleCursorAdapter(
     getSherlockActivity(), 
     R.layout.english_dict_list_item, 
     null, 
     null, 
     new int[] { R.id.english_dict_word }, 
     0 
    ); 
    setListAdapter(mAdapter); 
    getLoaderManager().initLoader(loaderId, null, this); 
} 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    mId = getArguments().getLong(WORD_ID); 
    mLangType = getArguments().getInt(LANG_TYPE); 
    loaderId = getArguments().getInt(WORD_POSITION); 
} 

@Override 
public Loader<Cursor> onCreateLoader(int id, Bundle args) { 
    return new CursorLoader(getSherlockActivity(), getContentUri(), null, null, null, null) 

@Override 
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) { 
    if (loader.getId() == loaderId) { 
     ((SimpleCursorAdapter)getListAdapter()).swapCursor(cursor); 
    } 
} 

@Override 
public void onLoaderReset(Loader<Cursor> loader) { 
    ((SimpleCursorAdapter)getListAdapter()).swapCursor(null); 
} 

它允許通過其中加載正確的ListFragments滾動內容。 但是,如果我試圖讓光標在某處代碼(例如上在onContextItemSelected)與代碼

cursor = (Cursor)getListAdapter().getItem(info.position); 

我經常收到從前面或後面的ListFragment光標ViewPager。 我不能想象是什麼原因,但我在onLoadFinished中看到, 方法被調用了3次,並且上次有其他ListFragment存在遊標參數。我可以假設,首先它使用正確的光標來顯示內容,但稍後會有加載屏幕外ListFragment項目(鄰居)的內容,並且某些來自鄰居ListFragment的遊標將被分配給當前(可見)ListFragment的SimpleCursorAdapter。 有人可以幫忙嗎?

+0

難道不是你的代碼拋出一個'NullPointerException'在'getItem'方法,你第一個電話後,要關閉遊標(也抵消它)? – Luksprog 2013-03-18 19:43:46

+0

@Luksprog。我關閉FragmentStatePagerAdapter中的Cursor。我剛纔展示了這段代碼片斷,展示瞭如何爲ViewPager實例化新的ListFragment對象。所以有一個帶有遊標的數據庫請求,將數據傳遞給新的ListFragment,並關閉cussor。然後,該數據用於爲LoaderManager創建CursorLoader。每個ListFragment都會有不同的URI。 getListAdapter()。getItem(info.position)我在ListFragment中的onContextItemSelected中使用。我很清楚看到上一頁有光標。但是我在當前頁面上的ListView中也看到了正確的數據。 – polymetr 2013-03-18 19:58:11

回答