web-dev-qa-db-ja.com

ActionBarの非表示アニメーションを変更しますか?

デフォルトでは、Android 3.0+で、ActionBar.hide()/ show()が呼び出されると、バーは短いフェードイン/フェードアウトアニメーションでアニメーション化されます。

XMLスタイル属性がないようです このリストに アニメーションリソースに関連付けられています。

このアニメーションを変更する方法はありますか?私の場合、アニメーションの時間を変更したいだけですが、スライドアニメーションを作成することもできますか?

24
blork

番号。

少なくとも3.0、3.1、または3.2ではありません。 com.Android.internal.app.ActionBarImplの逆コンパイルされたソースを見ると、アニメーションがハードコーディングされていることがわかります。

例: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 [〜#〜]

ICSとJellyBeanについても同じことが言えます

34
Jake Wharton

ActionBarアニメーションを無効にするためのハック(ソースコードを調べることで見つかります)は、次の方法でイントロスペクションを行うことで実行できます。

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

もちろん醜いですが、これは実際には機能します。少なくともAndroid v4.2から。

15

どちらの解決策も私には機能しないので、これを試してアニメーションをまったく無効にします。

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);
    }
}

そして、それは私にとってはうまく機能します。アクションバーviewGroup全体をアニメーション化して、同様の効果を実現することができます。

4
MikhailKrishtop

support-v7-compatを使用する場合、次のように非表示アニメーションを無効にできます。

@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){
            //....
        }
    }
}
4
panwy

はい、あなたは間違いなくそうすることができます。

最初に、次のようなActionBarビューを取得します。

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

次に、次のようにビューに直接アニメーションを適用できます。

View actionbar = getActionBarView();
actionbar.setTranslation(-48); // move it out of the screen
1
habitats