从活动中的onLoadFinished提交片段

Asw*_*nan 11 android-fragments actionbarsherlock android-listfragment

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

SherlockListFragment 
Run Code Online (Sandbox Code Playgroud)

我尝试使用提交片段

Fragment newFragment   = CategoryFragment.newInstance(mStackLevel,categoryList);
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.add(R.id.simple_fragment, newFragment).commit();
Run Code Online (Sandbox Code Playgroud)

在onLoadFinished中,它给出了一个IllegalStateException说

java.lang.IllegalStateException: Can not perform this action inside of onLoadFinished
Run Code Online (Sandbox Code Playgroud)

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

任何人都可以帮助我这个o我可以修复它而无需从片段调用加载器!

Asw*_*nan 14

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

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

在处理程序中

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
        }
    }
}; 
Run Code Online (Sandbox Code Playgroud)

片段数量取决于要求.

This method can be mainly used in case of stackFragments, where all fragments have different related functions.
Run Code Online (Sandbox Code Playgroud)

  • 请注意:调用DialogFragment.show()时调用commitAllowStateLoss不是一个选项.我不得不为特定类型的片段事务使用处理程序. (4认同)
  • @ javahead76或者你可以覆盖`DialogFragment`的`show()`方法,并用`commitAllowStateLoss()`替换`commit()`的调用. (2认同)

kwa*_*azi 8

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

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

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

(注意:将该链接复制/粘贴到您的浏览器中... StackOverflow不能很好地处理它..)

因此,您根本不应该在该状态下加载片段.如果你真的不想把Loader放在Fragment中,那么你需要在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);
     } 
Run Code Online (Sandbox Code Playgroud)

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