Collapsing Toolbar only for one Fragment in Navigation View

前端 未结 5 989
天命终不由人
天命终不由人 2021-01-02 03:47

The Problem

I have a navigation drawer with different fragments. There is a default toolbar every Fragment should use, except of one Fragment

相关标签:
5条回答
  • 2021-01-02 04:02

    The recommend practice is to use toolbars in fragments instead of a common toolbar in activity. That way you can control the looks and behaviour of toolbar in fragment. Refer https://developer.android.com/guide/navigation/navigation-ui#support_app_bar_variations

    0 讨论(0)
  • 2021-01-02 04:03

    It seems you want to achieve something like this.

    I have made an activity with common toolbar. when switching to the collapsing toolbar fragment I've made the toolbar transparent and fragment's toolbar takes over. The toolbar's color remains the same on switching to other fragments.

    This allows you to manage complete collapsing toolbar's layout structure in xml and logic remains in Fragment.

    Hope this will help. Refer the gif linked.

    Gist for gif

    0 讨论(0)
  • 2021-01-02 04:21

    You can easily get the Toolbar from your Fragment and then modify or change some property of that Toolbar inside the Fragment.

    To get the Toolbar from your Activity you might consider using this.

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

    Now you need to make the changes on the Toolbar in the onResume function and then undo the changes each time you return from the Fragment inside onStop function. Otherwise the changes made in the Fragment will be carried on to other fragments as well when switched to other Fragment from the navigation drawer.

    But in your case, I would recommend each Fragment should have their Toolbar so that it doesn't conflict with each other and can be modified as you need. And yes, remove the Toolbar from your Activity.

    So add the Toolbar in the layout of your Fragment like this.

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

    Then find it in the 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);
    }
    

    And Override the onOptionsItemSelected function.

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch(item.getItemId()){
            case android.R.id.home:
                getActivity().onBackPressed();
        }
        return super.onOptionsItemSelected(item);
    }
    
    0 讨论(0)
  • 2021-01-02 04:24

    The best solution that I found to easily collapse, lock it(keep it in collapsed mode) and unlock the 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;
                }
            });
        }
    }
    

    And I use these functions in this way:

        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;
    
    0 讨论(0)
  • 2021-01-02 04:26

    I'm using Jetpack's Navigation components with single Activity and different Fragments in my app.

    Some Fragments are accessible from bottom navigation (and have Toolbar from Activity). Some others are "special" Fragments and have their own Collapsible Toolbar.

    To achieve this, I'm hiding Toolbar from Activity in "special" Fragments with this code in 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
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题