从活动中的onLoadFinished提交片段

时间:2012-09-05 07:09:45

标签: android-fragments actionbarsherlock android-listfragment

我有一个活动,它使用加载程序回调从服务器加载数据列表。我必须将数据列入一个扩展的片段

SherlockListFragment 

我尝试使用

提交片段
Fragment newFragment   = CategoryFragment.newInstance(mStackLevel,categoryList);
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.add(R.id.simple_fragment, newFragment).commit();
onLoadFinished中的

,它给出了一个IllegalStateException说

java.lang.IllegalStateException: Can not perform this action inside of onLoadFinished

我在actionbar sherlock中引用了这个例子,但这些例子在片段中有加载器而不是活动。

任何人都可以帮我解决这个问题,我可以在不调用碎片加载程序的情况下修复它!

3 个答案:

答案 0 :(得分:14)

Atlast,我找到了解决这个问题的方法。创建一个设置空消息的句柄,并在onLoadFinished()上调用该处理程序。代码与此类似。

@Override
public void onLoadFinished(Loader<List<Station>> arg0, List<Station> arg1) {
    // do other actions
    handler.sendEmptyMessage(2);
}

在处理程序中,

private Handler handler = new Handler()  { // handler for commiting fragment after data is loaded
    @Override
    public void handleMessage(Message msg) {
        if(msg.what == 2) {
            Log.d(TAG, "onload finished : handler called. setting the fragment.");
            // commit the fragment
        }
    }
}; 

碎片数量取决于要求。

This method can be mainly used in case of stackFragments, where all fragments have different related functions.

答案 1 :(得分:8)

根据onLoadFinished()方法的Android文档:

  

请注意,通常,在此调用中,不允许应用程序提交片段事务,因为它可能在保存活动状态后发生。有关此内容的进一步讨论,请参阅FragmentManager.openTransaction()。

https://developer.android.com/reference/android/app/LoaderManager.LoaderCallbacks.html#onLoadFinished(android.content.Loader, D)

(注意:将该链接复制/粘贴到您的浏览器中... StackOverflow无法正常处理..)

所以你根本不应该在该状态下加载片段。如果你真的不想把Loader放在片段中,那么你需要在Activity的onCreate()方法中初始化片段,然后当onLoadFinished发生时,只需在你的片段上调用一个方法。

一些粗略伪代码如下:

public class DummyFragment {

     public void setData(Object someObject) {
           //do stuff
     }

public class DummyActivity extends LoaderCallbacks<Object> {

     public void onCreate(Bundle savedInstanceState) {
           super.onCreate(savedInstanceState);

           Fragment newFragment = DummyFragment.newInstance();
           FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
           ft.add(R.id.simple_fragment, newFragment).commit();

           getSupportLoaderManager.initLoader(0, null, this)
     }

     // put your other LoaderCallbacks here... onCreateLoader() and onLoaderReset()

     public void onLoadFinished(Loader<Object> loader, Object result) {
           Fragment f = getSupportLoaderManager.findFragmentById(R.id.simple_fragment);
           f.setData(result);
     } 

显然,你想要使用正确的对象..和正确的加载器,并且可能定义一个有用的setData()方法来更新你的片段。但希望这会指出你正确的方向。

答案 2 :(得分:0)

正如@kwazi所说,从FragmentTransition.commit()拨打onLoadFinished()是一种糟糕的用户体验。我通过使用ProgressDialog找到了此事件的解决方案。

首次创建ProgressDialog.setOnDismissListener(new listener)以观看onLoadFinished().progressDialog.show()之前getLoaderManager().restartLoader() progressDialog.dismiss()。 最后将onLoadFinished()放入public class FrPersonsListAnswer extends Fragment implements LoaderCallbacks<Cursor>{ private ProgressDialog progressDialog; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_persons_list, container, false); //prepare progress Dialog progressDialog = new ProgressDialog(curActivity); progressDialog.setMessage("Wait..."); progressDialog.setIndeterminate(true); progressDialog.setOnDismissListener(new OnDismissListener() { @Override public void onDismiss(DialogInterface dialog) { //make FragmentTransaction.commit() here; //but it's recommended to pass control to your Activity //via an Interface and manage fragments there. } }); lv = (ListView) view.findViewById(R.id.lv_out1); lv.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, final View view, final int position, long id) { //START PROGRESS DIALOG HERE progressDialog.show(); Cursor c = (Cursor) parent.getAdapter().getItem(position); // create Loader getLoaderManager().restartLoader(1, null, curFragment); } }); return view; } @Override public void onLoadFinished(Loader<Cursor> loader, Cursor data) { switch (loader.getId()) { case 1: //dismiss dialog and call progressDialog.onDismiss() listener progressDialog.dismiss(); break; default: break; } }。 这种方法允许不绑定主UI线程和Loader的线程。

&#13;
&#13;
{{1}}
&#13;
&#13;
&#13;