Android 在不播放Pop动画的情况下将片段向后弹出
我使用以下代码将片段推送到片段堆栈上:Android 在不播放Pop动画的情况下将片段向后弹出,android,android-fragments,android-animation,Android,Android Fragments,Android Animation,我使用以下代码将片段推送到片段堆栈上: FragmentManager fragmentManager = getActivity().getSupportFragmentManager(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); fragmentTransaction.setCustomAnimations(R.anim.slide_in_right, R.anim.slide
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_right,
R.anim.slide_in_left, R.anim.slide_out_left);
fragmentTransaction.replace(getId(), newFragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
这样,当片段堆栈弹出时(例如,按下后退按钮),将播放片段弹出动画。但是,在某些情况下,我希望在不显示此动画的情况下弹出片段backbackback,例如,因为我刚从另一个活动返回,并且希望在不显示动画的情况下立即显示上一个片段
FragmentManager fm = getSupportFragmentManager();
if (fm.getBackStackEntryCount() > 0) {
fm.popBackStack();
overridePendingTransition(0, 0);
}
导航示例如下所示:
- 用户在开始屏幕上显示根片段
- 他在根片段上选择一个项目,然后显示一个新片段以显示该项目的详细信息。它使用一个片段事务来实现这一点,该事务为push和pop case设置动画(因此,当用户按下back按钮时,转换被设置为动画)
- 他从这个片段开始一个活动,该活动(出于任何原因)删除刚才显示的项目
- 当这个活动结束时,我想返回到根片段,而不显示“细节片段”的“弹出动画”
有没有办法在不播放指定的pop动画的情况下弹出片段回退?只需使用另一种重载方法
setCustomAnimation()
,其中不设置R.anim.slide\u
这会解决你的问题
干杯:)
用户在开始屏幕上显示根片段
假设根片段包含在活动A中
他在根片段上选择一个项目,然后显示一个新片段以显示该项目的详细信息。它使用一个片段事务来实现这一点,该事务为push和pop case设置动画(因此,当用户按下back按钮时,转换被设置为动画)
事务被添加到后堆栈中。这意味着当从细节片段中按下后退按钮时,弹出过程将设置动画
他从这个片段开始一个活动,该活动(出于任何原因)删除刚才显示的项目
假设是活动B
当这个活动结束时,我想返回到根片段,而不显示“细节片段”的“弹出动画”
获得此行为的一种方法是在活动B中执行此操作:
Intent intent = new Intent(this, A.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
finish();
这将启动活动A,并根据将其重置为其根状态。(检查本节最后一段,其中说明“此启动模式也可与FLAG_Activity_NEW_TASK一起使用,以获得良好效果:……)
使用此配置,动画将在默认情况下显示,而在特殊情况下,可以使用以下方式控制动画:
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
在没有任何动画的情况下启动新活动。如果您确实需要任何动画,可以使用
重写PendingTransition
方法来执行。因此,对于支持库,请执行以下操作:
在应该具有自定义pop动画的片段中,您可以使用自己的自定义动画覆盖onCreateAnimation。你可以得到它,并根据需要设置某种参数。可能需要做一些额外的工作,才能使它与常规片段一起工作
下面是我覆盖它并更改设置的持续时间的示例:
@Override
public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) {
Animation anim = (Animation) super.onCreateAnimation(transit, enter, nextAnim);
if(!enter) {
if(anim != null) {
anim.setDuration(0); // This doesn't seem to be called.
return anim;
} else {
Animation test = new TestAnimation();
test.setDuration(0);
return test;
}
}
return anim;
}
private class TestAnimation extends Animation {
}
Warpzit走的是对的,他只是没有很好地解决你的具体问题。我遇到了完全相同的问题,下面是我如何解决它的 首先,我创建了一个静态布尔变量(为了简单起见,让我们把它放在FragmentUtils类中) 然后,在您拥有的每个片段中,您需要重写onCreateAnimation方法
@Override
public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) {
if (FragmentUtils.sDisableFragmentAnimations) {
Animation a = new Animation() {};
a.setDuration(0);
return a;
}
return super.onCreateAnimation(transit, enter, nextAnim);
}
然后,当你需要从你的活动中清除障碍时,只需执行以下操作
public void clearBackStack() {
FragmentUtils.sDisableFragmentAnimations = true;
getSupportFragmentManager().popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
FragmentUtils.sDisableFragmentAnimations = false;
}
瞧,对clearBackStack()的调用将使您返回到根片段中,而不需要任何转换动画
希望大G将来会增加一种不那么愚蠢的方式来做这件事。在回答你的问题之前,我需要自己问一个问题 在第二个活动的onBackPressed()方法中,可以访问第一个活动的backbackback吗 如果是,那么您可以调用popBackStackImmediate(字符串trnaisiotName,包含int),它将从backstack中删除片段转换,您不需要担心动画
我假设您可以访问上一个活动的后台,否则这将不起作用请回复Geoff和plackemacher的评论 您可以尝试从此片段中删除所有视图。然后片段将显示,但它应该是透明的 删除all-1(我使用导航抽屉,所以抽屉碎片应该保留)碎片:
int size = fragmentsList.size ()-1;
FragmentTransaction transaction = fragmentManager.beginTransaction ();
transaction.setTransition (FragmentTransaction.TRANSIT_NONE);
Fragment fragment;
for (int i = size ; i > 0 ; i--)
{
fragment = fragmentsList.get (i);
if(fragment != null)
{
View viewContainer = fragment.getView ();
if (viewContainer != null)
{
((ViewGroup) viewContainer).removeAllViews ();
}
transaction.remove (fragment);
}
}
size = fragmentManager.getBackStackEntryCount ();
for (int i = 0; i < size ; i++)
{
fragmentManager.popBackStack (null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
}
int size=fragmentsList.size()-1;
FragmentTransaction=fragmentManager.beginTransaction();
transaction.setTransition(FragmentTransaction.TRANSIT_无);
片段;
对于(int i=size;i>0;i--)
{
fragment=fragmentsList.get(i);
if(片段!=null)
{
View viewContainer=fragment.getView();
如果(viewContainer!=null)
{
((ViewGroup)viewContainer);
}
transaction.remove(片段);
}
}
size=fragmentManager.getBackStackEntryCount();
对于(int i=0;i
对不起,我的英语是这很容易通过
覆盖transition(int-enterAnim,int-exitAnim)
和0来实现,因为没有动画
FragmentManager fm = getSupportFragmentManager();
if (fm.getBackStackEntryCount() > 0) {
fm.popBackStack();
overridePendingTransition(0, 0);
}
所以,我想建议对@Geoff的答案做一个小的修改
与其使用全局静态布尔值,不如使用局部非静态布尔值。这就是我想到的
创建一个接口
public interface TransitionAnimator {
void disableTransitionAnimation();
void enableTransitionAnimation();
}
使片段实现该接口
public class MyFragment extends Fragment implements TransitionAnimator {
private boolean mTransitionAnimation;
@Override
public void disableTransitionAnimation() {
mTransitionAnimation = false;
}
@Override
public void enableTransitionAnimation() {
mTransitionAnimation = true;
}
@Override
public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) {
Animation result;
if (!mTransitionAnimation) {
Animation dummyAnimation = new Animation() {
};
dummyAnimation.setDuration(0);
result = dummyAnimation;
} else {
result = super.onCreateAnimation(transit, enter, nextAnim);
}
return result;
}
然后,当你想禁用trans
if (fragment instanceof TransitionAnimator) {
((TransitionAnimator) fragment).disableTransitionAnimation();
}
if (fragment instanceof TransitionAnimator) {
((TransitionAnimator) fragment).enableTransitionAnimation();
}
List<Fragment> fragments = getSupportFragmentManager().getFragments();
for (Fragment fragment : fragments) {
if (fragment instanceof TransitionAnimator) {
// disable animations
((TransitionAnimator) fragment).disableTransitionAnimation();
}
}
interface BaseActivityCallback
{
void addFragment ( BaseFragment f, int containerResId );
void popFragment ( boolean silently );
}
class BaseActivity extends android.support.v4.app.FragmentActivity implements BaseActivityCallback
{
public void addFragment ( BaseFragment f, int containerResId )
{
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.setCustomAnimations(R.anim.enter, R.anim.exit, R.anim.enter, R.anim.pop_exit); // http://stackoverflow.com/a/17488542/2412477
ft.addToBackStack(DEFAULT_FRAGMENT_STACK_NAME);
ft.replace(containerResId, fragment);
ft.commitAllowingStateLoss();
}
public void popFragment ( boolean silently )
{
FragmentManager fm = getSupportFragmentManager();
if ( silently ) {
int count = fm.getFragments().size();
BaseFragment f = (BaseFragment)fm.getFragments().get(count-1);
f.setDisableTransitionAnimations(true);
}
fm.popBackStackImmediate();
}
}
public abstract class BaseFragment extends android.support.v4.app.Fragment
{
private static final String TAG = "BaseFragment";
private final String STATE_DISABLE_TRANSITION_ANIMATIONS = TAG+".stateDisableTransitionAnimations";
protected BaseActivityCallback baseActivityCallback;
private boolean disableTransitionAnimations;
@Override
public void onCreate ( @Nullable Bundle savedInstanceState )
{
super.onCreate(savedInstanceState);
disableTransitionAnimations = (savedInstanceState==null ? false : savedInstanceState.getBoolean(STATE_DISABLE_TRANSITION_ANIMATIONS, false));
}
@Override
public void onAttach ( Context context )
{
super.onAttach(context);
baseActivityCallback = (BaseActivityCallback)context;
}
@Override
public void onSaveInstanceState ( Bundle outState )
{
super.onSaveInstanceState(outState);
outState.putBoolean(STATE_DISABLE_TRANSITION_ANIMATIONS, disableTransitionAnimations);
}
@Override
public Animation onCreateAnimation ( int transit, boolean enter, int nextAnim )
{
if ( disableTransitionAnimations ) {
Animation nop = new Animation(){};
nop.setDuration(0);
return nop;
}
return super.onCreateAnimation(transit, enter, nextAnim);
}
public void setDisableTransitionAnimations ( boolean disableTransitionAnimations )
{
this.disableTransitionAnimations = disableTransitionAnimations; // http://stackoverflow.com/a/11253987/2412477
}
}
public class MainActivity extends BaseActivity
{
protected void onCreate ( Bundle savedInstanceState )
{
setContentView(R.layout.main_activity);
...
if ( getSupportFragmentManager().getFragments() != null && !getSupportFragmentManager().getFragments().isEmpty() ) {
addFragment( FragmentA.newInstance(), R.id.main_activity_fragment_container );
}
}
...
}
public class FragmentA extends BaseFragment
{
public View onCreateView ( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState )
{
ViewGroup root = (ViewGroup)inflater.inflate(R.layout.fragment_a, container, false);
...
root.findViewById(R.id.fragment_a_next_button)
.setOnClickListener( new View.OnClickListener() {
public void onClick ( View v ) {
baseActivityCallback.addFragment( FragmentB.newInstance(), R.id.main_activity_fragment_container );
}
});
}
}
public class FragmentB extends BaseFragment
{
public View onCreateView ( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState )
{
ViewGroup root = (ViewGroup)inflater.inflate(R.layout.fragment_b, container, false);
...
root.findViewById(R.id.fragment_b_pop_silently_button)
.setOnClickListener( new View.OnClickListener() {
public void onClick ( View v ) {
baseActivityCallback.popFragment( true );
}
});
}
}
@Override
public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) {
if(!enter){
Animation a = new Animation() {};
a.setDuration(0);
return a;
}
return super.onCreateAnimation(transit, enter, nextAnim);
}
for (fragment in supportFragmentManager.fragments) {
removeFragment(fragment)
}
if (supportFragmentManager.backStackEntryCount > 0) {
supportFragmentManager.popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE)
}
supportFragmentTransaction.beginTransaction()
.setReorderingAllowed(true)
.addToBackStack(null)
.setCustomAnimations(
android.R.anim.fade_in,
android.R.anim.fade_out,
android.R.anim.fade_in,
android.R.anim.fade_out
)
.replace(yourContainer.id, yourFragment)
.commit()