等待 FragmentTransaction 动画完成
Wait for FragmentTransaction animation to finish
我有一个 Activity,一个 EditText
和一个 Button
。一旦在 EditText 中输入了一个数字并单击了按钮,就会显示一个片段(覆盖整个屏幕)两秒钟,然后将其删除。两个事务都调用了 showCustomAnimations()
。在代码中,在删除 FragmentTransaction 上调用 commit()
后,软键盘通过 showSoftInput()
.
显示
我遇到的问题:当移除动画是运行并且Fragment已经滑出屏幕80%时,弹出软键盘。现在,如果您快速输入一个数字并按下按钮,应用程序会崩溃,因为之前的动画仍然是 运行.
我已经看到了几个答案,但我发现它们不够充分或无法正常工作。对 commitNow()
或 executePendingTransitions()
的任何调用都无济于事,因为事务已提交,问题是动画之后仍然是 运行。 getVisibleUserHint()
检查 Activity 是否可见的方法已弃用。
代码:
TrueFragment trueFragment = new TrueFragment();
fabNext.setOnClickListener(new View.OnClickListener() { //fabNext is my button
@Override
public void onClick(View v) {
fabNext.setEnabled(false); //blocking button to avoid clicking (... further code for this...)
inputManager.hideSoftInputFromWindow(constraintLayoutCalculating.getWindowToken(), 0); //hide Keyboard
final FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); //FragmentTransaction to show the Fragment
transaction.setCustomAnimations(R.animator.slide_in, 0);
transaction.add(R.id.constraintLayoutCalculating, trueFragment);
transaction.commitAllowingStateLoss();
getSupportFragmentManager().executePendingTransactions();
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
FragmentTransaction transaction2 = getSupportFragmentManager().beginTransaction(); //FragmentTransaction to remove the Fragment
transaction2.setCustomAnimations(0, R.animator.slide_out);
transaction2.remove(trueFragment);
transaction2.commitAllowingStateLoss();
editText.setText(null); //reset EditText
editText.requestFocus();
textInputLayout.setError(null);
inputManager.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT); //show Keyboard
fabNext.setEnabled(true); //reenable button at the end - Problem: Button made clickable again, even if the remove FragmentTransaction animation hasn't finished
}
}, 1000);
}
这就是我遇到的崩溃。在 Whosebug 上搜索显示它与启动 FragmentTransaction 而另一个尚未完成有关。
--------- beginning of crash
2020-02-17 10:27:29.787 23467-23467/my.top.secretpreciousname E/AndroidRuntime: FATAL EXCEPTION: main
my.top.secretpreciousname, PID: 23467
java.lang.IllegalStateException: Restarter must be created only during owner's initialization stage
at androidx.savedstate.SavedStateRegistryController.performRestore(SavedStateRegistryController.java:58)
at androidx.fragment.app.Fragment.performCreate(Fragment.java:2585)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:838)
at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1238)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1303)
at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:439)
at androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManagerImpl.java:2079)
at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1869)
at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1824)
at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1727)
at androidx.fragment.app.FragmentManagerImpl.executePendingTransactions(FragmentManagerImpl.java:183)
at my.top.secretpreciousname.CalculatingActivity.onClick(CalculatingActivity.java:254)
at android.view.View.performClick(View.java:7339)
at my.top.secretpreciousname.CalculatingActivity.onEditorAction(CalculatingActivity.java:320)
at android.widget.TextView.doKeyDown(TextView.java:8617)
at android.widget.TextView.onKeyDown(TextView.java:8486)
at android.view.KeyEvent.dispatch(KeyEvent.java:3359)
at android.view.View.dispatchKeyEvent(View.java:13312)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1912)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1912)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1912)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1912)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1912)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1912)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1912)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1912)
有好的解决办法吗?在此先感谢您的帮助。
事实证明我必须添加行
transaction2.addToBackStack(null);
到动画 FragmentTransaction 以实现在前一个事务完成其动画之前触发新事务时它不会崩溃。
仍然不确定这是否可以被视为有效的解决方案,因为实际上我不希望这些片段具有后台功能,所以我必须暂时阻止后退按钮或在每次交易后刷新后台。
我有一个 Activity,一个 EditText
和一个 Button
。一旦在 EditText 中输入了一个数字并单击了按钮,就会显示一个片段(覆盖整个屏幕)两秒钟,然后将其删除。两个事务都调用了 showCustomAnimations()
。在代码中,在删除 FragmentTransaction 上调用 commit()
后,软键盘通过 showSoftInput()
.
我遇到的问题:当移除动画是运行并且Fragment已经滑出屏幕80%时,弹出软键盘。现在,如果您快速输入一个数字并按下按钮,应用程序会崩溃,因为之前的动画仍然是 运行.
我已经看到了几个答案,但我发现它们不够充分或无法正常工作。对 commitNow()
或 executePendingTransitions()
的任何调用都无济于事,因为事务已提交,问题是动画之后仍然是 运行。 getVisibleUserHint()
检查 Activity 是否可见的方法已弃用。
代码:
TrueFragment trueFragment = new TrueFragment();
fabNext.setOnClickListener(new View.OnClickListener() { //fabNext is my button
@Override
public void onClick(View v) {
fabNext.setEnabled(false); //blocking button to avoid clicking (... further code for this...)
inputManager.hideSoftInputFromWindow(constraintLayoutCalculating.getWindowToken(), 0); //hide Keyboard
final FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); //FragmentTransaction to show the Fragment
transaction.setCustomAnimations(R.animator.slide_in, 0);
transaction.add(R.id.constraintLayoutCalculating, trueFragment);
transaction.commitAllowingStateLoss();
getSupportFragmentManager().executePendingTransactions();
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
FragmentTransaction transaction2 = getSupportFragmentManager().beginTransaction(); //FragmentTransaction to remove the Fragment
transaction2.setCustomAnimations(0, R.animator.slide_out);
transaction2.remove(trueFragment);
transaction2.commitAllowingStateLoss();
editText.setText(null); //reset EditText
editText.requestFocus();
textInputLayout.setError(null);
inputManager.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT); //show Keyboard
fabNext.setEnabled(true); //reenable button at the end - Problem: Button made clickable again, even if the remove FragmentTransaction animation hasn't finished
}
}, 1000);
}
这就是我遇到的崩溃。在 Whosebug 上搜索显示它与启动 FragmentTransaction 而另一个尚未完成有关。
--------- beginning of crash
2020-02-17 10:27:29.787 23467-23467/my.top.secretpreciousname E/AndroidRuntime: FATAL EXCEPTION: main
my.top.secretpreciousname, PID: 23467
java.lang.IllegalStateException: Restarter must be created only during owner's initialization stage
at androidx.savedstate.SavedStateRegistryController.performRestore(SavedStateRegistryController.java:58)
at androidx.fragment.app.Fragment.performCreate(Fragment.java:2585)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:838)
at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1238)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1303)
at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:439)
at androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManagerImpl.java:2079)
at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1869)
at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1824)
at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1727)
at androidx.fragment.app.FragmentManagerImpl.executePendingTransactions(FragmentManagerImpl.java:183)
at my.top.secretpreciousname.CalculatingActivity.onClick(CalculatingActivity.java:254)
at android.view.View.performClick(View.java:7339)
at my.top.secretpreciousname.CalculatingActivity.onEditorAction(CalculatingActivity.java:320)
at android.widget.TextView.doKeyDown(TextView.java:8617)
at android.widget.TextView.onKeyDown(TextView.java:8486)
at android.view.KeyEvent.dispatch(KeyEvent.java:3359)
at android.view.View.dispatchKeyEvent(View.java:13312)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1912)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1912)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1912)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1912)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1912)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1912)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1912)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1912)
有好的解决办法吗?在此先感谢您的帮助。
事实证明我必须添加行
transaction2.addToBackStack(null);
到动画 FragmentTransaction 以实现在前一个事务完成其动画之前触发新事务时它不会崩溃。 仍然不确定这是否可以被视为有效的解决方案,因为实际上我不希望这些片段具有后台功能,所以我必须暂时阻止后退按钮或在每次交易后刷新后台。