Ely
Ely

Reputation: 11162

Up navigation in fragment's toolbar

I am trying to use the up navigation in my app. The up navigation button displays, but sometimes it works and sometimes it does not. The app can be viewed here XYZReader on GitHub

Desired behaviour

The main activity displays a grid of cards. When you choose a card a detail activity displays the article. The detail activity uses fragments and view pager so that one can swipe right/left to the next/previous article.
In the (collapsing) toolbar of a fragment the up/back navigation button displays, and when I click on the button I want to go back to main activity.

Actual behaviour (Up navigation not working)

I choose an article from the grid in the main activity, and the detail activity displays the corresponding fragment.
I click on the up navigation button and nothing happens.
I would like the up navigation to bring me back to main activity to see the grid list of articles.

Actual behaviour (Up navigation working)

I choose an article from the grid in the main activity, and the detail activity displays the corresponding fragment.
I swipe to the right to see the next article. Then I click on the up navigation button and I go back to the main activity to see the grid list of articles.

Relevant code snippets

activity_article_detail.xml is the layout of the host/detail activity. It merely contains a view pager view:

<android.support.v4.view.ViewPager
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

fragment_article_detail.xml is the fragment's layout. It contains the collapsing toolbar (and a nested scroll view and a floating action button):

<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/app_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/collapsing_toolbar_container"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:expandedTitleMarginBottom="@dimen/toolbar_title_bottom_margin"
            app:expandedTitleMarginStart="@dimen/detail_inner_horiz_margin"
            app:expandedTitleTextAppearance="@style/Toolbar_Title"
            app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">

            <ImageView
                android:id="@+id/photo"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:contentDescription="@string/photo_of_the_article"
                android:scaleType="centerCrop"
                app:layout_collapseMode="parallax"
                app:layout_collapseParallaxMultiplier="0.1"/>

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?android:attr/actionBarSize"
                app:layout_collapseMode="pin">

            </android.support.v7.widget.Toolbar>

        </android.support.design.widget.CollapsingToolbarLayout>

    </android.support.design.widget.AppBarLayout>

    <android.support.v4.widget.NestedScrollView
        android:id="@+id/scrollview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <com.example.xyzreader.ui.MaxWidthLinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="center_horizontal"
            android:background="@android:color/white"
            android:maxWidth="@dimen/detail_card_max_width"
            android:orientation="vertical">

            <LinearLayout
                android:id="@+id/linear_layout_title_container"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:orientation="vertical"
                android:paddingBottom="@dimen/detail_metabar_vert_padding"
                android:paddingLeft="@dimen/detail_inner_horiz_margin"
                android:paddingRight="@dimen/detail_inner_horiz_margin"
                android:paddingTop="@dimen/detail_metabar_vert_padding">

                <TextView
                    android:id="@+id/article_byline"
                    style="?android:attr/textAppearanceSmall"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textColor="@color/byline_text_color"/>

            </LinearLayout>

            <WebView
                android:id="@+id/article_body"
                style="?android:attr/textAppearanceMedium"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginLeft="@dimen/detail_inner_horiz_margin"
                android:layout_marginRight="@dimen/detail_inner_horiz_margin"
                android:lineSpacingMultiplier="@fraction/detail_body_line_spacing_multiplier"
                android:paddingBottom="@dimen/detail_body_bottom_margin"
                android:paddingTop="@dimen/body_padding_top"
                android:textColor="?android:attr/textColorPrimary"
                android:textColorLink="?attr/colorAccent"
                android:textSize="@dimen/detail_body_text_size"/>

        </com.example.xyzreader.ui.MaxWidthLinearLayout>

    </android.support.v4.widget.NestedScrollView>

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/floating_action_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="@dimen/fab_margin"
        android:contentDescription="@string/action_share"
        app:fabSize="normal"
        app:srcCompat="@drawable/ic_share_white_24dp"/>

</android.support.design.widget.CoordinatorLayout>

In the onCreateView of the fragment I try to program the functionalities:

    mCollapsingToolbarLayout = mRootView.findViewById(R.id.collapsing_toolbar_container);
    mCollapsingToolbarLayout.setExpandedTitleTypeface(Typeface.create(mCollapsingToolbarLayout.getExpandedTitleTypeface(), Typeface.BOLD));
    mCollapsingToolbarLayout.setCollapsedTitleTypeface(Typeface.create(mCollapsingToolbarLayout.getExpandedTitleTypeface(), Typeface.BOLD));
    mCollapsingToolbarLayout.setCollapsedTitleTextColor(getResources().getColor(android.R.color.white));

    AppCompatActivity appCompatActivity = ((AppCompatActivity) getActivity());
    Toolbar toolbar = mRootView.findViewById(R.id.toolbar);
    toolbar.setNavigationIcon(R.drawable.ic_arrow_back_white_24dp);
    appCompatActivity.setSupportActionBar(toolbar);
    ActionBar actionBar = appCompatActivity.getSupportActionBar();
    actionBar.setDisplayHomeAsUpEnabled(true); //<-- DISPLAYS THE HOME BUTTON IN THE COLLAPSING TOOLBAR
    actionBar.setDisplayShowTitleEnabled(false);

What I have tried

  1. I have tried to move the toolbar to the host activity's layout. I ran into issues and gave up on this. I did not want to do this anyway because it looks like a flawed design. In my opinion each fragment owns a toolbar.
  2. I have tried to set the navigation icon and a listener on the toolbar. The result was the same. Sometimes it works, sometimes it does not.

    toolbar.setNavigationIcon(nav_icon);
    toolbar.setNavigationOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Log.d(TAG, "Up navigation button pressed.");
        }
    });
    
  3. I was suggested to try to add a code snippet to the fragment. This did not work neither.

    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                Intent intent = NavUtils.getParentActivityIntent(getActivity());
                intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
                NavUtils.navigateUpTo(getActivity(), intent);
                return true;
        }
        return super.onOptionsItemSelected(item);
    }
    

Upvotes: 2

Views: 1922

Answers (3)

val navHostFragment =
        activity?.supportFragmentManager?.findFragmentById(R.id.main_nav_host_fragment) as NavHostFragment
    val navController = navHostFragment.navController
    val appBarConfiguration = AppBarConfiguration(
        topLevelDestinationIds = setOf()
    )
    binding.toolbar.setupWithNavController(navController, appBarConfiguration)

Upvotes: 0

binding.toolbar.setNavigationOnClickListener {
   activity!!.onBackPressed()
}

Upvotes: -1

Ely
Ely

Reputation: 11162

The issue is that I tried to set the support action bar of the host activity for each fragment, which is wrong (I cannot believe I really did that).

I just use the toolbar, set the navigation icon and a corresponding listener:

    Toolbar toolbar = mRootView.findViewById(R.id.toolbar);
    toolbar.setNavigationIcon(R.drawable.ic_arrow_back_white_24dp);
    toolbar.setNavigationOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            getActivity().onBackPressed();
        }
    });

Upvotes: 4

Related Questions