Android fragments 从onLoadFinished提交片段在活动内完成

Android fragments 从onLoadFinished提交片段在活动内完成,android-fragments,actionbarsherlock,android-listfragment,Android Fragments,Actionbarsherlock,Android Listfragment,我有一个活动,它使用loader回调从服务器加载数据列表。我必须把数据列成一个片段 SherlockListFragment 我尝试使用 Fragment newFragment = CategoryFragment.newInstance(mStackLevel,categoryList); FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); ft.add(R.id.simple_fragme

我有一个活动,它使用loader回调从服务器加载数据列表。我必须把数据列成一个片段

SherlockListFragment 
我尝试使用

Fragment newFragment   = CategoryFragment.newInstance(mStackLevel,categoryList);
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.add(R.id.simple_fragment, newFragment).commit();
在onLoadFinished中,它给出了一个非法状态异常

java.lang.IllegalStateException: Can not perform this action inside of onLoadFinished
我在actionbar sherlock中提到了这个例子,但是这些例子在片段中有加载程序,而不是活动


有人能帮我解决这个问题吗?我不需要从碎片中调用加载程序就可以修复它

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

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

(注意:将该链接复制/粘贴到浏览器中…StackOverflow无法很好地处理该链接。)

因此,您根本不应该加载处于该状态的片段。如果确实不想将加载程序放入片段中,则需要在活动的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);
     } 
公共类DummyFragment{
公共void setData(对象someObject){
//做事
}
公共类DummyActivity扩展LoaderCallbacks{
创建时的公共void(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)
}
//将您的其他LoaderCallback放在这里…onCreateLoader()和onLoaderReset()
public void onLoadFinished(加载器,对象结果){
片段f=getSupportLoaderManager.findFragmentById(R.id.simple_片段);
f、 设置数据(结果);
} 

显然,您希望使用正确的对象..和正确的加载程序,并可能定义一个有用的setData()方法来更新您的片段。但希望这将为您指明正确的方向。

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

@Override
public void onLoadFinished(Loader<List<Station>> arg0, List<Station> arg1) {
    // do other actions
    handler.sendEmptyMessage(2);
}
碎片的数量取决于需求

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

正如@kwazi回答的,从
onLoadFinished()
调用
FragmentTransition.commit()
,这是一种糟糕的用户体验。我使用ProgressDialog找到了此事件的解决方案

首先创建的
ProgressDialog.setOnDismissListener(新侦听器)
用于查看
onLoadFinished()。
此外,我在
getLoaderManager().restartLoader()之前执行
progressDialog.show()
。 最后将
progressDialog.discouse()
放入
onload finished()
中。 这种方法允许不绑定主UI线程和加载程序线程

公共类FRPersonListAnswer扩展片段
工具
装载机回扣{
私有进程对话;
@凌驾
创建视图上的公共视图(更平坦的充气机,
视图组容器,捆绑包savedInstanceState){
视图=充气机。充气(R.layout.fragment\u persons\u list,container,false);
//准备进度对话框
progressDialog=新建progressDialog(CuraActivity);
progressDialog.setMessage(“等待…”);
progressDialog.setUndeterminate(true);
progressDialog.setOnDismissListener(新的OnDismissListener(){
@凌驾
公共void onDismiss(对话框接口对话框){
//在此处创建FragmentTransaction.commit();
//但建议将控制权传递给您的活动
//通过一个接口,并在那里管理片段。
}
});
lv=(ListView)view.findViewById(R.id.lv_out1);
lv.setOnItemClickListener(新的OnItemClickListener(){
@凌驾
public void onItemClick(AdapterView父视图、最终视图、,
最终整数位置,长id){
//在此处启动进度对话框
progressDialog.show();
游标c=(游标)parent.getAdapter().getItem(位置);
//创建加载器
getLoaderManager().restartLoader(1,null,curFragment);
}
});
返回视图;
}
@凌驾
public void onLoadFinished(加载器、光标数据){
开关(loader.getId()){
案例1:
//关闭对话框并调用progressDialog.onDismiss()侦听器
progressDialog.disclose();
打破
违约:
打破
}

}
谢谢你的回答!:)也许我对我的问题不太清楚。我已经把我的homefragment放在了上面,只是想在加载一些数据时实现下一个片段的堆叠。我找到了一个方法来实现这一点。我会把它作为一个答案发布。+1感谢你的支持和回答。我真的没有想到使用f.setData(result)我本可以在其他片段中的相同活动中使用它。:)啊,我不知道。无论如何,请看我对您关于更好解决方案的答案的评论。commitAllowingStateLoss()将是一种方法……嗯,我建议不要这样做。如果您确实需要按照您所说的那样堆叠片段,那么您可以调用commitAllowingStateLoss()。这将避免处理程序和IllegalArgumentException,因为您会告诉平台..“没关系,我知道风险..无论如何都要这样做”。请参阅感谢kwazi,我已经尝试过该方法。感谢您的帮助。这是一个很好的建议。干杯:)只是注意:调用DialogFragment.show()时,调用commitAllowStateLoss不是一个选项。我必须为特定类型的片段事务使用处理程序。@javahead76或者您可以重写
对话框fragment
show()
方法,并用
commitAllowStateLoss()替换对
commit()
的调用
This method can be mainly used in case of stackFragments, where all fragments have different related functions.