diff --git a/packages/SystemUI/res/drawable/ic_qs_drag_handle.xml b/packages/SystemUI/res/drawable/ic_qs_drag_handle.xml new file mode 100644 index 0000000000000..9a69b33fd5917 --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_qs_drag_handle.xml @@ -0,0 +1,24 @@ + + + + diff --git a/packages/SystemUI/res/layout/qs_panel.xml b/packages/SystemUI/res/layout/qs_panel.xml index 4c6418ace3fcc..2ac03c262edb3 100644 --- a/packages/SystemUI/res/layout/qs_panel.xml +++ b/packages/SystemUI/res/layout/qs_panel.xml @@ -13,13 +13,13 @@ See the License for the specific language governing permissions and limitations under the License. --> - + android:clipChildren="false"> + - + - + + diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java index eeae652eb408a..adcaf5d55773c 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java @@ -27,6 +27,7 @@ import android.util.AttributeSet; import android.view.View; import android.view.WindowInsets; import android.widget.FrameLayout; +import android.widget.ImageView; import com.android.systemui.R; import com.android.systemui.qs.customize.QSCustomizer; @@ -47,6 +48,7 @@ public class QSContainerImpl extends FrameLayout { private float mQsExpansion; private QSCustomizer mQSCustomizer; private NonInterceptingScrollView mQSPanelContainer; + private ImageView mDragHandle; private int mSideMargins; private boolean mQsDisabled; @@ -65,6 +67,7 @@ public class QSContainerImpl extends FrameLayout { mQSDetail = findViewById(R.id.qs_detail); mHeader = findViewById(R.id.header); mQSCustomizer = findViewById(R.id.qs_customize); + mDragHandle = findViewById(R.id.qs_drag_handle); setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO); } @@ -195,6 +198,8 @@ public class QSContainerImpl extends FrameLayout { mQSDetail.setBottom(getTop() + scrollBottom); int qsDetailBottomMargin = ((MarginLayoutParams) mQSDetail.getLayoutParams()).bottomMargin; mQSDetail.setBottom(getTop() + scrollBottom - qsDetailBottomMargin); + // Pin the drag handle to the bottom of the panel. + mDragHandle.setTranslationY(scrollBottom - mDragHandle.getHeight()); } protected int calculateContainerHeight() { @@ -216,6 +221,7 @@ public class QSContainerImpl extends FrameLayout { public void setExpansion(float expansion) { mQsExpansion = expansion; mQSPanelContainer.setScrollingEnabled(expansion > 0f); + mDragHandle.setAlpha(1.0f - expansion); updateExpansion(); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java index 0a1e9d04fab00..2d7bfcd830830 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java @@ -32,6 +32,7 @@ import android.view.View.OnClickListener; import android.view.ViewGroup; import android.view.ViewTreeObserver; import android.widget.FrameLayout.LayoutParams; +import android.widget.ImageView; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; @@ -86,6 +87,7 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca private QSFooter mFooter; private float mLastQSExpansion = -1; private boolean mQsDisabled; + private ImageView mQsDragHandler; private final RemoteInputQuickSettingsDisabler mRemoteInputQuickSettingsDisabler; private final InjectionInflationController mInjectionInflater; @@ -187,6 +189,7 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca mHeader = view.findViewById(R.id.header); mQSPanelController.setHeaderContainer(view.findViewById(R.id.header_text_container)); mFooter = qsFragmentComponent.getQSFooter(); + mQsDragHandler = view.findViewById(R.id.qs_drag_handle); mQsDetailDisplayer.setQsPanelController(mQSPanelController); @@ -291,6 +294,7 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca mQSAnimator.onRtlChanged(); } } + updateQsState(); } @Override @@ -363,15 +367,19 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca : View.INVISIBLE); mHeader.setExpanded((keyguardShowing && !mHeaderAnimating && !mShowCollapsedOnKeyguard) || (mQsExpanded && !mStackScrollerOverscrolling), mQuickQSPanelController); - mFooter.setVisibility( - !mQsDisabled && (mQsExpanded || !keyguardShowing || mHeaderAnimating - || mShowCollapsedOnKeyguard) + mFooter.setVisibility(!mQsDisabled && (mQsExpanded || !keyguardShowing || mHeaderAnimating + || mShowCollapsedOnKeyguard) ? View.VISIBLE : View.INVISIBLE); mFooter.setExpanded((keyguardShowing && !mHeaderAnimating && !mShowCollapsedOnKeyguard) || (mQsExpanded && !mStackScrollerOverscrolling)); mQSPanelController.setVisibility( !mQsDisabled && expandVisually ? View.VISIBLE : View.INVISIBLE); + mQsDragHandler.setVisibility((mQsExpanded || !keyguardShowing || mHeaderAnimating + || mShowCollapsedOnKeyguard) + && Utils.shouldUseSplitNotificationShade(mFeatureFlags, getResources()) + ? View.VISIBLE + : View.GONE); } private boolean isKeyguardState() {