更改ActionBar隐藏animation?

默认情况下,在Android 3.0以上的版本中,当调用ActionBar.hide()/ show()时,会使用简短的淡入/淡出animation来animation。

这个列表中似乎没有与animation资源关联的XML样式属性。

有什么方法可以改变这个animation? 在我的情况下,我只是想改变animation的时间,但也有可能有一个滑动animation?

Solutions Collecting From Web of "更改ActionBar隐藏animation?"

没有。

至less不在3.0,3.1或3.2中。 如果你看看反编译的com.android.internal.app.ActionBarImpl源代码,你会发现这些animation是硬编码的。

例如,从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和果冻豆也一样

禁用ActionBaranimation(通过检查源代码find)的黑客可以通过内省完成:

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

当然,丑陋,但实际上,至less从Android v4.2。

如果您使用support-v7-compat,则可以禁用隐藏animation,如下所示:

 @Override public boolean onCreateOptionsMenu(Menu menu) { //消除animation效果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){ //.... } } } 

这两种解决scheme都不适用于我,所以我尝试这样做来禁用animation:

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

它对我来说很好。 你可以尝试animation整个动作栏viewGroup来达到类似的效果。

是的,你当然可以。

你首先得到这样的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); } 

然后,您可以直接在视图上应用animation,如下所示:

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