Merge "Fix a flicker problem on top app bar" into sc-dev

This commit is contained in:
TreeHugger Robot
2021-06-24 13:32:55 +00:00
committed by Android (Google) Code Review
4 changed files with 176 additions and 84 deletions

View File

@@ -33,7 +33,7 @@
android:background="?android:attr/colorPrimary"
android:theme="@style/Theme.CollapsingToolbar.Settings">
<com.android.settingslib.collapsingtoolbar.AdjustableToolbarLayout
<com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="@dimen/toolbar_one_line_height"
@@ -59,7 +59,7 @@
android:transitionName="shared_element_view"
app:layout_collapseMode="pin"/>
</com.android.settingslib.collapsingtoolbar.AdjustableToolbarLayout>
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<FrameLayout

View File

@@ -1,80 +0,0 @@
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settingslib.collapsingtoolbar;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.material.appbar.CollapsingToolbarLayout;
/**
* A customized version of CollapsingToolbarLayout that can apply different font size based on the
* line count of its title.
*/
public class AdjustableToolbarLayout extends CollapsingToolbarLayout {
private static final int TOOLBAR_MAX_LINE_NUMBER = 2;
public AdjustableToolbarLayout(@NonNull Context context) {
this(context, null);
}
public AdjustableToolbarLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public AdjustableToolbarLayout(@NonNull Context context, @Nullable AttributeSet attrs,
int defStyleAttr) {
super(context, attrs, defStyleAttr);
initCollapsingToolbar();
}
@SuppressWarnings("RestrictTo")
private void initCollapsingToolbar() {
this.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
@Override
public void onLayoutChange(View v, int left, int top, int right, int bottom,
int oldLeft, int oldTop, int oldRight, int oldBottom) {
v.removeOnLayoutChangeListener(this);
final int count = getLineCount();
if (count > TOOLBAR_MAX_LINE_NUMBER) {
final ViewGroup.LayoutParams lp = getLayoutParams();
lp.height = getResources()
.getDimensionPixelSize(R.dimen.toolbar_three_lines_height);
setScrimVisibleHeightTrigger(
getResources().getDimensionPixelSize(
R.dimen.scrim_visible_height_trigger_three_lines));
setLayoutParams(lp);
} else if (count == TOOLBAR_MAX_LINE_NUMBER) {
final ViewGroup.LayoutParams lp = getLayoutParams();
lp.height = getResources()
.getDimensionPixelSize(R.dimen.toolbar_two_lines_height);
setScrimVisibleHeightTrigger(
getResources().getDimensionPixelSize(
R.dimen.scrim_visible_height_trigger_two_lines));
setLayoutParams(lp);
}
}
});
}
}

View File

