web-dev-qa-db-ja.com

プログラムでアニメーション付きの引き出しレイアウトを開くことはできますか?

次のライブラリを使用してアプリドロワーを作成しました: http://developer.Android.com/training/implementing-navigation/nav-drawer.html

アプリを開くときにナビゲーションドロワーをアニメーションで表示したい。どうやってやるの?

21
benleung

事前描画リスナー、別名セーフウェイ

これはpredrawリスナーの例です。それは文字通り、できるだけ早くアニメーションを開始します。これを2番目に示すランナブルと組み合わせることもできます。 2つを組み合わせて表示するのではなく、別々に表示します。

@Override
protected void onCreate(Bundle savedInstanceState) {
    ...
    // Building NavDrawer logic here. Just a method call would be best.
    ...

    ViewTreeObserver vto = drawer.getViewTreeObserver();
    if (vto != null) vto.addOnPreDrawListener(new ShouldShowListener(drawer));
}

private static class ShouldShowListener implements OnPreDrawListener {

    private final DrawerLayout drawerLayout;

    private ShouldShowListener(DrawerLayout drawerLayout) {
        this.drawerLayout= drawerLayout;
    }

    @Override
    public boolean onPreDraw() {
        if (view != null) {
            ViewTreeObserver vto = view.getViewTreeObserver();
            if (vto != null) {
                vto.removeOnPreDrawListener(this);
            }
        }

        drawerLayout.openDrawer(Gravity.LEFT);
        return true;
    }
}

PostDelay Runnable、別名リビング危険

// Delay is in milliseconds
static final int DRAWER_DELAY = 200;

@Override
protected void onCreate(Bundle savedInstanceState) {
    ...
    // Building NavDrawer logic here. Just a method call would be best.
    ...
    new Handler().postDelayed(openDrawerRunnable(), DRAWER_DELAY);
}

private Runnable openDrawerRunnable() {
    return new Runnable() {

        @Override
        public void run() {
            drawerLayout.openDrawer(Gravity.LEFT);
        }
    }
}

[〜#〜]警告[〜#〜]

アプリの起動時に初めて回転する場合BOOM!詳細については、このブログ投稿をお読みください http:// corner。 squareup.com/2013/12/Android-main-thread-2.html 。最善の方法は、プリドローリスナーを使用するか、onPauseでランナブルを削除することです。

53
MinceMan

DrawerLayoutopenDrawer(int gravity)を呼び出すと、アニメーションでドロワーを開くことができます。

7
Brayden

引き出しの開口部をアニメーション化するには、drawerLayout.openDrawer(Gravity.LEFT)を呼び出す必要があります。アクティビティライフサイクルの早い段階で呼び出しを行うと、引き出しはアニメーション化されません。

最も簡単な解決策は、onCreate()でフラグを設定し、onResume()でそれを処理することです。

フラグが設定されるのは、saveedInstanceStateがnullで、アクティビティがバックグラウンドから再開されていないことを示す場合に限るようにします。向きを変えたり、アプリケーションを切り替えたりするたびに、引き出しがスライドするのは望ましくありません。

public class MainActivity extends ActionBarActivity {
    private DrawerLayout drawerLayout;
    private boolean firstResume = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        drawerLayout = (DrawerLayout)findViewById(R.id.drawer);

        if(savedInstanceState == null){
            firstResume = true;
        }
    }

    @Override
    protected void onResume() {
        super.onResume();

        if(firstResume) {
            drawerLayout.openDrawer(Gravity.LEFT);
        }

        firstResume = false;
    }
}

OnPreDrawListenerを使用することもできますが、onPreDrawが複数回呼び出されるため、ドロワーを開いた後にリスナーを削除する必要があるため、少し不必要に複雑に感じます。また、preDrawは、ドロワーレイアウトの内部実装であるドロワーをアクティブ化するのに適した時間であると想定しています。将来の実装では、たとえばonDrawが完了するまで正しくアニメーション化されない可能性があります。

ドロワーの開放をミリ秒単位で遅らせることは、この問題を解決するための危険な方法です。最悪の場合、ユーザーがすばやく離れると、onDestroyの後にドロワーを開く呼び出しが発生する可能性があります。

1
Jared Kells