导航视图中仅为一个片段折叠工具栏

12

问题

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

我的问题

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


对于您导航视图中的该项,您可以打开一个带有可折叠工具栏的单独活动。 - Yyy
目前似乎只有这个选项,但我并不是很喜欢这个选项... - Mayr Technologies
{btsdaf} - Franco
5个回答

10

看起来你想实现这样的效果。

Nothing fancy

我使用了常规工具栏制作了一个活动。在切换到折叠工具栏片段时,我将工具栏设为透明,并让片段的工具栏接管。在切换到其他片段时,工具栏的颜色保持不变。

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

希望这可以帮到你。请参考链接的gif。

Gif的Gist


你能提供给我们代码吗?你是如何设置工具栏透明的,什么时候设置的? - Mycoola
附上了代码片段。您可以在 https://gist.github.com/groverankush/9d09fbba07879790d5395434fda1e2d4 访问它。 - Ankush
我仔细阅读了这个要点并将其整合在一起,它确实有效。有一个评论指出这会创建两个工具栏,但事实并非如此,这确实有效。然而,它在折叠工具栏标题时存在问题,不知道抽屉切换在哪里,所以我将标题设置为折叠到中心。 - martinseal1987
@Ankush 我尝试过这个,但我的其他片段内容被隐藏在工具栏下面。 - Vishal Thakkar

5
我找到的最佳解决方案是轻松折叠、锁定(保持折叠模式)和解锁CollapsingToolbar。
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;

4

您可以轻松地从Fragment获取Toolbar,然后修改或更改该Toolbar的某些属性。

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

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

现在你需要在onResume函数中更改Toolbar,然后在每次从Fragment返回到onStop函数时撤消更改。否则,在从导航抽屉切换到其他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);
}

谢谢您的回答,但我如何通过编程将普通工具栏制作成可折叠的工具栏? - Mayr Technologies
1
我认为这就是你要找的。https://dev59.com/GF0a5IYBdhLWcg3wJl2o#30747281 - 如果有帮助,请接受并点赞该答案。 - Reaz Murshed
这个解决方案没有考虑到在创建ActionBarDrawerToggle对象时必须设置工具栏(toolbar)的事实,而这是使导航抽屉在用户点击汉堡图标时打开的重要部分。 - Franco

1

1
我正在使用Jetpack的导航组件,在我的应用程序中,使用单个Activity和不同的Fragment。
其中一些Fragments可以从底部导航访问(并具有来自Activity的工具栏)。另一些是“特殊”Fragments,并具有自己的可折叠工具栏。
为了实现这一点,在“特殊”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
        }
    }
}

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