@@ -35,10 +35,18 @@ import com.google.android.material.resources.TextAppearanceConfig;
* A base Activity that has a collapsing toolbar layout is used for the activities intending to
* enable the collapsing toolbar function.
*/
public class CollapsingToolbarBaseActivity extends SettingsTransitionActivity {
public class CollapsingToolbarBaseActivity extends SettingsTransitionActivity implements
AppBarLayout.OnOffsetChangedListener {
private static final int TOOLBAR_MAX_LINE_NUMBER = 2;
private static final int FULLY_EXPANDED_OFFSET = 0;
private static final String KEY_IS_TOOLBAR_COLLAPSED = "is_toolbar_collapsed";
@Nullable
private CollapsingToolbarLayout mCollapsingToolbarLayout;
@Nullable
private AppBarLayout mAppBarLayout;
private boolean mIsToolbarCollapsed;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
@@ -48,6 +56,12 @@ public class CollapsingToolbarBaseActivity extends SettingsTransitionActivity {
super.setContentView(R.layout.collapsing_toolbar_base_layout);
mCollapsingToolbarLayout = findViewById(R.id.collapsing_toolbar);
mAppBarLayout = findViewById(R.id.app_bar);
mAppBarLayout.addOnOffsetChangedListener(this);
if (savedInstanceState != null) {
mIsToolbarCollapsed = savedInstanceState.getBoolean(KEY_IS_TOOLBAR_COLLAPSED);
}
initCollapsingToolbar();
disableCollapsingToolbarLayoutScrollingBehavior();
final Toolbar toolbar = findViewById(R.id.action_bar);
@@ -107,14 +121,43 @@ public class CollapsingToolbarBaseActivity extends SettingsTransitionActivity {
return true;
}
@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int offset) {
if (offset == FULLY_EXPANDED_OFFSET) {
mIsToolbarCollapsed = false;
} else {
mIsToolbarCollapsed = true;
}
}
@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
if (isChangingConfigurations()) {
outState.putBoolean(KEY_IS_TOOLBAR_COLLAPSED, mIsToolbarCollapsed);
}
}
/**
* Returns an instance of collapsing toolbar.
*/
@Nullable
public CollapsingToolbarLayout getCollapsingToolbarLayout() {
return mCollapsingToolbarLayout;
}
/**
* Return an instance of app bar.
*/
@Nullable
public AppBarLayout getAppBarLayout() {
return mAppBarLayout;
}
private void disableCollapsingToolbarLayoutScrollingBehavior() {
if (mAppBarLayout == null) {
return;
}
final CoordinatorLayout.LayoutParams params =
(CoordinatorLayout.LayoutParams) mAppBarLayout.getLayoutParams();
final AppBarLayout.Behavior behavior = new AppBarLayout.Behavior();
@@ -127,4 +170,39 @@ public class CollapsingToolbarBaseActivity extends SettingsTransitionActivity {
});
params.setBehavior(behavior);
}
@SuppressWarnings("RestrictTo")
private void initCollapsingToolbar() {
if (mCollapsingToolbarLayout == null || mAppBarLayout == null) {
return;
}
mCollapsingToolbarLayout.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
@Override
public void onLayoutChange(View v, int left, int top, int right, int bottom,
int oldLeft, int oldTop, int oldRight, int oldBottom) {
v.removeOnLayoutChangeListener(this);
if (mIsToolbarCollapsed) {
return;
}
final int count = mCollapsingToolbarLayout.getLineCount();
if (count > TOOLBAR_MAX_LINE_NUMBER) {
final ViewGroup.LayoutParams lp = mCollapsingToolbarLayout.getLayoutParams();
lp.height = getResources()
.getDimensionPixelSize(R.dimen.toolbar_three_lines_height);
mCollapsingToolbarLayout.setScrimVisibleHeightTrigger(
getResources().getDimensionPixelSize(
R.dimen.scrim_visible_height_trigger_three_lines));
mCollapsingToolbarLayout.setLayoutParams(lp);
} else if (count == TOOLBAR_MAX_LINE_NUMBER) {
final ViewGroup.LayoutParams lp = mCollapsingToolbarLayout.getLayoutParams();
lp.height = getResources()
.getDimensionPixelSize(R.dimen.toolbar_two_lines_height);
mCollapsingToolbarLayout.setScrimVisibleHeightTrigger(
getResources().getDimensionPixelSize(
R.dimen.scrim_visible_height_trigger_two_lines));
mCollapsingToolbarLayout.setLayoutParams(lp);
}
}
});
}
}

View File

