Android - 使用 FragmentActivity 的问题 +用于更新 FragmentStatePagerAdapter 的加载器
我正在尝试将 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:无法在 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
值不为 null,并且当结果返回到 onLoadFinished
时,它被设置在 LoaderManagerImpl.LoaderInfo
中>
我正在查看各种变量,试图以某种方式将 tramsaction.commit()
更改为 transaction.commitAllowingStateLoss()
但与事务相关的所有内容似乎都是私有的或至少受包保护的。
如果我可以做我需要做的事情(以及如何做),有人可以给我一个大概的想法吗?
请注意,如果我不使用 Loader,而是在 AsyncTask 中运行加载操作,则我的代码可以正常工作
I'm trying to use FragmentActivity
with ViewPager
to display dynamic list of Fragments
. There are plenty of examples on how to do a static version of it. My problem is that the list I display needs to be loaded dynamically and also can change based on user input (add/delete). I'm trying to use customized android.support.v4.content.Loader
to load set of data that I can use to build my list.
Everything goes fine in my setup until I get to the point when I want to update the adapter and issue FragmentStatePagerAdapter#notifyDataSetChanged()
call at which point this code is executed (from FragmentStatePagerAdapter
)
public void finishUpdate(View container)
{
if(mCurTransaction != null)
{
mCurTransaction.commit(); // BANG!!! The exception is thrown
mCurTransaction = null;
mFragmentManager.executePendingTransactions();
}
}
The transaction commit fails with this message:
java.lang.IllegalStateException: Can not perform this action inside of onLoadFinished
because within FragmentManagerImpl
this code is executed:
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);
}
}
It turns out that mNoTransactionsBecause
value is not null and it is set in LoaderManagerImpl.LoaderInfo
when the result is returned back to onLoadFinished
I was looking at the various variables trying to somehow change tramsaction.commit()
to transaction.commitAllowingStateLoss()
but everything related to transaction seems to be private or at least package-protected.
Can someone give me a general idea if I can do what I need to do (and how)?
Just to note that my code works fine if instead of using Loader I run the loading ops in AsyncTask
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我遇到了与此非常相似的问题,并通过在片段上使用处理程序解决了它。
我想在 onLoadFinished() 上显示一个警报对话框,类似于以下内容
但这给出了一个错误
无法在 onLoadFinished 内执行此操作
解决方案是向片段添加一个处理程序来处理显示对话框
然后修改 onLoadFinished(...) 以向处理程序发送消息
I had a very similar problem to this and solved it by using a handler on the Fragment.
I wanted to show an alert dialog on onLoadFinished(), similar to the following
But this gave an error
can not perform this action inside of onLoadFinished
The solution was to add a handler to the fragment to take care of showing the dialog
And then modify onLoadFinished(...) to send a message to the handler instead
您可以复制
FragmentStatePagerAdapter
并根据需要进行更改,或者从头开始创建自己的PagerAdapter
。或者干脆不使用装载机。You can copy
FragmentStatePagerAdapter
and change it however you like, or create your ownPagerAdapter
from scratch. Or simply don't use a Loader.它使用 rootView.post() 工作。只需在类作用域中定义 rootView 变量,然后在 CreateView() 上对其进行扩充。
最后 onLoadFinished() 只需像这样使用它:
It works using rootView.post(). Just define rootView variable in class scope and then inflate it onCreateView().
Finally onLoadFinished() simply use it like this: