53

Google を使用していますDrawerLayout

アイテムをクリックすると、ドロワーがスムーズに閉じられ、Activity起動されます。これらの活動をFragments に変えることはできません。このため、アクティビティを起動してからドロワーを閉じることもできません。ドロワーを閉じると同時にアクティビティを起動すると、閉じるアニメーションが途切れます。

最初にスムーズに閉じてからアクティビティを起動したい場合、ユーザーが引き出しアイテムをクリックしてから、移動したいアクティビティが表示されるまでの待ち時間に問題があります。

各項目のクリック リスナーは次のようになります。

final View.OnClickListener mainItemClickListener = new View.OnClickListener() {
    @Override
    public void onClick(final View v) {
        mViewToLaunch = v;
        mDrawerLayout.closeDrawers();
    }
};

私のアクティビティも DrawerListener です。そのonDrawerClosedメソッドは次のようになります。

@Override
public synchronized void onDrawerClosed(final View view) {
    if (mViewToLaunch != null) {
        onDrawerItemSelection(mViewToLaunch);
        mViewToLaunch = null;
    }
}

onDrawerItemSelection5 つのアクティビティのうちの 1 つを開始するだけです。

私は何もしませonPauseDrawerActivity

私はこれを計測しており、onClick が呼び出された瞬間から onDrawerClosed が終了する瞬間まで、平均で 500 ~ 650 ミリ秒かかります。

ドロワーが閉じてから、対応するアクティビティが開始されるまでに、顕著な遅延があります。

いくつかのことが起こっていることに気づきました:

  • 数ミリ秒 (300 としましょう) の終了アニメーションが発生します。

  • 次に、ドロワーが視覚的に閉じてからそのリスナーが起動するまでに、おそらくある程度の待ち時間があります。ソースを見てDrawerLayout、これがどの程度起こっているかを正確に把握しようとしていますが、まだ把握していません。

  • 次に、起動されたアクティビティがスタートアップ ライフサイクル メソッドを実行するのにかかる時間 (最大 を含む) がありonResumeます。これはまだ計測していませんが、約 200 ~ 300 ミリ秒と見積もっています。

これは、間違った道をたどると非常にコストがかかる問題のように思えるので、完全に理解したいと思います。

解決策の 1 つは、終了時のアニメーションをスキップすることですが、そのままにしておきたいと思っていました。

移行時間をできるだけ短縮するにはどうすればよいですか?

4

7 に答える 7

10

Google IOsched 2015 は (設定を除いて) 非常にスムーズに実行されます。その理由は、ドロワーの実装方法と起動方法にあります。

まず、ハンドラーを使用して遅延を起動します。

        // launch the target Activity after a short delay, to allow the close animation to play
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                goToNavDrawerItem(itemId);
            }
        }, NAVDRAWER_LAUNCH_DELAY);

遅延は次のとおりです。

private static final int NAVDRAWER_LAUNCH_DELAY = 250;

彼らが行うもう 1 つのことは、アクティビティ onCreate() 内の次のコードで起動されるアクティビティからアニメーションを削除することです。

overridePendingTransition(0, 0);

ソースを表示するには、gitに移動します。

于 2015-10-20T12:15:05.497 に答える
4

私は以下のようなアプローチを使用しています。スムーズに動作します。

public class MainActivity extends BaseActivity implements NavigationView.OnNavigationItemSelectedListener {

    private DrawerLayout drawerLayout;
    private MenuItem menuItemWaiting;

    /* other stuff here ... */

    private void setupDrawerLayout() {

        /* other stuff here ... */

        drawerLayout.addDrawerListener(new DrawerLayout.SimpleDrawerListener() {
            @Override
            public void onDrawerClosed(View drawerView) {
                super.onDrawerClosed(drawerView);
                if(menuItemWaiting != null) {
                    onNavigationItemSelected(menuItemWaiting);
                }
            }
        });

    }

    @Override
    public boolean onNavigationItemSelected(MenuItem menuItem) {

        menuItemWaiting = null;
        if(drawerLayout.isDrawerOpen(GravityCompat.START)) {
            menuItemWaiting = menuItem;
            drawerLayout.closeDrawers();
            return false;
        };

        switch(menuItem.getItemId()) {
            case R.id.drawer_action:
                startActivity(new Intent(this, SecondActivity.class));

            /* other stuff here ... */

        }
        return true;
    }
}

ActionBarDrawerToggleと同じ:

drawerToggle = new ActionBarDrawerToggle(this, drawerLayout, R.string.drawer_open, R.string.drawer_close){
    @Override
    public void onDrawerClosed(View drawerView) {
        super.onDrawerClosed(drawerView);
        if(menuItemWaiting != null) {
            onNavigationItemSelected(menuItemWaiting);
        }
    }
};
drawerLayout.setDrawerListener(drawerToggle);
于 2016-04-22T13:08:45.483 に答える
2

より良い方法は、onDrawerSlide(View, float) メソッドを使用し、slideOffset が 0 になったらアクティビティを開始することです。以下を参照してください。

public void onDrawerSlide(View drawerView, float slideOffset) {
    if (slideOffset <= 0 && mPendingDrawerIntent != null) {
        startActivity(mPendingDrawerIntent);
        mPendingDrawerIntent = null;
    }
}

Drawer の ListView.OnItemClickListener onItemClick メソッドで mPendingDrawerIntent を設定するだけです。

于 2014-04-08T16:46:28.117 に答える