@@ -25,21 +25,31 @@ import android.widget.Toolbar;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
import androidx.fragment.app.Fragment;
import com.google.android.material.appbar.AppBarLayout;
import com.google.android.material.appbar.CollapsingToolbarLayout;
/**
* A base fragment that has a collapsing toolbar layout for enabling the collapsing toolbar design.
*/
public abstract class CollapsingToolbarBaseFragment extends Fragment {
public abstract class CollapsingToolbarBaseFragment extends Fragment implements
AppBarLayout.OnOffsetChangedListener {
private static final int TOOLBAR_MAX_LINE_NUMBER = 2;
private static final int FULLY_EXPANDED_OFFSET = 0;
private static final String KEY_IS_TOOLBAR_COLLAPSED = "is_toolbar_collapsed";
@Nullable
private CollapsingToolbarLayout mCollapsingToolbarLayout;
@Nullable
private AppBarLayout mAppBarLayout;
@NonNull
private Toolbar mToolbar;
@NonNull
private FrameLayout mContentFrameLayout;
private boolean mIsToolbarCollapsed;
@Nullable
@Override
@@ -48,6 +58,13 @@ public abstract class CollapsingToolbarBaseFragment extends Fragment {
final View view = inflater.inflate(R.layout.collapsing_toolbar_base_layout, container,
false);
mCollapsingToolbarLayout = view.findViewById(R.id.collapsing_toolbar);
mAppBarLayout = view.findViewById(R.id.app_bar);
mAppBarLayout.addOnOffsetChangedListener(this);
if (savedInstanceState != null) {
mIsToolbarCollapsed = savedInstanceState.getBoolean(KEY_IS_TOOLBAR_COLLAPSED);
}
initCollapsingToolbar();
disableCollapsingToolbarLayoutScrollingBehavior();
mToolbar = view.findViewById(R.id.action_bar);
mContentFrameLayout = view.findViewById(R.id.content_frame);
return view;
@@ -60,6 +77,31 @@ public abstract class CollapsingToolbarBaseFragment extends Fragment {
requireActivity().setActionBar(mToolbar);
}
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
if (getActivity().isChangingConfigurations()) {
outState.putBoolean(KEY_IS_TOOLBAR_COLLAPSED, mIsToolbarCollapsed);
}
}
@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int offset) {
if (offset == FULLY_EXPANDED_OFFSET) {
mIsToolbarCollapsed = false;
} else {
mIsToolbarCollapsed = true;
}
}
/**
* Return an instance of app bar.
*/
@Nullable
public AppBarLayout getAppBarLayout() {
return mAppBarLayout;
}
/**
* Return the collapsing toolbar layout.
*/
@@ -75,4 +117,56 @@ public abstract class CollapsingToolbarBaseFragment extends Fragment {
public FrameLayout getContentFrameLayout() {
return mContentFrameLayout;
}
private void disableCollapsingToolbarLayoutScrollingBehavior() {
if (mAppBarLayout == null) {
return;
}
final CoordinatorLayout.LayoutParams params =
(CoordinatorLayout.LayoutParams) mAppBarLayout.getLayoutParams();
final AppBarLayout.Behavior behavior = new AppBarLayout.Behavior();
behavior.setDragCallback(
new AppBarLayout.Behavior.DragCallback() {
@Override
public boolean canDrag(@NonNull AppBarLayout appBarLayout) {
return false;
}
});
params.setBehavior(behavior);
}
@SuppressWarnings("RestrictTo")
private void initCollapsingToolbar() {
if (mCollapsingToolbarLayout == null || mAppBarLayout == null) {
return;
}
mCollapsingToolbarLayout.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
@Override
public void onLayoutChange(View v, int left, int top, int right, int bottom,
int oldLeft, int oldTop, int oldRight, int oldBottom) {
v.removeOnLayoutChangeListener(this);
if (mIsToolbarCollapsed) {
return;
}
final int count = mCollapsingToolbarLayout.getLineCount();
if (count > TOOLBAR_MAX_LINE_NUMBER) {
final ViewGroup.LayoutParams lp = mCollapsingToolbarLayout.getLayoutParams();
lp.height = getResources()
.getDimensionPixelSize(R.dimen.toolbar_three_lines_height);
mCollapsingToolbarLayout.setScrimVisibleHeightTrigger(
getResources().getDimensionPixelSize(
R.dimen.scrim_visible_height_trigger_three_lines));
mCollapsingToolbarLayout.setLayoutParams(lp);
} else if (count == TOOLBAR_MAX_LINE_NUMBER) {
final ViewGroup.LayoutParams lp = mCollapsingToolbarLayout.getLayoutParams();
lp.height = getResources()
.getDimensionPixelSize(R.dimen.toolbar_two_lines_height);
mCollapsingToolbarLayout.setScrimVisibleHeightTrigger(
getResources().getDimensionPixelSize(
R.dimen.scrim_visible_height_trigger_two_lines));
mCollapsingToolbarLayout.setLayoutParams(lp);
}
}
});
}
}