我从我的应用程序中获取用户报告,提供以下异常:
java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
at android.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1109)
at android.app.FragmentManagerImpl.popBackStackImmediate(FragmentManager.java:399)
at android.app.Activity.onBackPressed(Activity.java:2066)
at android.app.Activity.onKeyUp(Activity.java:2044)
at android.view.KeyEvent.dispatch(KeyEvent.java:2529)
at android.app.Activity.dispatchKeyEvent(Activity.java:2274)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1803)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchKeyEvent(PhoneWindow.java:1855)
at com.android.internal.policy.impl.PhoneWindow.superDispatchKeyEvent(PhoneWindow.java:1277)
at android.app.Activity.dispatchKeyEvent(Activity.java:2269)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1803)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at android.widget.TabHost.dispatchKeyEvent(TabHost.java:297)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchKeyEvent(PhoneWindow.java:1855)
at com.android.internal.policy.impl.PhoneWindow.superDispatchKeyEvent(PhoneWindow.java:1277)
at android.app.Activity.dispatchKeyEvent(Activity.java:2269)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1803)
at android.view.ViewRoot.deliverKeyEventPostIme(ViewRoot.java:2880)
at android.view.ViewRoot.handleFinishedEvent(ViewRoot.java:2853)
at android.view.ViewRoot.handleMessage(ViewRoot.java:2028)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:132)
at android.app.ActivityThread.main(ActivityThread.java:4028)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:491)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:844) …
Run Code Online (Sandbox Code Playgroud) android illegalstateexception android-fragments android-viewpager fragmenttransaction
我使用以下方法通过显示/隐藏它们来切换片段(在我的NavigationDrawer中).
protected void showFragment(int container, Fragment fragment, String tag, String lastTag, boolean addToBackStack ) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
if ( lastTag != null && !lastTag.equals("")) {
Fragment lastFragment = fragmentManager.findFragmentByTag( lastTag );
if ( lastFragment != null ) {
transaction.hide( lastFragment );
}
}
if ( fragment.isAdded() ) {
transaction.show( fragment );
}
else {
transaction.add( container, fragment, tag );
}
if ( addToBackStack ) {
transaction.addToBackStack( tag );
}
transaction.commit();
// set the active …
Run Code Online (Sandbox Code Playgroud) 在Android N和支持库版本24中添加的新commitNow()方法具有有限且有点令人困惑的文档.
同步提交此事务.任何添加的片段都将被初始化并完全进入其主机的生命周期状态,并且在此调用返回之前,所有已删除的片段将相应地被拆除.以这种方式提交事务允许将片段添加为专用的封装组件,这些组件监视其主机的生命周期状态,同时提供更完整的排序保证,以确保这些片段何时完全初始化并准备就绪.管理视图的片段将创建和附加这些视图.
调用commitNow比调用commit()后跟FragmentManager.executePendingTransactions()更好,因为后者的副作用是尝试提交所有当前挂起的事务,无论这是否是所需的行为.
以这种方式提交的事务可能不会被添加到FragmentManager的后台堆栈中,因为这样做会破坏其他异步提交事务的其他预期排序保证.如果先前请求使用addToBackStack(String)将事务添加到后台堆栈,则此方法将抛出IllegalStateException.
事务只能在其包含活动保存其状态之前使用此方法提交.如果在该点之后尝试提交,则将引发异常.这是因为如果活动需要从其状态恢复,则提交后的状态可能会丢失.请参阅commitAllowingStateLoss()以了解可能丢失提交的情况.
我用粗体突出显示了我认为令人困惑的部分.
所以,我的主要关注点/问题是:
1 - 他们可能不会被添加?它说我会得到一个IllegalStateException,它会被添加还是不被添加?
2 - 如果我们想在backstack中添加片段,我接受这样的事实:我不能使用它.它没有说的是你得到这个例外:
java.lang.IllegalStateException: This transaction is already being added to the back stack
Run Code Online (Sandbox Code Playgroud)
???? !!!!
所以我不能打电话给addToBackStack(String)
自己,因为它在内部为我打电话?对不起但是......什么?为什么?如果我不希望它被添加到Backstack中怎么办?如果我稍后尝试从后台堆栈中使用该片段但是因为它可能不会被添加,以后它不存在呢?
看起来这是我期待的东西commitAllowingStateLoss()
,但是我看到它commitNowAllowingStateLoss()
也存在,所以...它遵循什么样的逻辑?
TL; DR
commitNow()内部如何处理backstack?
我在下面有简单的代码
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, mFeedFragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
Run Code Online (Sandbox Code Playgroud)
这些代码行做了什么?
android fragmenttransaction fragmentmanager fragment-backstack
我正在开发一个使用导航抽屉图案的应用程序(使用DrawerLayout).
每次单击抽屉的项目,都会替换主容器中的片段.
但是,我不确定何时是进行片段交易的合适时机?抽屉开始关闭时?或者关闭后?
在google的documentaion示例中,您可以看到他们在项目单击后立即执行事务,然后关闭抽屉.
结果,抽屉看起来很迟钝而且不平滑,看起来非常糟糕(它也发生在我的应用中).
在Gmail和Google云端硬盘应用程序中,另一方面,它似乎是在抽屉关闭后进行交易(我是对吗?).
结果,抽屉没有延迟且非常平滑,但至少需要大约1秒钟(抽屉关闭所需的时间)才能看到下一个片段.
在立即进行片段交易时,似乎抽屉没有办法顺畅.
你觉得怎么样?
提前致谢!
android android-fragments fragmenttransaction navigation-drawer drawerlayout
我的错误:
java.lang.IllegalStateException:已经调用了commit
我的代码:
final FragmentTransaction fragmentTransaction =getFragmentManager().beginTransaction();
f1_fragment = new F1_Fragments();
f2_fragment = new F2_Fragments();
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
parent.getItemAtPosition(position);
if(position==0){
fragmentTransaction.replace(android.R.id.content, f1_fragment);
}else{
fragmentTransaction.replace(android.R.id.content, f2_fragment);
}
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
});
Run Code Online (Sandbox Code Playgroud) 我的场景:活动1由碎片A-> B-> C组成.使用以下代码添加所有碎片:
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.content, fragment, TAG);
ft.addToBackStack(TAG);
ft.commit();
Run Code Online (Sandbox Code Playgroud)
现在,从片段C开始,我想直接返回片段A.因此,我ft.addToBackStack(TAG)
在添加片段C时进行了评论.因此,当我从CI按下后退按钮时,直接在屏幕上显示片段A.
但是,片段C不会被A替换.事实上,这两个片段都是可见的.我该如何解决这个问题?
我的Android应用由三个片段:A,B和C.它们被加载到MainActivity
布局中定义的两个容器中.
当应用程序启动时,它会显示在left_container中加载的fragmentA和在right_container中加载的fragmentC.
如果按在按钮fragmentA,一个FragmentTransaction
改变FragmentC通过FragmentB.
一切都好.但是当我尝试使用加载的fragmentB的引用时出现问题 findFragmentByTag()
,因为它返回null
.我已经使用了方法替换,FragmentTransaction
并且我已经完成了它commit()
,但是没有办法调用FragmentB方法.我的代码:
MainActivity.java:
public class MainActivity extends Activity{
static String fragmentTag = "FRAGMENTB_TAG";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Adds the left container's fragment
getFragmentManager().beginTransaction().add(R.id.left_container, new FragmentA()).commit(); //Adds the fragment A to the left container
//Adds the right container's fragment
getFragmentManager().beginTransaction().add(R.id.right_container, new FragmentC()).commit(); //Adds the Fragment C …
Run Code Online (Sandbox Code Playgroud) 我试图从一个片段移动到另一个片段.它在片段事务期间显示以下错误 -
java.lang.IllegalArgumentException: No view found for id 0x1020002 (android:id/content) for fragment PhotosFragment2{41a57218 #3 id=0x1020002}
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:930)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1115)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1478)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:446)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:153)
at android.app.ActivityThread.main(ActivityThread.java:5086)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:821)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:584)
at dalvik.system.NativeStart.main(Native Method)
Run Code Online (Sandbox Code Playgroud)
下面是类.我使用了以下代码进行片段事务
Fragment fragment = new PhotosFragment2();
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.replace(android.R.id.content, fragment);
fragmentTransaction.commit();
Run Code Online (Sandbox Code Playgroud)
PhotosFragment.java
public class PhotosFragment extends Fragment {
private FragmentActivity myContext;
@Override
public void onAttach(Activity activity) {
myContext = (FragmentActivity) activity;
super.onAttach(activity);
} …
Run Code Online (Sandbox Code Playgroud) 我刚刚通过的文件去attach()
和detach()
方法FragmentTransaction
:
attach()
:在先前已从UI分离后重新附加片段detach(Fragment)
.这会导致其视图层次结构被重新创建,附加到UI并显示.
嗯,这是什么意思?
更具体地说,我看到了一个例子:
mMapFragment = new MapFragment();
ft.beginTransaction(mMapFragment)
.attach()
.add(R.id.container, mMapFragment)
.commit();
Run Code Online (Sandbox Code Playgroud)
我删除了attach()
并再次尝试:我没有发现任何差异.什么是attach
在这个例子吗?与此相比有何不同:
ft.beginTransaction()
.add(R.id.container, mMapFragment)
.commit();
Run Code Online (Sandbox Code Playgroud)如果上面的例子是不够好,以示区别.我只是想知道做的时候,我们需要调用attach()
和detach()
明确?如果你可以解释添加/删除/替换方面的差异会更好.