方向更改时如何保留工具栏背景颜色?

How to retain toolbar background color when orientation changes?

我在 fragment 中遇到了工具栏的这种不良行为,工具栏背景工作正常,但是当滚动到某个级别然后将方向从纵向模式更改为横向模式时,背景颜色会丢失。横向模式的滚动状态与纵向模式相同。

如果切换回纵向,背景颜色仍然丢失

当背景颜色丢失时,改变滚动状态将恢复背景颜色。

问题是如何在更改设备方向后第一个滚动状态发生变化时保留背景颜色?

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>

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

当更改配置发生时(在您的情况下为方向),在正常情况下系统能够保留一些内容,例如滚动状态。

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

但是其他内容无法保留,例如您在滚动 ScrollView 后以编程方式更改的背景颜色。

There are different ways维护分片配置变化的数据; weediest/robust 一个使用 ViewModels.

但在您的情况下,滚动值已被保留;你可以只覆盖 onConfigurationChanged 并在那里重置背景:

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

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

更新:

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

这可能是因为清单文件 activity 部分缺少 android:configChanges="orientation"

但是,我更愿意推荐另一种解决方法:

您可以在 onCreateView() 回调中检查 bundle 参数是否为空,而不是覆盖 onConfigurationChanged();配置更改不应该为 null:

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