【问题标题】:Properly handle DrawerLayout animation while navigating through fragment在通过片段导航时正确处理 DrawerLayout 动画
【发布时间】:2016-08-05 15:17:28
【问题描述】:

我目前正在为 DrawerLayout 动画做奇怪的事情而苦苦挣扎; 汉堡包图标很迟钝,如果我不放置处理程序来延迟fragment 事务动画,则经常从汉堡包切换到没有动画的箭头。

所以我最终放置了一个处理程序来等待汉堡图标执行动画,但是我们需要等到抽屉关闭才能切换片段并不自然。我确信有更好的方法来处理这个......

这是我目前的做法:

private void selectProfilFragment() {
    final BackHandledFragment fragment;
    // TODO test this again
    Bundle bundle = new Bundle();
    bundle.putString(FragmentUserProfile.USER_FIRST_NAME, user.getFirstname());
    bundle.putString(FragmentUserProfile.USER_LAST_NAME, user.getLastname());
    bundle.putString(FragmentUserProfile.USER_PICTURE, user.getProfilepic());
    bundle.putString(FragmentUserProfile.USER_EMAIL, user.getEmail());
    bundle.putBoolean(FragmentUserProfile.USER_SECURITY, user.getParameters().getSecuritymodule().equals("YES"));
    fragment = new FragmentUserProfile();
    fragment.setArguments(bundle);
    mDrawerLayout.closeDrawer(mDrawerLinear);

    new Handler().postDelayed(new Runnable() {
        public void run() {
            FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
            ft.setCustomAnimations(R.anim.pull_in_right, R.anim.push_out_left, R.anim.pull_in_left, R.anim.push_out_right);
            ft.replace(R.id.content_frame, fragment)
                    .addToBackStack(fragment.getTagText())
                    .commitAllowingStateLoss();
        }
    }, 300);
}

DrawerLayout 关闭和打开片段事务动画之间仍然出现故障

这是我实例化抽屉的方法:

mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);

mDrawerListChild.setAdapter(new DrawerListAdapter(this, R.layout.drawer_layout_item, mPlanTitles));
mDrawerListChild.setOnItemClickListener(new DrawerItemClickListener());

mProfilPic.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        selectProfilFragment();
    }
});

mDrawerToggle = new ActionBarDrawerToggle(
        this,
        mDrawerLayout,
        toolbar,
        R.string.drawer_open,
        R.string.drawer_close
) {
    public void onDrawerClosed(View view) {
        invalidateOptionsMenu();
    }

    public void onDrawerOpened(View drawerView) {
        invalidateOptionsMenu();
    }
};
getSupportFragmentManager().addOnBackStackChangedListener(mOnBackStackChangedListener);
mDrawerLayout.setDrawerListener(mDrawerToggle);
setSupportActionBar(toolbar);

【问题讨论】:

  • 我猜 BackHandledFragment 的初始化处理繁重。将 BackHandledFragments onCreateView` 和 onActivityCreated 改简单,延迟繁重的处理。
  • 对不起,我弄错了。 FragmentUserProfile 的初始化过程是否繁重?
  • 即使这样,我们应该如何处理关闭抽屉动画然后交换片段?因为,同时做这两件事并不自然……是的,也许 FragmentProfil 有点重,但话又说回来,这不是问题
  • 我的意思是即使片段的处理真的很快,我仍然需要等到抽屉关闭才能执行片段滑动动画
  • 我有类似的安卓应用,它有 NavigationDrawer,但没有片段过渡动画。我的应用程序不会跳过抽屉动画和汉堡图标动画。所以如果FragmentProfile的初始化很简单,动画跳过的原因可能是动画太多。我建议您检查 gpu monitor 以检测原因。 developer.android.com/studio/profile/am-gpu.html

标签: android android-fragments animation navigation-drawer


【解决方案1】:

虽然我想提请您注意几件事,但我不确定是什么导致了这种行为。

  1. 我不知道您使用的是哪个 ActionBarDrawerToggle 类,但最好使用 android.support.v7.app.ActionBarDrawerToggle 而不是 android.support.v4.app.ActionBarDrawerToggle,因为它已被弃用。

  2. 使用 addDrawerListener() 代替 setDrawerListener(),因为它已被弃用。

  3. 使用spinBars 并设置值true 在过渡期间旋转条形图。 前任。在您的 styles.xml 中,如 here 所述。

  4. onDrawerClosedonDrawerOpened 中调用syncState()。也可以在您的ActionBarDrawerToggle 上调用此方法。 Check this.

    希望这会对你有所帮助。

【讨论】:

    【解决方案2】:

    您可以这样做。在包含片段的 Activity 中设置您的抽屉。

    public void setupDrawer(){
     NavigationFragment drawerFragment = (NavigationFragment)
                    getSupportFragmentManager().findFragmentById(R.id.navigation_drawer);
            mActionbarToggle = drawerFragment.setUp(R.id.navigation_drawer, mDrawerLayout, mToolbar); 
    }
    

    现在在 NavigationDrawerFragment 中定义您的 setUp 方法

    public ActionBarDrawerToggle setUp(int navigation_drawer, DrawerLayout drawerLayout, Toolbar mToolbar) {
            mFragmentContainerView = getActivity().findViewById(navigation_drawer);
            this.mDrawerLayout = drawerLayout;
            //mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
            ActionBar actionBar = getActionBar();
            actionBar.setDisplayHomeAsUpEnabled(true);
            actionBar.setHomeButtonEnabled(true);
            mDrawerToggle = new ActionBarDrawerToggle(getActivity(), drawerLayout, mToolbar, R.string.drawer_open, R.string.drawer_close) {
                @Override
                public void onDrawerClosed(View drawerView) {
                    super.onDrawerClosed(drawerView);
                    if (!isAdded()) {
                        return;
                    }
                    getActivity().supportInvalidateOptionsMenu(); // calls onPrepareOptionsMenu()
                }
    
                @Override
                public void onDrawerOpened(View drawerView) {
                    super.onDrawerOpened(drawerView);
                    if (!isAdded()) {
                        return;
                    }
                    getActivity().supportInvalidateOptionsMenu(); // calls onPrepareOptionsMenu()
                }
            };
            mDrawerToggle.setToolbarNavigationClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
    
                    ((MainActivity) mContext).onBackPress();
                }
            });
            mDrawerLayout.post(new Runnable() {
                @Override
                public void run() {
                    mDrawerToggle.syncState();
                }
            });
            mDrawerLayout.setDrawerListener(mDrawerToggle);
    
            return mDrawerToggle;
        }
    

    就是这样,你的抽屉已经完全设置好了。

    【讨论】:

    • 什么是 isAdded()?我没有关注你,这应该如何解决我的问题?
    • NavigationFragment 到底是什么?这个设置方法应该永远不会离开活动。
    • 你必须从包含 navigationFragment @EugenPechanec 的活动中调用 setup()
    • 我的意思是不应该有 NavigationFragment。您正在从活动内部调用片段的方法,并且该片段仅触及其自身范围之外的视图。片段不仅毫无意义,而且还显示出糟糕的设计。
    猜你喜欢
    • 2019-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-22
    • 2022-07-14
    • 1970-01-01
    • 1970-01-01
    • 2021-09-19
    相关资源
    最近更新 更多