Fix navbar clipping

Instead of clipping on the navbar, as the QS background takes the whole
screen, just have a padding the size of the navbar. That way, when the
QS container is scrolled completely to the bottom, no view is obstructed
by the nav bar.

Test: manual
Fixes: 187444362
Change-Id: If22f46a27d48066571ba5c2193c9f6e2e0c3fe24
This commit is contained in:
Fabian Kozynski
2021-05-10 13:38:50 -04:00
parent 2c987129a7
commit 89a6033e93
6 changed files with 40 additions and 38 deletions

View File

@@ -23,7 +23,6 @@
android:clickable="true"
android:orientation="vertical"
android:layout_marginTop="@*android:dimen/quick_qs_offset_height"
android:layout_marginBottom="@dimen/qs_container_bottom_padding"
android:paddingBottom="8dp"
android:visibility="invisible"
android:elevation="4dp"

View File

@@ -17,7 +17,7 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/quick_settings_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_height="match_parent"
android:clipToPadding="false"
android:clipChildren="false" >
@@ -25,7 +25,6 @@
android:id="@+id/expanded_qs_scroll_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/qs_container_bottom_padding"
android:elevation="4dp"
android:importantForAccessibility="no"
android:scrollbars="none"

View File

@@ -623,8 +623,6 @@
<dimen name="qs_notif_collapsed_space">64dp</dimen>
<dimen name="qs_container_bottom_padding">24dp</dimen>
<!-- Desired qs icon overlay size. -->
<dimen name="qs_detail_icon_overlay_size">24dp</dimen>

View File

