2

我對android很新穎,我有一些過濾的listView和它從橫向模式改變爲縱向模式或反之亦然的問題。我有一個editText用於過濾「drinkSearch」,只要不改變視角(人像與風景),這種過濾就可以工作。這是錯誤,我得到:Android - 嘗試重新打開一個已關閉的對象:使用loaderManager的SQLiteQuery

java.lang.IllegalStateException:嘗試重新打開一個已關閉 對象:SQLiteQuery:選擇_id,名字從飲料

正如你所看到的在下面的代碼中,我使用接口LoaderManager.LoaderCallbacks,這個概念對我來說有點新,我不確定 哪裏出了問題。我會感謝所有幫助,提前致謝!

公共類Drinks_Fragment擴展片段實現LoaderManager.LoaderCallbacks {

private static final int DRINKS_LIST_LOADER = 0x01; 
private SimpleCursorAdapter adapter; 
private ListView drinksList; 
private String LOG; 
private EditText drinkSearch; 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 

    View view = inflater.inflate(R.layout.drinks_list, container, false); 
    drinkSearch = (EditText)view.findViewById(R.id.drinkInputSearch); 
    drinksList = (ListView) view.findViewById(R.id.drinksList); 
    drinksList.setEmptyView(view.findViewById(R.id.empty_list_view)); 

    String[] from = {DrinksTable.COLUMN_NAME}; 
    int[] to = {R.id.drinkName}; 
    getLoaderManager().initLoader(DRINKS_LIST_LOADER, null, this); 
    adapter = new SimpleCursorAdapter(getActivity().getApplicationContext(), R.layout.drinks_list_item,null, from, to, 0); 
    drinksList.setAdapter(adapter); 

在這一部分,我問我的ContentProvider基於在searchDrink EDITTEXT輸入的字符串一個新的光標。 (下面的代碼,直到「返回查看」只是以下的部分上面,同樣onCreateView法)

drinkSearch.addTextChangedListener(new TextWatcher() { 

     @Override 
     public void onTextChanged(CharSequence s, int arg1, int arg2, int arg3) { 
      // When user changed the Text 
      adapter.getFilter().filter(s.toString()); 
     } 

     @Override 
     public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) { 
      // TODO Auto-generated method stub 

     } 

     @Override 
     public void afterTextChanged(Editable arg0) { 
      // TODO Auto-generated method stub 
     } 
    }); 

    adapter.setFilterQueryProvider(new FilterQueryProvider() { 

     public Cursor runQuery(CharSequence constraint) { 
      String value = "%"+constraint.toString()+"%"; 
      ContentResolver content = getActivity().getContentResolver(); 
      return content.query(CupProvider.DRINKS_URI,new String[]{DrinksTable.COLUMN_ID,DrinksTable.COLUMN_NAME},DrinksTable.COLUMN_NAME + " LIKE ?",new String[]{value},null); 
     } 
    }); 

    return view; 
} 

@Override 
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { 
    super.onCreateContextMenu(menu,v,menuInfo); 
    MenuInflater inflater = getActivity().getMenuInflater(); 
    inflater.inflate(R.menu.drink_actions,menu); 
} 


@Override 
public Loader<Cursor> onCreateLoader(int i, Bundle bundle) { 
    String[] projection = {DrinksTable.COLUMN_ID, DrinksTable.COLUMN_NAME}; 
    CursorLoader cursorLoader = new CursorLoader(getActivity(), CupProvider.DRINKS_URI, projection, null, null, null); 
    return cursorLoader; 
} 

@Override 
public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) { 
    adapter.swapCursor(cursor); 

} 

@Override 
public void onLoaderReset(Loader<Cursor> cursorLoader) { 
    // data is not available anymore, delete reference 
    adapter.swapCursor(null); 
} 

}

這裏有兩張照片,以顯示它的外觀的時刻:http://oi42.tinypic.com/dfc702.jpg http://oi43.tinypic.com/2ylqkqa.jpg

回答

6

你的代碼是有點難以做出應有意識差格式。

無論如何,提供的答案實際上不是一個修復。在onLoadFinished處返回的光標應該保證不被關閉,所以您以錯誤的方式加載光標。特別是,當你調用

adapter.getFilter().filter(s.toString());

我真的不明白髮生的事情在這裏,但我不明白,你應該做別的事情。只需將查詢過濾器存儲在Fragment內的字段中並運行getLoaderManager().restartLoader(DRINKS_LIST_LOADER, null, this);即可。請注意,您運行的是restartLoader,而不是initLoader,因爲您有不同的數據要查詢。

在您的onCreateLoader中,應該使用您存儲的過濾器作爲selection的實例變量。

一些背景

initLoader負荷已加載在最後運行,如果它之前運行數據。這就是爲什麼你要調用你的Fragment/Activity的初始化方法。這很方便,因爲您不需要重新定位方向更改。

restartLoader,讓你得到一個新的Loader與(可能)不同的數據進行工作清理以前加載數據。


如果你真的不知道自己在做什麼還,請務必閱讀this article,這與示例代碼裝載機很好的介紹性文章,看起來非常像你想達到什麼目的。起初,裝載機非常神祕,但一旦你掌握了它,它就會順利航行。

1

固定它:

@覆蓋 公共無效onLoadFinished(裝載機cursorLoader,光標光標){ 如果{(cursor.isClosed()!)adapter.swapCursor(cursor); }}

我現在有一個問題,我的名單沒有得到自動更新......

1

添加在AndroidManifest此行讓我在同樣的情況:

android:configChanges="keyboardHidden|orientation|screenSize" 
1

這是因爲過濾後,原來的光標被關閉,因爲changeCursor被調用。與重寫changeCursor:在您的SimpleCursorAdapter

super.swapCursor(cursor) 

確保原始光標被CursorLoader管理。

相關問題