web-dev-qa-db-ja.com

Android NavigationDrawerを介してナビゲートすると、Navigation Componentに遅延が発生します

アプリをNavigation Architecture Componentsに更新していますが、スムーズに閉じないNavigationDrawerに表示されるフラグメントを置き換えるラグがあります。

今まで、私はこのアプローチに従っていました:

https://vikrammnit.wordpress.com/2016/03/28/facing-navigation-drawer-item-onclick-lag/

したがって、グリッチを回避するために、onDrawerClosedではなくonNavigationItemSelectedに移動します。

これは非常に一般的な問題でしたが、再び戻ってきました。ナビゲーションコンポーネントを使用すると、再び遅延が発生し、onDrawerClosedに実装する方法がわかりません。

これらは、ナビゲーションコンポーネントより前の古い回答です。

Androidのナビゲーションドロアーラグ

DrawerLayoutのアイテムのクリック-フラグメントを置き換える適切なタイミングはいつですか?

どうもありがとうございました。

16
Javier Delgado

この回答を書いている今、この問題に取り組んでいます。いくつかのテストの後、作成したコード(RecyclerViewアダプターを初期化してデータを入力する、またはUIを構成するなど)が断片化して実行していると、ドロワーがすべて同時に発生するため、遅延が発生することがわかりました。

今私が得た最良のアイデアは、onDrawerClosedに依存するいくつかの古いソリューションと同様です。ドロワーが閉じるまで、コードの実行を断片的に遅らせます。ドロワーを閉じる前にフラグメントのレイアウトが表示されるので、高速で応答性が高くなります。

ナビゲーションコンポーネントも使用していることに注意してください。

最初に、インターフェースを作成し、フラグメントを実装します。

interface StartFragmentListener {
    fun configureFragment()
}

アクティビティ設定ではDrawerListenerのように:

private fun configureDrawerStateListener(){
    psMainNavDrawerLayout.addDrawerListener(object: DrawerLayout.DrawerListener{
        override fun onDrawerStateChanged(newState: Int) {}
        override fun onDrawerSlide(drawerView: View, slideOffset: Float) {}
        override fun onDrawerOpened(drawerView: View) {}

        override fun onDrawerClosed(drawerView: View) {
            notifyDrawerClosed()
        }

    })
}

ドロワーが閉じられ、ラグを引き起こす操作を実行できることをフラグメントに通知するには:

private fun notifyDrawerClosed(){
    val currentFragment =
            supportFragmentManager.findFragmentById(R.id.psMainNavHostFragment)
                    ?.childFragmentManager?.primaryNavigationFragment

    if(currentFragment is StartFragmentListenr && currentFragment != null)
        currentFragment.configureFragment()

}

ドロワーからフラグメントに移動していない場合(例えば、戻るボタンを押すなど)、フラグメントに通知して、その処理を実行する必要があります。 FragmentLifecycleCallbacksListenerを実装します。

private fun setupFragmentLifecycleCallbacksListener(){
    supportFragmentManager.findFragmentById(R.id.psMainNavHostFragment)
            ?.childFragmentManager?.registerFragmentLifecycleCallbacks(object : FragmentManager.FragmentLifecycleCallbacks() {

        override fun onFragmentActivityCreated(fm: FragmentManager, f: Fragment, savedInstanceState: Bundle?) {
            super.onFragmentActivityCreated(fm, f, savedInstanceState)

            if (!psMainNavDrawerLayout.isDrawerOpen(GravityCompat.START)) {
                if (f is StartFragmentListener)
                    f.configureFragment()
            }

        }
    }, true)
}

断片的に:

class MyFragment: Fragment(), MyActivity.StartFragmentListener {
    private var shouldConfigureUI = true
    ...

    override fun onDetach() {
        super.onDetach()
        shouldConfigureUI = true
    }

    override fun configureFragment() {
        if(shouldConfigureUI){
            shouldConfigureUI = false
            //do your things here, like configuring UI, getting data from VM etc...
            configureUI()
        }
    }
} 

同様のソリューションを共有ビューモデルで実装できます。

5
UrosKekovic

NavigationItemSelected-AndroidでFragment/Activityを変更する際に生じる遅延を回避

ナビゲーションドロワーは、アプリケーションで使用される最も一般的なオプションです。5つを超えるオプションがある場合は、ナビゲーションメニューに移動します。

多くのアプリケーションで、ナビゲーションメニューからオプションを変更すると遅延が発生することがわかりました。StackOverflowの一部の人は、次のコードのようにHandlerを使用することを推奨しています。

private void openDrawerActivity(final Class className) {
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                ProjectUtils.genericIntent(NewDrawer.this, className, null, false);
            }
        }, 200);
    }

しかし、上記のコードでは、それはまだスムーズではありません&ハンドラーを追加する理由は、多くのR&Dの後に別の解決策があるかもしれないと思いました、引き出しが閉じるときにフラグメント/アクティビティを変更する必要があることがわかりました。実装で見てみましょう。

ソリューションの詳細については、親切に https://Android.jlelse.eu/avoid-the-lag-caused-while-changing-fragment-activity-onnavigationitemselected-Android-28bcb2528ad8 を参照してください。それは本当に役に立ち、便利です。

あなたがそれにより良い解決策を見つけてくれることを願っています!

0
Kalpesh Rupani