当前位置: 首页 > 知识库问答 >
问题:

抽屉布局的项目点击-什么时候是替换片段的正确时间?

彭鸿文
2023-03-14

我正在开发一个使用导航抽屉模式(带抽屉布局)的应用程序。

每次单击抽屉中的项目,都会替换主容器中的片段。

然而,我不确定何时是执行片段事务的正确时间?抽屉什么时候开始关?还是在它关闭之后?

在谷歌的文档示例中,您可以看到他们在项目点击后立即进行交易,然后关闭抽屉。
结果,抽屉看起来滞后且不光滑,看起来非常糟糕(我的应用程序中也发生了这种情况)。

另一方面,在Gmail和Google Drive应用程序中,他们似乎是在抽屉关闭后进行交易(我说得对吗?)<因此,抽屉并不迟钝且非常平滑,但至少需要大约1秒(抽屉闭合所需的时间)才能看到下一个片段。

似乎抽屉在立即进行碎片交易时不可能顺利。

你怎么看?

提前感谢!

共有3个答案

钮晟
2023-03-14

这就是我为实现类似于Gmail应用程序的流畅交易动画所做的事情:

activity_抽屉。xml

<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <!-- The main content view -->
    <FrameLayout
        android:id="@+id/content_frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <!-- The navigation drawer -->
    <ListView 
    android:id="@+id/left_drawer"
        android:layout_width="280dp"
        android:layout_height="match_parent"
        android:layout_gravity="left"
        android:choiceMode="singleChoice" />

</android.support.v4.widget.DrawerLayout>

抽屉ctivity.java

private Fragment mContentFragment;
private Fragment mNextContentFragment;
private boolean mChangeContentFragment = false;

private Handler mHandler = new Handler();

...

@Override
public void onCreate(Bundle savedInstanceState) {
    ...

    mDrawerLayout.setDrawerListener(new DrawerListener());

    mDrawerList.setOnItemClickListener(new DrawerItemClickListener());

    ...
}

....

private class DrawerItemClickListener implements ListView.OnItemClickListener {

    @Override
    public void onItemClick(AdapterView parent, View view, int position, long id) {
        getSupportFragmentManager().beginTransaction().remove(mContentFragment).commit();

        switch (position) {
            case 0:
                mNextContentFragment = new Fragment1();
                break;

            case 1:
                mNextContentFragment = new Fragment2();
                break;

            case 2:
                mNextContentFragment = new Fragment3();
                break;
        }

        mChangeContentFragment = true;

        mDrawerList.setItemChecked(position, true);

        mHandler.postDelayed(new Runnable() {

            @Override
            public void run() {
                mDrawerLayout.closeDrawer(mDrawerList);
            }           
        }, 150);
    }
}

private class DrawerListener implements android.support.v4.widget.DrawerLayout.DrawerListener {

    @Override
    public void onDrawerClosed(View view) {
        if (mChangeContentFragment) {
             getSupportFragmentManager().beginTransaction().setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN).replace(R.id.content_frame, mNextContentFragment).commit();

             mContentFragment = mNextContentFragment;           
             mNextContentFragment = null;

             mChangeContentFragment = false;
         }
     }
 }

希望对你有帮助!:-)

熊朝
2023-03-14

另一个解决方案是创建一个Handler,并在关闭抽屉后发布一个延迟的Runnable,如下所示:https://stackoverflow.com/a/18483633/769501.这种方法的好处是,您的片段将比您等待DrawerListener#onDrawerCloked()时更快地被替换,但当然,任意延迟并不能100%保证抽屉动画会及时完成。

也就是说,我使用200毫秒的延迟,它工作得非常好。

private class DrawerItemClickListener implements OnItemClickListener {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, final int position, long id) {
        drawerLayout.closeDrawer(drawerList);
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                switchFragments(position); // your fragment transactions go here
            }
        }, 200);
    }
}
堵泽宇
2023-03-14

是的,非常同意,执行片段(带视图)事务会导致布局传递,这会导致视图上的janky动画被动画化,引用了DrawerLayout文档:

抽屉布局。DrawerListener可用于监视抽屉视图的状态和运动。避免在动画期间执行昂贵的操作,如布局,因为这可能会导致口吃;尝试在STATE\u空闲状态下执行昂贵的操作。

因此,请在抽屉关闭或有人修补支持库以某种方式修复后执行片段事务:)

 类似资料:
  • 我对android比较陌生,我想在我的应用程序中添加一个导航抽屉,所以我添加了一个新的活动并选择导航抽屉活动 活动类 当我运行应用程序并尝试点击另一个项目时,什么都没有发生,它会保留在主片段上。到目前为止,我看到的大多数信息都是在3.6.3版本之前的旧信息,其他信息只是我到目前为止尝试过的工作——卸载并重新安装android studio——更新到最新的android studio(目前为4个)—

  • 有什么方法可以确保抽屉菜单保持在片段内容的顶部吗? 我用虚拟数据创建了一个小测试应用程序。10个片段,带有相应的编号按钮和文本视图。问题在于片段元素似乎比导航抽屉具有更高的优先级。 如屏幕截图所示,一旦我试图打开“0片段”,它就会选择注册点击导航抽屉后面的按钮。按下任何其他内容项都可以,但只要它们下面没有其他可交互的项。我该怎么做才能让导航抽屉正确地位于其后面内容的顶部?

  • 我有导航抽屉的BaseActivity,我在其中使用片段管理器在片段布局中显示/隐藏片段,当单击每个导航抽屉项时,我希望每次单击导航项时都刷新我的片段。我尝试了两种方法,例如片段附加/分离,但它不起作用,有谁能帮我在每次点击导航项时刷新我的片段吗。

  • 我在我的应用程序中使用抽屉菜单,并实现了在NavigationDrawer片段类中切换片段的逻辑。我最近读到片段切换只能从托管活动中发生。 有一个从NavigationDrawerFragment调用的接口,用于通知导航抽屉列表视图中所选位置的MainActivity。 我感到困惑的是,在Mainactive中有一个静态片段,它是使用NavigationDrawer片段中接口提供的位置调用的。 P

  • 我是android新手,我将设计这种对我来说很复杂的布局。这是主_活动的代码。xml文件: 基本上,我的主要活动中有一个导航抽屉和3个选项卡。这是一张照片: 一切按我的意愿进行,我很高兴。 当我点击导航抽屉项目时,我开始了一个新的意图来打开一个新的活动,这很好,但抽屉当然会消失(因为新活动没有抽屉)。我想把抽屉一直放在屏幕上。 为了把抽屉放在屏幕上,我想我可以把上面XML的TabLayout作为一

  • 我正在实现Android的标准抽屉菜单模式,用户可以从抽屉导航到大约10个片段。目前,每次点击不同的抽屉菜单项时,我都会创建一个新的片段,如下所示: 我一直在想,这样做是否更有效: 我主要担心的是,一些片段包含大量数据(相当大的列表和大量的视图)。将所有这些片段保存在内存中会有任何问题吗?与每次实例化新片段相比,它会提供任何优势吗(除了片段之间更快的切换)?是否有一个普遍接受的“更好”解决方案?