【问题标题】:Collapsing Toolbar only for one Fragment in Navigation View仅针对导航视图中的一个片段折叠工具栏
【发布时间】:2017-11-27 00:58:53
【问题描述】:

问题

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

我的问题

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

【问题讨论】:

  • 对于导航视图的该项目,您可以打开带有折叠工具栏的单独活动。
  • 似乎是目前唯一的选择,但我不太喜欢那个选择...
  • 你有没有为这个@MayrTechnologies找到任何好的解决方案?

标签: java android xml android-layout android-fragments


【解决方案1】:

看来你想实现这样的目标。

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

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

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

Gist for gif

【讨论】:

  • 你能提供给我们代码吗?你如何设置工具栏透明以及何时?
  • 附上要点。您可以通过gist.github.com/groverankush/9d09fbba07879790d5395434fda1e2d4访问它
  • 我仔细阅读了要点并将其放在一起,它确实有效,关于要点的评论表明这会创建 2 个工具栏,但事实并非如此,但它确实存在问题折叠工具栏标题不知道抽屉切换的位置,所以我将标题设置为折叠到中心,
  • @Ankush 我试过这个,但我的其他片段内容隐藏在工具栏下方
【解决方案2】:

我发现的最好的解决方案是轻松折叠、锁定(保持折叠模式)并解锁 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;

【讨论】:

    【解决方案3】:

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

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

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

    现在您需要在onResume 函数中对Toolbar 进行更改,然后每次从onStop 函数中的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);
    }
    

    【讨论】:

    • 感谢您的回答,但我怎样才能以编程方式将普通工具栏制作成折叠工具栏?
    • 我想这就是你要找的。 stackoverflow.com/a/30747281/3145960 - 如果有帮助,请接受并投票。
    • 这个解决方案没有考虑到在ActionBarDrawerToggle中创建该对象时必须在ActionBarDrawerToggle中设置工具栏这一事实,这是制作导航抽屉的重要部分当用户点击汉堡图标时打开。
    【解决方案4】:

    我在我的应用中使用 Jetpack's Navigation components 和单个 Activity 和不同的片段。

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

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

    // 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
            }
        }
    }
    

    【讨论】:

      【解决方案5】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-09-26
        • 2018-11-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-08-21
        相关资源
        最近更新 更多