繁体   English   中英

仅针对导航视图中的一个片段折叠工具栏

[英]Collapsing Toolbar only for one Fragment in Navigation View

问题

我有一个带有不同片段的导航抽屉。 每个Fragment都应该使用一个默认工具栏,除了一个需要折叠Toolbar Fragment

我的问题

如何在片段的工具栏之间切换?

看来您想要实现这样的目标。

没有什么花哨

我做了一个带有通用工具栏的活动。 当切换到折叠的工具栏片段时,我使工具栏透明,片段的工具栏接管。 切换到其他片段时,工具栏的颜色保持不变。

这允许您在 xml 中管理完整的折叠工具栏的布局结构,而逻辑保留在 Fragment 中。

希望这会有所帮助。 请参阅链接的 gif。

gif 的要点

我发现可以轻松折叠、锁定(保持折叠模式)并解锁折叠工具栏的最佳解决方案。

private void collapseAppBar() {
    // Collapse the AppBarLayout with animation
    mAppBarLayout.setExpanded(false, true);
}

private void lockAppBar() {
    /* Disable the nestedScrolling to disable expanding the
     appBar with dragging the nestedScrollView below it */
    ViewCompat.setNestedScrollingEnabled(nestedScrollView, false);

    /* But still appBar is expandable with dragging the appBar itself
    and below code disables that too
     */
    CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) mAppBarLayout.getLayoutParams();
    AppBarLayout.Behavior behavior = (AppBarLayout.Behavior) params.getBehavior();
    behavior.setDragCallback(new AppBarLayout.Behavior.DragCallback() {
        @Override
        public boolean canDrag(AppBarLayout appBarLayout) {
            return false;
        }
    });
}

private void unLockAppBar() {
    ViewCompat.setNestedScrollingEnabled(nestedScrollView, true);

    CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) mAppBarLayout.getLayoutParams();
    AppBarLayout.Behavior behavior = (AppBarLayout.Behavior) params.getBehavior();
    if (behavior != null) {
        behavior.setDragCallback(new AppBarLayout.Behavior.DragCallback() {
            @Override
            public boolean canDrag(AppBarLayout appBarLayout) {
                return true;
            }
        });
    }
}

我以这种方式使用这些功能:

    Fragment fragment = null;
    Class fragmentClass;
    switch (menuItem.getItemId()) {
        case R.id.fragment1:
            unLockAppBar();
            fragmentClass = first_Fragment.class;
            break;
        case R.id.fragment2:
            collapseAppBar();
            lockAppBar();
            fragmentClass = second_Fragment.class;
            break;
        case R.id.fragment3:
            collapseAppBar();
            lockAppBar();
            fragmentClass = third_Fragment.class;
            break;

您可以轻松地获得Toolbar从你的Fragment ,然后修改或更改的某些属性Toolbar里面Fragment

要从您的Activity获取Toolbar ,您可以考虑使用它。

Toolbar toolbar = (Toolbar) getActivity().findViewById(R.id.toolbar);

现在您需要在onResume函数中的Toolbar上进行更改,然后每次从onStop函数中的Fragment返回时撤消更改。 否则,当从导航抽屉切换到其他Fragment时,在Fragment所做的更改也将继续到其他Fragment

但是在您的情况下,我建议每个Fragment都应该有自己的Toolbar这样它就不会相互冲突,并且可以根据需要进行修改。 是的,从您的Activity删除Toolbar

因此,像这样在Fragment的布局中添加Toolbar

<android.support.v7.widget.Toolbar
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="?attr/colorPrimaryDark"/>

然后在Fragment找到它

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment, container, false);
    Toolbar toolbar = (Toolbar) view.findViewById(R.id.toolbar);

    // Modify your Toolbar here. 
    // ... 
    // For example. 
    // toolbar.setBackground(R.color.red);

    // Create home button
    AppCompatActivity activity = (AppCompatActivity) getActivity();
    activity.setSupportActionBar(toolbar);
    activity.getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}

并覆盖onOptionsItemSelected函数。

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch(item.getItemId()){
        case android.R.id.home:
            getActivity().onBackPressed();
    }
    return super.onOptionsItemSelected(item);
}

我在我的应用程序中使用Jetpack 的导航组件和单个活动和不同的片段。

一些 Fragments 可以从底部导航访问(并且有来自 Activity 的Toolbar )。 其他一些是“特殊”片段,并有自己的可折叠工具栏。

为了实现这一点,我将工具栏从“特殊”片段中的活动中隐藏起来,并在活动中使用以下代码:

// Handle toolbar changes in different Fragments
val navController = findNavController(R.id.nav_host_fragment)
navController.addOnDestinationChangedListener { _, destination, _ ->
    when (destination.id) {
        R.id.my_special_fragment_with_collapsible_toolbar -> {
            binding.toolbarMain.visibility = View.GONE
        }
        else -> {
            binding.toolbarMain.visibility = View.VISIBLE
        }
    }
}

推荐的做法是在片段中使用工具栏,而不是在活动中使用通用工具栏。 这样您就可以在片段中控制工具栏的外观和行为。 参考https://developer.android.com/guide/navigation/navigation-ui#support_app_bar_variations

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM