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:
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user