导航抽屉关闭时抖动

4

我尝试在我的应用中实现导航抽屉(Material Design)。我的活动包含带片段的 FrameLayout。当用户在导航抽屉中选择项目时,FrameLayout 会重新加载新的片段:

    listViewDrawer.setOnItemClickListener( new AdapterView.OnItemClickListener() {

        @Override
        public void onItemClick( AdapterView<?> parent, View view, int position, long id) {

            drawerLayout.closeDrawer( listViewDrawer); // <<<-------

            toolbar.setTitle( getResources().getString( R.string.title));

            fragmentMain = new FragmentMain();

            android.app.FragmentManager fragmentManager = getFragmentManager();
            fragmentManager.beginTransaction()
                       .replace( R.id.frameLayoutMain, ApplicationTapaKiosk.getInstance().fragmentMain)
                       .commit();

        }
     }

当我点击项目时,一切都很好。导航抽屉关闭时不太平滑,而是会因为后台片段重新加载而冻结(抖动,抽搐)。

如何使导航抽屉平滑关闭?

2个回答

9

您需要决定更喜欢哪个:

替换 FrameLayout 中的 Fragment,然后关闭 DrawerLayout

或者

关闭 DrawerLayout,然后替换您的 Fragment

实现第一种方法:

只需在您的代码中进行这些更改:

listViewDrawer.setOnItemClickListener(new AdapterView.OnItemClickListener() {

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        toolbar.setTitle(getResources().getString(R.string.title));

        fragmentMain = new FragmentMain();

        android.app.FragmentManager fragmentManager = getFragmentManager();
        fragmentManager.beginTransaction()
                   .replace(R.id.frameLayoutMain, ApplicationTapaKiosk.getInstance().fragmentMain)
                   .commit();

        fragmentManager.executePendingTransactions(); // wait for the transaction to finish
        drawerLayout.closeDrawer(listViewDrawer); // call closeDrawer(...) as a last thing
    }
 }

实施第二种方法:

在用户点击时设置某种标志:

listViewDrawer.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        mDrawerItemClicked = true;
        drawerLayout.closeDrawer(listViewDrawer); 
    }
 }

并在您的DrawerLayout上设置DrawerLayout.DrawerListener,如下所示:

drawerLayout.setDrawerListener(new DrawerLayout.DrawerListener() {
    @Override
    public void onDrawerSlide(View drawerView, float slideOffset) {
    }

    @Override
    public void onDrawerOpened(View drawerView) {
    }

    @Override
    public void onDrawerClosed(View drawerView) {
        if (mDrawerItemClicked){
            mDrawerItemClicked = false;

            toolbar.setTitle(getResources().getString(R.string.title));
            fragmentMain = new FragmentMain();
            android.app.FragmentManager fragmentManager = getFragmentManager();
            fragmentManager.beginTransaction()
                   .replace(R.id.frameLayoutMain, ApplicationTapaKiosk.getInstance().fragmentMain)
                   .commit();
        }
    }

    @Override
    public void onDrawerStateChanged(int newState) {
    }
});

谢谢您先生!!正是我所需要的 :) - Sumit Jha

3

抽屉关闭需要大约200毫秒的时间。因此,您可以执行以下操作:

Handler mHandler = new Handler();

drawerLayout.closeDrawer( listViewDrawer);
mHandler.postDelayed(
                new Runnable() {
                    @Override
                    public void run () {
                        loadFragment();
                    }
                }
                , NAVDRAWER_CLOSE_DELAY // 250...for delay
        );

当我使用这个延迟时,导航抽屉关闭得很快而不会冻结,但是我的片段直到延迟后才更新。片段开始重新加载只有在200毫秒的延迟后,这是“冻结”的片段...是否有任何解决方案,既可以避免导航抽屉冻结,又可以避免片段冻结? :( - Tapa Save
好的,你可以进行动画处理...淡出当前片段,关闭抽屉,淡入新片段。我在关闭时没有遇到任何问题,但我使用这段代码是因为它同步得很好。此外,谷歌在他们的“Google IO”演示应用程序中也在使用这段代码。 - royB

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接