@@ -129,6 +129,12 @@ public class QSContainerImpl extends FrameLayout {
@Override
public WindowInsets onApplyWindowInsets(WindowInsets insets) {
mNavBarInset = insets.getInsets(WindowInsets.Type.navigationBars()).bottom;
mQSPanelContainer.setPaddingRelative(
mQSPanelContainer.getPaddingStart(),
mQSPanelContainer.getPaddingTop(),
mQSPanelContainer.getPaddingEnd(),
mNavBarInset
);
return super.onApplyWindowInsets(insets);
}
@@ -138,8 +144,7 @@ public class QSContainerImpl extends FrameLayout {
// bottom and footer are inside the screen.
MarginLayoutParams layoutParams = (MarginLayoutParams) mQSPanelContainer.getLayoutParams();
int availableScreenHeight = getDisplayHeight() - mNavBarInset;
int maxQs = availableScreenHeight - layoutParams.topMargin - layoutParams.bottomMargin
int maxQs = getDisplayHeight() - layoutParams.topMargin - layoutParams.bottomMargin
- getPaddingBottom();
int padding = mPaddingLeft + mPaddingRight + layoutParams.leftMargin
+ layoutParams.rightMargin;
@@ -148,10 +153,8 @@ public class QSContainerImpl extends FrameLayout {
mQSPanelContainer.measure(qsPanelWidthSpec,
MeasureSpec.makeMeasureSpec(maxQs, MeasureSpec.AT_MOST));
int width = mQSPanelContainer.getMeasuredWidth() + padding;
int height = layoutParams.topMargin + layoutParams.bottomMargin
+ mQSPanelContainer.getMeasuredHeight() + getPaddingBottom();
super.onMeasure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(availableScreenHeight, MeasureSpec.EXACTLY));
MeasureSpec.makeMeasureSpec(getDisplayHeight(), MeasureSpec.EXACTLY));
// QSCustomizer will always be the height of the screen, but do this after
// other measuring to avoid changing the height of the QS.
mQSCustomizer.measure(widthMeasureSpec,
@@ -196,13 +199,10 @@ public class QSContainerImpl extends FrameLayout {
void updateResources(QSPanelController qsPanelController,
QuickStatusBarHeaderController quickStatusBarHeaderController) {
mQSPanelContainer.setPaddingRelative(
mQSPanelContainer.getPaddingStart(),
mContext.getResources().getDimensionPixelSize(
com.android.internal.R.dimen.quick_qs_offset_height),
mQSPanelContainer.getPaddingEnd(),
mContext.getResources().getDimensionPixelSize(R.dimen.qs_container_bottom_padding)
);
LayoutParams layoutParams = (LayoutParams) mQSPanelContainer.getLayoutParams();
layoutParams.topMargin = mContext.getResources().getDimensionPixelSize(
com.android.internal.R.dimen.quick_qs_offset_height);
mQSPanelContainer.setLayoutParams(layoutParams);
int sideMargins = getResources().getDimensionPixelSize(R.dimen.notification_side_paddings);
int padding = getResources().getDimensionPixelSize(

View File

@@ -30,6 +30,7 @@ import android.util.SparseArray;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewStub;
import android.view.WindowInsets;
import android.view.accessibility.AccessibilityEvent;
import android.widget.ImageView;
import android.widget.LinearLayout;
@@ -153,11 +154,18 @@ public class QSDetail extends LinearLayout {
MarginLayoutParams lp = (MarginLayoutParams) getLayoutParams();
lp.topMargin = mContext.getResources().getDimensionPixelSize(
com.android.internal.R.dimen.quick_qs_offset_height);
lp.bottomMargin = mContext.getResources().getDimensionPixelSize(
R.dimen.qs_container_bottom_padding);
setLayoutParams(lp);
}
@Override
public WindowInsets onApplyWindowInsets(WindowInsets insets) {
int bottomNavBar = insets.getInsets(WindowInsets.Type.navigationBars()).bottom;
MarginLayoutParams lp = (MarginLayoutParams) getLayoutParams();
lp.bottomMargin = bottomNavBar;
setLayoutParams(lp);
return super.onApplyWindowInsets(insets);
}
public boolean isClosingDetail() {
return mClosingDetail;
}

View File

@@ -30,6 +30,7 @@ import android.testing.TestableLooper.RunWithLooper;
import android.testing.ViewUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.FrameLayout;
import androidx.test.filters.SmallTest;
@@ -58,24 +59,26 @@ public class QSDetailTest extends SysuiTestCase {
private DetailAdapter mMockDetailAdapter;
private TestableLooper mTestableLooper;
private UiEventLoggerFake mUiEventLogger;
private FrameLayout mParent;
@Before
public void setup() throws Exception {
mTestableLooper = TestableLooper.get(this);
mUiEventLogger = QSEvents.INSTANCE.setLoggerForTesting();
mTestableLooper.runWithLooper(() -> {
mMetricsLogger = mDependency.injectMockDependency(MetricsLogger.class);
mActivityStarter = mDependency.injectMockDependency(ActivityStarter.class);
mQsDetail = (QSDetail) LayoutInflater.from(mContext).inflate(R.layout.qs_detail, null);
mQsPanelController = mock(QSPanelController.class);
mQuickHeader = mock(QuickStatusBarHeader.class);
mQsDetail.setQsPanel(mQsPanelController, mQuickHeader, mock(QSFooter.class));
mParent = new FrameLayout(mContext);
mMetricsLogger = mDependency.injectMockDependency(MetricsLogger.class);
mActivityStarter = mDependency.injectMockDependency(ActivityStarter.class);
LayoutInflater.from(mContext).inflate(R.layout.qs_detail, mParent);
mQsDetail = (QSDetail) mParent.getChildAt(0);
mMockDetailAdapter = mock(DetailAdapter.class);
when(mMockDetailAdapter.createDetailView(any(), any(), any()))
.thenReturn(mock(View.class));
});
mQsPanelController = mock(QSPanelController.class);
mQuickHeader = mock(QuickStatusBarHeader.class);
mQsDetail.setQsPanel(mQsPanelController, mQuickHeader, mock(QSFooter.class));
mMockDetailAdapter = mock(DetailAdapter.class);
when(mMockDetailAdapter.createDetailView(any(), any(), any()))
.thenReturn(new View(mContext));
// Only detail in use is the user detail
when(mMockDetailAdapter.openDetailEvent())
@@ -84,16 +87,18 @@ public class QSDetailTest extends SysuiTestCase {
.thenReturn(QSUserSwitcherEvent.QS_USER_DETAIL_CLOSE);
when(mMockDetailAdapter.moreSettingsEvent())
.thenReturn(QSUserSwitcherEvent.QS_USER_MORE_SETTINGS);
ViewUtils.attachView(mParent);
}
@After
public void tearDown() {
QSEvents.INSTANCE.resetLogger();
mTestableLooper.processAllMessages();
ViewUtils.detachView(mParent);
}
@Test
public void testShowDetail_Metrics() {
ViewUtils.attachView(mQsDetail);
mTestableLooper.processAllMessages();
mQsDetail.handleShowingDetail(mMockDetailAdapter, 0, 0, false);
@@ -107,14 +112,10 @@ public class QSDetailTest extends SysuiTestCase {
assertEquals(1, mUiEventLogger.numLogs());
assertEquals(QSUserSwitcherEvent.QS_USER_DETAIL_CLOSE.getId(), mUiEventLogger.eventId(0));
ViewUtils.detachView(mQsDetail);
mTestableLooper.processAllMessages();
}
@Test
public void testMoreSettingsButton() {
ViewUtils.attachView(mQsDetail);
mTestableLooper.processAllMessages();
mQsDetail.handleShowingDetail(mMockDetailAdapter, 0, 0, false);
@@ -127,9 +128,6 @@ public class QSDetailTest extends SysuiTestCase {
assertEquals(QSUserSwitcherEvent.QS_USER_MORE_SETTINGS.getId(), mUiEventLogger.eventId(0));
verify(mActivityStarter).postStartActivityDismissingKeyguard(any(), anyInt());
ViewUtils.detachView(mQsDetail);
mTestableLooper.processAllMessages();
}
@Test