我正在尝试将FragmentActivity
与ViewPager
一起使用来显示Fragments
的动态列表。有很多关于如何做静态版本的例子。我的问题是我显示的列表需要动态加载,也可以根据用户输入(添加/删除)进行更改。我正在尝试使用自定义android.support.v4.content.Loader
来加载可用于构建列表的数据集。
在我的设置中一切正常,直到我想要更新适配器并发出FragmentStatePagerAdapter#notifyDataSetChanged()
调用此时执行此代码(来自FragmentStatePagerAdapter
)
public void finishUpdate(View container)
{
if(mCurTransaction != null)
{
mCurTransaction.commit(); // BANG!!! The exception is thrown
mCurTransaction = null;
mFragmentManager.executePendingTransactions();
}
}
事务提交失败并显示以下消息:
java.lang.IllegalStateException: Can not perform this action inside of onLoadFinished
因为在FragmentManagerImpl
内执行了此代码:
private void checkStateLoss() {
if (mStateSaved) {
throw new IllegalStateException(
"Can not perform this action after onSaveInstanceState");
}
if (mNoTransactionsBecause != null) {
throw new IllegalStateException(
"Can not perform this action inside of " + mNoTransactionsBecause);
}
}
结果是mNoTransactionsBecause
LoaderManagerImpl.LoaderInfo
更改为onLoadFinished
的各种变量,但与事务相关的所有内容似乎都是私有的或至少是受包保护的。
如果我可以做我需要做的事情(以及如何做),有人可以给我一个大概吗?
请注意,如果不使用Loader,我的代码工作正常我在AsyncTask中运行加载操作
答案 0 :(得分:35)
我遇到了一个非常类似的问题,并通过在Fragment上使用处理程序来解决它。
我想在onLoadFinished()上显示警告对话框,类似于以下
public class MyFragment extends Fragment
implements LoaderManager.LoaderCallbacks<T> {
public void onLoadFinished(Loader<T> loader, T data) {
showDialog();
}
public void showDialog() {
MyAlertDialogFragment fragment = new MyAlertDialogFragment();
fragment.show(getActivity().getSupportFragmentManager(), "dialog");
}
}
但是这给了一个错误
无法在onLoadFinished
中执行此操作解决方案是在片段中添加一个处理程序来处理显示对话框
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
if(msg.what == MSG_SHOW_DIALOG) {
showDialog();
}
}
};
然后修改onLoadFinished(...)以向处理程序发送消息
public void onLoadFinished(Loader<T> loader, T data) {
handler.sendEmptyMessage(MSG_SHOW_DIALOG);
}
答案 1 :(得分:0)
您可以复制FragmentStatePagerAdapter
并根据需要进行更改,也可以从头开始创建自己的PagerAdapter
。或者只是不要使用Loader。
答案 2 :(得分:0)
使用rootView.post()。只需在类范围中定义rootView变量,然后在onCreateView()上对其进行充气。 最后onLoadFinished()只需使用它:
rootView.post(new Runnable() {
public void run() {
General.showFragment();
}
});