Changing the ActionBar hide animation?

前端 未结 5 1369
滥情空心
滥情空心 2021-02-01 18:09

By default in Android 3.0+, when ActionBar.hide()/show() are called the bar is animated with a brief fade in/out animation.

There does not seem to be an XML style attri

相关标签:
5条回答
  • 2021-02-01 18:23

    Yes, you most certainly can.

    You first get the ActionBar view like this:

    public View getActionBarView() {
        Window window = getActivity().getWindow();
        View v = window.getDecorView();
        int resId = getResources().getIdentifier("action_bar_container", "id", "android");
        return v.findViewById(resId);
    }
    

    Then you can apply animations directly on the view like this:

    View actionbar = getActionBarView();
    actionbar.setTranslation(-48); // move it out of the screen
    
    0 讨论(0)
  • 2021-02-01 18:25

    if you use support-v7-compat, you can disable hide animation like this:

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        //消除动画效果
        disableABCShowHideAnimation(getSupportActionBar());
        return super.onCreateOptionsMenu(menu);
    }
    
    
    
    public static void disableABCShowHideAnimation(ActionBar actionBar) {
        try
        {
            actionBar.getClass().getDeclaredMethod("setShowHideAnimationEnabled", boolean.class).invoke(actionBar, false);
        }
        catch (Exception exception)
        {
            try {
                Field mActionBarField = actionBar.getClass().getSuperclass().getDeclaredField("mActionBar");
                mActionBarField.setAccessible(true);
                Object icsActionBar = mActionBarField.get(actionBar);
                Field mShowHideAnimationEnabledField = icsActionBar.getClass().getDeclaredField("mShowHideAnimationEnabled");
                mShowHideAnimationEnabledField.setAccessible(true);
                mShowHideAnimationEnabledField.set(icsActionBar,false);
                Field mCurrentShowAnimField = icsActionBar.getClass().getDeclaredField("mCurrentShowAnim");
                mCurrentShowAnimField.setAccessible(true);
                mCurrentShowAnimField.set(icsActionBar,null);
                //icsActionBar.getClass().getDeclaredMethod("setShowHideAnimationEnabled", boolean.class).invoke(icsActionBar, false);
            }catch (Exception e){
                //....
            }
        }
    }
    
    0 讨论(0)
  • 2021-02-01 18:25

    Neither of solutions doesn't work for me so I try this to disable animation at all:

    public void setActionBarVisible(boolean isVisible) {
        View decorView = getWindow().getDecorView();
        int resId;
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB
            || Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            resId = getResources().getIdentifier(
                    "action_bar_container", "id", getPackageName());
        } else {
            resId = Resources.getSystem().getIdentifier(
                    "action_bar_container", "id", "android");
        }
        if (resId != 0) {
            decorView.findViewById(resId).setVisibility(isVisible ? View.VISIBLE : View.GONE);
        }
    }
    

    And it works just fine for me. You can try to animate whole action bar viewGroup to achieve similar effect.

    0 讨论(0)
  • 2021-02-01 18:27

    A hack for disabling the ActionBar animation (found by inspecting the source code) can be done through introspection via:

    try
    {
      getActionBar().getClass().getDeclaredMethod("setShowHideAnimationEnabled", boolean.class).invoke(getActionBar(), false);
    }
    catch (Exception exception)
    {
      // Too bad, the animation will be run ;(
    }
    

    Ugly, of course, but this actually work, at least from Android v4.2.

    0 讨论(0)
  • 2021-02-01 18:34

    No.

    At least not in 3.0, 3.1, or 3.2. If you look at the decompiled sources of com.android.internal.app.ActionBarImpl you'll find that the animations are hard-coded.

    E.g., from 3.2:

    .method public hide()V
        .locals 8
    
        .prologue
        const/4 v5, 0x0
    
        const/4 v7, 0x0
    
        const/4 v6, 0x1
    
        .line 529
        iget-object v2, p0, Lcom/android/internal/app/ActionBarImpl;->mCurrentAnim:Landroid/animation/Animator;
    
        if-eqz v2, :cond_0
    
        .line 530
        iget-object v2, p0, Lcom/android/internal/app/ActionBarImpl;->mCurrentAnim:Landroid/animation/Animator;
    
        invoke-virtual {v2}, Landroid/animation/Animator;->end()V
    
        .line 532
        :cond_0
        iget-object v2, p0, Lcom/android/internal/app/ActionBarImpl;->mContainerView:Lcom/android/internal/widget/ActionBarContainer;
    
        invoke-virtual {v2}, Lcom/android/internal/widget/ActionBarContainer;->getVisibility()I
    
        move-result v2
    
        const/16 v3, 0x8
    
        if-ne v2, v3, :cond_1
    
        .line 553
        :goto_0
        return-void
    
        .line 536
        :cond_1
        iget-boolean v2, p0, Lcom/android/internal/app/ActionBarImpl;->mShowHideAnimationEnabled:Z
    
        if-eqz v2, :cond_3
    
        .line 537
        iget-object v2, p0, Lcom/android/internal/app/ActionBarImpl;->mContainerView:Lcom/android/internal/widget/ActionBarContainer;
    
        const/high16 v3, 0x3f80
    
        invoke-virtual {v2, v3}, Lcom/android/internal/widget/ActionBarContainer;->setAlpha(F)V
    
        .line 538
        iget-object v2, p0, Lcom/android/internal/app/ActionBarImpl;->mContainerView:Lcom/android/internal/widget/ActionBarContainer;
    
        invoke-virtual {v2, v6}, Lcom/android/internal/widget/ActionBarContainer;->setTransitioning(Z)V
    
        .line 539
        new-instance v0, Landroid/animation/AnimatorSet;
    
        invoke-direct {v0}, Landroid/animation/AnimatorSet;-><init>()V
    
        .line 540
        .local v0, anim:Landroid/animation/AnimatorSet;
        iget-object v2, p0, Lcom/android/internal/app/ActionBarImpl;->mContainerView:Lcom/android/internal/widget/ActionBarContainer;
    
        const-string v3, "alpha"
    
        new-array v4, v6, [F
    
        aput v5, v4, v7
    
        invoke-static {v2, v3, v4}, Landroid/animation/ObjectAnimator;->ofFloat(Ljava/lang/Object;Ljava/lang/String;[F)Landroid/animation/ObjectAnimator;
    
        move-result-object v2
    
        invoke-virtual {v0, v2}, Landroid/animation/AnimatorSet;->play(Landroid/animation/Animator;)Landroid/animation/AnimatorSet$Builder;
    
        move-result-object v1
    
        .line 541
        .local v1, b:Landroid/animation/AnimatorSet$Builder;
        iget-object v2, p0, Lcom/android/internal/app/ActionBarImpl;->mContentView:Landroid/view/View;
    
        if-eqz v2, :cond_2
    
        .line 542
        iget-object v2, p0, Lcom/android/internal/app/ActionBarImpl;->mContentView:Landroid/view/View;
    
        const-string/jumbo v3, "translationY"
    
        const/4 v4, 0x2
    
        new-array v4, v4, [F
    
        aput v5, v4, v7
    
        iget-object v5, p0, Lcom/android/internal/app/ActionBarImpl;->mContainerView:Lcom/android/internal/widget/ActionBarContainer;
    
        invoke-virtual {v5}, Lcom/android/internal/widget/ActionBarContainer;->getHeight()I
    
        move-result v5
    
        neg-int v5, v5
    
        int-to-float v5, v5
    
        aput v5, v4, v6
    
        invoke-static {v2, v3, v4}, Landroid/animation/ObjectAnimator;->ofFloat(Ljava/lang/Object;Ljava/lang/String;[F)Landroid/animation/ObjectAnimator;
    
        move-result-object v2
    
        invoke-virtual {v1, v2}, Landroid/animation/AnimatorSet$Builder;->with(Landroid/animation/Animator;)Landroid/animation/AnimatorSet$Builder;
    
        .line 544
        iget-object v2, p0, Lcom/android/internal/app/ActionBarImpl;->mContainerView:Lcom/android/internal/widget/ActionBarContainer;
    
        const-string/jumbo v3, "translationY"
    
        new-array v4, v6, [F
    
        iget-object v5, p0, Lcom/android/internal/app/ActionBarImpl;->mContainerView:Lcom/android/internal/widget/ActionBarContainer;
    
        invoke-virtual {v5}, Lcom/android/internal/widget/ActionBarContainer;->getHeight()I
    
        move-result v5
    
        neg-int v5, v5
    
        int-to-float v5, v5
    
        aput v5, v4, v7
    
        invoke-static {v2, v3, v4}, Landroid/animation/ObjectAnimator;->ofFloat(Ljava/lang/Object;Ljava/lang/String;[F)Landroid/animation/ObjectAnimator;
    
        move-result-object v2
    
        invoke-virtual {v1, v2}, Landroid/animation/AnimatorSet$Builder;->with(Landroid/animation/Animator;)Landroid/animation/AnimatorSet$Builder;
    
        .line 547
        :cond_2
        iget-object v2, p0, Lcom/android/internal/app/ActionBarImpl;->mHideListener:Landroid/animation/Animator$AnimatorListener;
    
        invoke-virtual {v0, v2}, Landroid/animation/AnimatorSet;->addListener(Landroid/animation/Animator$AnimatorListener;)V
    
        .line 548
        iput-object v0, p0, Lcom/android/internal/app/ActionBarImpl;->mCurrentAnim:Landroid/animation/Animator;
    
        .line 549
        invoke-virtual {v0}, Landroid/animation/AnimatorSet;->start()V
    
        goto :goto_0
    
        .line 551
        .end local v0           #anim:Landroid/animation/AnimatorSet;
        .end local v1           #b:Landroid/animation/AnimatorSet$Builder;
        :cond_3
        iget-object v2, p0, Lcom/android/internal/app/ActionBarImpl;->mHideListener:Landroid/animation/Animator$AnimatorListener;
    
        const/4 v3, 0x0
    
        invoke-interface {v2, v3}, Landroid/animation/Animator$AnimatorListener;->onAnimationEnd(Landroid/animation/Animator;)V
    
        goto :goto_0
    .end method
    

    UPDATE

    Same goes for ICS and JellyBean

    0 讨论(0)
提交回复
热议问题