我有一个活动,它使用加载程序回调从服务器加载数据列表。我必须将数据列入一个扩展的片段
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中引用了这个例子,但这些例子在片段中有加载器而不是活动。
任何人都可以帮我解决这个问题,我可以在不调用碎片加载程序的情况下修复它!
答案 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()。
(注意:将该链接复制/粘贴到您的浏览器中... 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的线程。
{{1}}&#13;