2016-07-31 11 views
0

Я реализую это Two Pane UI. Вид списка на левой панели заполняется загрузчиком. Когда элемент списка щелкнут, в правой панели отображаются сведения об этом элементе.Выполнение ListViewItemClick() вызывает IllegalStateException при вызове внутри onLoadFinished()

Я хочу, чтобы первый элемент на левой панели был выбран по умолчанию и его данные должны отображаться в правой панели. Чтобы сделать это, я пытался позвонить performItemClick() в моем списке, как это:

listView.performItemClick(listView, 
          ListView.SCROLLBAR_POSITION_DEFAULT, 
          listView.getItemIdAtPosition(ListView.SCROLLBAR_POSITION_DEFAULT)); 

Я делаю это в onLoadFinished() методе моего загрузчика, потому что это та точка, где я могу быть уверен, что в списке был заселен. Этот метод работает в потоке пользовательского интерфейса, поэтому я не ожидал никаких икота. Однако я получаю ошибку java.lang.IllegalStateException.

Я хотел бы знать, почему выполнение действия click в onLoadFinished() вызывает исключение, тогда как другие вызовы в виде списка, такие как smoothScrollToPosition(), будут выполнены.

Из других сообщений SO я вижу, что это можно сделать, используя Handler(). Но мне непонятно, почему прокрутка списка может выполняться прямым вызовом, но нажатие на элемент требует отправки в очередь сообщений через Handler(). Я довольно новичок в Android, и есть пробелы в моем понимании его архитектуры.

Вот полный код, который не удается:

public void onLoadFinished(Loader<Cursor> loader, Cursor data) { 
    //Update the adapter 
    mForecastAdapter.swapCursor(data); 

    //If there is some item in the list that was selected before then scroll to it 
    if(lastSelectedIndex != ListView.INVALID_POSITION) { 
     //Restore to last scrolled position 
     // Get a reference to the ListView, and attach this adapter to it. 
     ListView listView = (ListView) getActivity().findViewById(R.id.listview_forecast); 

     listView.smoothScrollToPosition(lastSelectedIndex); 
    } 

    //select the first element if two pane is supported and last state doesn't exist 
    else if(!mUseTodayLayout) { 

     ListView listView = (ListView) getActivity().findViewById(R.id.listview_forecast); 

     listView.performItemClick(listView, 
       ListView.SCROLLBAR_POSITION_DEFAULT, 
       listView.getItemIdAtPosition(ListView.SCROLLBAR_POSITION_DEFAULT)); 

    } 
} 

Трассировка стека наклеена ниже:

java.lang.IllegalStateException: Can not perform this action inside of onLoadFinished 
      at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1369) 
      at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1383) 
      at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:636) 
      at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:615) 
      at com.example.android.sunshine.app.MainActivity.onListItemClicked(MainActivity.java:200) 
      at com.example.android.sunshine.app.ForecastFragment.onLoadFinished(ForecastFragment.java:285) 
      at com.example.android.sunshine.app.ForecastFragment.onLoadFinished(ForecastFragment.java:46) 
      at android.support.v4.app.LoaderManagerImpl$LoaderInfo.callOnLoadFinished(LoaderManager.java:427) 
      at android.support.v4.app.LoaderManagerImpl$LoaderInfo.onLoadComplete(LoaderManager.java:395) 
      at android.support.v4.content.Loader.deliverResult(Loader.java:104) 
      at android.support.v4.content.CursorLoader.deliverResult(CursorLoader.java:73) 
      at android.support.v4.content.CursorLoader.deliverResult(CursorLoader.java:35) 
      at android.support.v4.content.AsyncTaskLoader.dispatchOnLoadComplete(AsyncTaskLoader.java:223) 
      at android.support.v4.content.AsyncTaskLoader$LoadTask.onPostExecute(AsyncTaskLoader.java:61) 
      at android.support.v4.content.ModernAsyncTask.finish(ModernAsyncTask.java:461) 
      at android.support.v4.content.ModernAsyncTask.access$500(ModernAsyncTask.java:47) 
      at android.support.v4.content.ModernAsyncTask$InternalHandler.handleMessage(ModernAsyncTask.java:474) 
      at android.os.Handler.dispatchMessage(Handler.java:102) 
      at android.os.Looper.loop(Looper.java:135) 
      at android.app.ActivityThread.main(ActivityThread.java:5257) 
      at java.lang.reflect.Method.invoke(Native Method) 
      at java.lang.reflect.Method.invoke(Method.java:372) 
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903) 
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698) 

ответ

0

The IllegalStateException происходит не из-за вызова listView.performItemClick(), но потому, что этот вызов был в конечном счете, в результате чего транзакции фрагмент , Фрагментные транзакции запрещены в асинхронных обратных вызовах, таких как onLoadFinished(). Я нашел полезную информацию here.