デフォルトでは、Android 3.0+で、ActionBar.hide()/ show()が呼び出されると、バーは短いフェードイン/フェードアウトアニメーションでアニメーション化されます。
XMLスタイル属性がないようです このリストに アニメーションリソースに関連付けられています。
このアニメーションを変更する方法はありますか?私の場合、アニメーションの時間を変更したいだけですが、スライドアニメーションを作成することもできますか?
番号。
少なくとも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についても同じことが言えます
ActionBarアニメーションを無効にするためのハック(ソースコードを調べることで見つかります)は、次の方法でイントロスペクションを行うことで実行できます。
try
{
getActionBar().getClass().getDeclaredMethod("setShowHideAnimationEnabled", boolean.class).invoke(getActionBar(), false);
}
catch (Exception exception)
{
// Too bad, the animation will be run ;(
}
もちろん醜いですが、これは実際には機能します。少なくともAndroid v4.2から。
どちらの解決策も私には機能しないので、これを試してアニメーションをまったく無効にします。
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全体をアニメーション化して、同様の効果を実現することができます。
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){
//....
}
}
}
はい、あなたは間違いなくそうすることができます。
最初に、次のような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