Home > Back-end >  How to retain toolbar background color when orientation changes?
How to retain toolbar background color when orientation changes?

Time:04-24

I encounter this unwanted behavior with toolbar in fragment , the toolbar background is working fine but when scrolled to a level then change orientation from portrait to landscape mode the background color is lost. The scroll state of landscape mode is the same as it was in portrait mode.

If you switch back to portrait the background color is still lost

When the background color is lost, changing scroll state will bring back the background color.

The question is how to retain the background color when the first scroll state changed after the changing the device orientation ?

public class VideoInfo extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        mTitleBar = (Toolbar) mRoot.findViewById(R.id.titlebar);

        mTitleBar.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
            @Override
            public void onLayoutChange(View view, int i, int i1, int i2, int i3, int i4, int i5, int i6, int i7) {
                updateHeaderHeight();
            }
        });
    }

    private void updateHeaderHeight() {
        log.debug("updateHeaderHeight");
        mHeaderHeight = mTitleBar.getMeasuredHeight();
        if (mHeaderHeight == 0)
            log.debug("Warning updateHeaderHeight sets mHeaderHeight to zero!");
        if (mIsPortraitMode) {
            View scrollView = mRoot.findViewById(R.id.scroll_content);
            scrollView.setPadding(scrollView.getPaddingLeft(), mHeaderHeight, scrollView.getPaddingRight(), scrollView.getPaddingBottom());
        }
    }

    @Override
    public void onScrollChanged(int i, boolean b, boolean b1) {
        updateHeaderBackground(i, true);

    }

    private void updateHeaderBackground(int scroll) {
        mTitleBar.setBackgroundColor(mContext.getResources().getColor(R.color.deep_dark_blue_transparent));
    }
}
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">
        <androidx.appcompat.widget.Toolbar
            android:id="@ id/titlebar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:contentInsetLeft="0dp"
            app:contentInsetStart="0dp"
            android:layout_margin="0dp"
            android:background="@android:color/transparent"
            android:paddingLeft="0dip">
            <!--text size is programmatically changed -->
            <TextView
                android:id="@ id/toolbar_title"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:fontFamily="@font/lato_regular"
                android:singleLine="true"
                android:textColor="@color/white_font"
                android:textSize="24sp"/>
        </androidx.appcompat.widget.Toolbar>
</RelativeLayout>

CodePudding user response:

The scroll state of landscape mode is the same as it was in portrait mode.

When the change configuration occurred (orientation in your case), in normal cases the system is able to preserve some stuff like the scroll state.

but when scrolled to a level then change orientation from portrait to landscape mode the background color is lost.

But other stuff can't be preserved such as this background color which you changed programmatically after scrolling the ScrollView.

There are different ways to maintain the data on configuration changes in fragments; the weediest/robust one to use ViewModels.

But in your case as the scroll value is already preserved; you can just override onConfigurationChanged and reset the background there:

@Override
public void onConfigurationChanged(@NonNull Configuration newConfig) {
    super.onConfigurationChanged(newConfig);

    updateHeaderBackground(scrollView.getScrollY()); // Change this to scrollView.getScrollX() if you the scroll is horizontal
}

UPDATE:

it does not get hit, the method is not called for some reason when changing orientation

This could be cause missing android:configChanges="orientation" in manifest file, activity section.

But, I'd rather recommend another way to solve it:

Instead of overriding onConfigurationChanged(), you can check if the bundle argument is null or not in onCreateView() callback; it shouldn't be null for configuration changes:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    // CODE IS OMITTED
    
    if (savedInstanceState != null) // It's not null
        updateHeaderBackground(scrollView.getScrollY()); // Change this to scrollView.getScrollX() if you the scroll is horizontal
    
}
  • Related