Merge "Updates home controls overflow menu visuals" into udc-dev am: 7a03e3eabc
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/21994912 Change-Id: I459155c9ec0c834bd5f28d3ebd3bc36269411167 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -13,13 +13,17 @@
|
|||||||
~ See the License for the specific language governing permissions and
|
~ See the License for the specific language governing permissions and
|
||||||
~ limitations under the License.
|
~ limitations under the License.
|
||||||
-->
|
-->
|
||||||
<TextView
|
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/controls_more_item_text"
|
||||||
style="@style/Control.MenuItem"
|
style="@style/Control.MenuItem"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="@dimen/control_menu_item_height"
|
||||||
android:layout_gravity="start"
|
android:layout_gravity="center_vertical"
|
||||||
|
android:background="@drawable/controls_popup_item_background"
|
||||||
android:paddingStart="@dimen/control_menu_horizontal_padding"
|
android:paddingStart="@dimen/control_menu_horizontal_padding"
|
||||||
android:paddingEnd="@dimen/control_menu_horizontal_padding"
|
android:paddingEnd="@dimen/control_menu_horizontal_padding"
|
||||||
android:textDirection="locale"/>
|
android:textDirection="locale"
|
||||||
|
android:textSize="@dimen/control_item_text_size"
|
||||||
|
tools:fontFamily="@null"
|
||||||
|
tools:text="@tools:sample/lorem/random" />
|
||||||
@@ -16,18 +16,18 @@
|
|||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="@dimen/control_popup_item_height"
|
android:layout_height="@dimen/control_apps_popup_item_height"
|
||||||
android:background="@drawable/controls_popup_item_background"
|
android:background="@drawable/controls_popup_item_background"
|
||||||
android:gravity="center_vertical|start"
|
android:gravity="center_vertical|start"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:paddingStart="@dimen/control_popup_item_padding"
|
android:paddingStart="@dimen/control_menu_horizontal_padding"
|
||||||
android:paddingEnd="@dimen/control_popup_item_padding">
|
android:paddingEnd="@dimen/control_menu_horizontal_padding">
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/app_icon"
|
android:id="@+id/app_icon"
|
||||||
android:layout_width="@dimen/controls_header_app_icon_size"
|
android:layout_width="@dimen/controls_header_app_icon_size"
|
||||||
android:layout_height="@dimen/controls_header_app_icon_size"
|
android:layout_height="@dimen/controls_header_app_icon_size"
|
||||||
android:layout_marginEnd="@dimen/control_popup_item_padding"
|
android:layout_marginEnd="@dimen/control_menu_horizontal_padding"
|
||||||
android:contentDescription="@null"
|
android:contentDescription="@null"
|
||||||
tools:src="@drawable/ic_android" />
|
tools:src="@drawable/ic_android" />
|
||||||
|
|
||||||
|
|||||||
@@ -1199,19 +1199,17 @@
|
|||||||
<dimen name="controls_top_margin">48dp</dimen>
|
<dimen name="controls_top_margin">48dp</dimen>
|
||||||
<dimen name="controls_content_margin_horizontal">0dp</dimen>
|
<dimen name="controls_content_margin_horizontal">0dp</dimen>
|
||||||
<dimen name="control_header_text_size">24sp</dimen>
|
<dimen name="control_header_text_size">24sp</dimen>
|
||||||
<dimen name="control_item_text_size">16sp</dimen>
|
<dimen name="control_item_text_size">14sp</dimen>
|
||||||
<dimen name="control_menu_item_text_size">16sp</dimen>
|
<dimen name="control_menu_item_text_size">16sp</dimen>
|
||||||
<dimen name="control_menu_item_min_height">56dp</dimen>
|
<dimen name="control_menu_item_height">54dp</dimen>
|
||||||
<dimen name="control_menu_vertical_padding">12dp</dimen>
|
<dimen name="control_menu_vertical_padding">12dp</dimen>
|
||||||
<dimen name="control_menu_horizontal_padding">16dp</dimen>
|
<dimen name="control_menu_horizontal_padding">@dimen/notification_side_paddings</dimen>
|
||||||
<dimen name="control_popup_item_corner_radius">4dp</dimen>
|
<dimen name="control_apps_popup_item_height">56dp</dimen>
|
||||||
<dimen name="control_popup_item_height">56dp</dimen>
|
<dimen name="control_popup_item_corner_radius">@dimen/notification_corner_radius_small</dimen>
|
||||||
<dimen name="control_popup_item_padding">16dp</dimen>
|
<dimen name="control_popup_items_divider_height">@dimen/controls_app_divider_height</dimen>
|
||||||
<dimen name="control_popup_items_divider_height">1dp</dimen>
|
|
||||||
<dimen name="control_popup_max_width">380dp</dimen>
|
<dimen name="control_popup_max_width">380dp</dimen>
|
||||||
<dimen name="control_popup_corner_radius">28dp</dimen>
|
<dimen name="control_popup_corner_radius">@dimen/notification_corner_radius</dimen>
|
||||||
<dimen name="control_popup_horizontal_margin">16dp</dimen>
|
<dimen name="control_popup_horizontal_margin">16dp</dimen>
|
||||||
<dimen name="control_spinner_padding_vertical">24dp</dimen>
|
|
||||||
<dimen name="control_spinner_padding_horizontal">20dp</dimen>
|
<dimen name="control_spinner_padding_horizontal">20dp</dimen>
|
||||||
<dimen name="control_text_size">14sp</dimen>
|
<dimen name="control_text_size">14sp</dimen>
|
||||||
<dimen name="control_icon_size">24dp</dimen>
|
<dimen name="control_icon_size">24dp</dimen>
|
||||||
|
|||||||
@@ -895,7 +895,7 @@
|
|||||||
<item name="android:textColor">@color/control_primary_text</item>
|
<item name="android:textColor">@color/control_primary_text</item>
|
||||||
<item name="android:singleLine">true</item>
|
<item name="android:singleLine">true</item>
|
||||||
<item name="android:gravity">center_vertical</item>
|
<item name="android:gravity">center_vertical</item>
|
||||||
<item name="android:minHeight">@dimen/control_menu_item_min_height</item>
|
<item name="android:minHeight">@dimen/control_menu_item_height</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="Control.Spinner">
|
<style name="Control.Spinner">
|
||||||
|
|||||||
@@ -20,11 +20,18 @@ import android.content.Context
|
|||||||
import android.content.res.Resources
|
import android.content.res.Resources
|
||||||
import android.graphics.drawable.ColorDrawable
|
import android.graphics.drawable.ColorDrawable
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import android.view.Gravity
|
import android.view.Gravity.END
|
||||||
|
import android.view.Gravity.GravityFlags
|
||||||
|
import android.view.Gravity.NO_GRAVITY
|
||||||
|
import android.view.Gravity.START
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import android.view.View.MeasureSpec
|
||||||
|
import android.view.ViewGroup
|
||||||
import android.widget.ListPopupWindow
|
import android.widget.ListPopupWindow
|
||||||
|
import android.widget.ListView
|
||||||
import android.widget.PopupWindow
|
import android.widget.PopupWindow
|
||||||
import com.android.systemui.R
|
import com.android.systemui.R
|
||||||
|
import kotlin.math.max
|
||||||
|
|
||||||
class ControlsPopupMenu(context: Context) : ListPopupWindow(context) {
|
class ControlsPopupMenu(context: Context) : ListPopupWindow(context) {
|
||||||
|
|
||||||
@@ -40,13 +47,13 @@ class ControlsPopupMenu(context: Context) : ListPopupWindow(context) {
|
|||||||
private val dimDrawable: Drawable = ColorDrawable(resources.getColor(R.color.control_popup_dim))
|
private val dimDrawable: Drawable = ColorDrawable(resources.getColor(R.color.control_popup_dim))
|
||||||
|
|
||||||
private var dismissListener: PopupWindow.OnDismissListener? = null
|
private var dismissListener: PopupWindow.OnDismissListener? = null
|
||||||
|
@GravityFlags private var dropDownGravity: Int = NO_GRAVITY
|
||||||
|
|
||||||
init {
|
init {
|
||||||
setBackgroundDrawable(dialogBackground)
|
setBackgroundDrawable(dialogBackground)
|
||||||
|
|
||||||
inputMethodMode = INPUT_METHOD_NOT_NEEDED
|
inputMethodMode = INPUT_METHOD_NOT_NEEDED
|
||||||
isModal = true
|
isModal = true
|
||||||
setDropDownGravity(Gravity.START)
|
|
||||||
|
|
||||||
// dismiss method isn't called when popup is hidden by outside touch. So we need to
|
// dismiss method isn't called when popup is hidden by outside touch. So we need to
|
||||||
// override a listener to remove a dimming foreground
|
// override a listener to remove a dimming foreground
|
||||||
@@ -59,30 +66,68 @@ class ControlsPopupMenu(context: Context) : ListPopupWindow(context) {
|
|||||||
override fun show() {
|
override fun show() {
|
||||||
// need to call show() first in order to construct the listView
|
// need to call show() first in order to construct the listView
|
||||||
super.show()
|
super.show()
|
||||||
|
updateWidth()
|
||||||
val paddedWidth = resources.displayMetrics.widthPixels - 2 * horizontalMargin
|
|
||||||
width = maxWidth.coerceAtMost(paddedWidth)
|
|
||||||
anchorView?.let {
|
anchorView?.let {
|
||||||
horizontalOffset = -width / 2 + it.width / 2
|
positionPopup(it)
|
||||||
verticalOffset = -it.height / 2
|
|
||||||
if (it.layoutDirection == View.LAYOUT_DIRECTION_RTL) {
|
|
||||||
horizontalOffset = -horizontalOffset
|
|
||||||
}
|
|
||||||
|
|
||||||
it.rootView.foreground = dimDrawable
|
it.rootView.foreground = dimDrawable
|
||||||
}
|
}
|
||||||
|
|
||||||
with(listView!!) {
|
with(listView!!) {
|
||||||
clipToOutline = true
|
clipToOutline = true
|
||||||
background = dialogBackground
|
background = dialogBackground
|
||||||
dividerHeight = listDividerHeight
|
dividerHeight = listDividerHeight
|
||||||
}
|
}
|
||||||
|
|
||||||
// actual show takes into account updated ListView specs
|
// actual show takes into account updated ListView specs
|
||||||
super.show()
|
super.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun setDropDownGravity(@GravityFlags gravity: Int) {
|
||||||
|
super.setDropDownGravity(gravity)
|
||||||
|
dropDownGravity = gravity
|
||||||
|
}
|
||||||
|
|
||||||
override fun setOnDismissListener(listener: PopupWindow.OnDismissListener?) {
|
override fun setOnDismissListener(listener: PopupWindow.OnDismissListener?) {
|
||||||
dismissListener = listener
|
dismissListener = listener
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun updateWidth() {
|
||||||
|
val paddedWidth = resources.displayMetrics.widthPixels - 2 * horizontalMargin
|
||||||
|
val maxWidth = maxWidth.coerceAtMost(paddedWidth)
|
||||||
|
when (width) {
|
||||||
|
ViewGroup.LayoutParams.MATCH_PARENT -> {
|
||||||
|
width = maxWidth
|
||||||
|
}
|
||||||
|
ViewGroup.LayoutParams.WRAP_CONTENT -> {
|
||||||
|
width = listView!!.measureDesiredWidth(maxWidth).coerceAtMost(maxWidth)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun positionPopup(anchorView: View) {
|
||||||
|
when (dropDownGravity) {
|
||||||
|
NO_GRAVITY -> {
|
||||||
|
horizontalOffset = (-width + anchorView.width) / 2
|
||||||
|
if (anchorView.layoutDirection == View.LAYOUT_DIRECTION_RTL) {
|
||||||
|
horizontalOffset = -horizontalOffset
|
||||||
|
}
|
||||||
|
}
|
||||||
|
END,
|
||||||
|
START -> {
|
||||||
|
horizontalOffset = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
verticalOffset = -anchorView.height / 2
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun ListView.measureDesiredWidth(maxWidth: Int): Int {
|
||||||
|
var maxItemWidth = 0
|
||||||
|
repeat(adapter.count) {
|
||||||
|
val view = adapter.getView(it, null, listView)
|
||||||
|
view.measure(
|
||||||
|
MeasureSpec.makeMeasureSpec(maxWidth, MeasureSpec.AT_MOST),
|
||||||
|
MeasureSpec.UNSPECIFIED
|
||||||
|
)
|
||||||
|
maxItemWidth = max(maxItemWidth, view.measuredWidth)
|
||||||
|
}
|
||||||
|
return maxItemWidth
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ import android.service.controls.Control
|
|||||||
import android.service.controls.ControlsProviderService
|
import android.service.controls.ControlsProviderService
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.ContextThemeWrapper
|
import android.view.ContextThemeWrapper
|
||||||
|
import android.view.Gravity
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
@@ -72,7 +73,6 @@ import com.android.systemui.dagger.qualifiers.Main
|
|||||||
import com.android.systemui.dump.DumpManager
|
import com.android.systemui.dump.DumpManager
|
||||||
import com.android.systemui.flags.FeatureFlags
|
import com.android.systemui.flags.FeatureFlags
|
||||||
import com.android.systemui.flags.Flags
|
import com.android.systemui.flags.Flags
|
||||||
import com.android.systemui.globalactions.GlobalActionsPopupMenu
|
|
||||||
import com.android.systemui.plugins.ActivityStarter
|
import com.android.systemui.plugins.ActivityStarter
|
||||||
import com.android.systemui.settings.UserTracker
|
import com.android.systemui.settings.UserTracker
|
||||||
import com.android.systemui.statusbar.policy.KeyguardStateController
|
import com.android.systemui.statusbar.policy.KeyguardStateController
|
||||||
@@ -540,12 +540,12 @@ class ControlsUiControllerImpl @Inject constructor (
|
|||||||
val anchor = parent.requireViewById<ImageView>(R.id.controls_more)
|
val anchor = parent.requireViewById<ImageView>(R.id.controls_more)
|
||||||
anchor.setOnClickListener(object : View.OnClickListener {
|
anchor.setOnClickListener(object : View.OnClickListener {
|
||||||
override fun onClick(v: View) {
|
override fun onClick(v: View) {
|
||||||
popup = GlobalActionsPopupMenu(
|
popup = ControlsPopupMenu(popupThemedContext).apply {
|
||||||
popupThemedContext,
|
width = ViewGroup.LayoutParams.WRAP_CONTENT
|
||||||
false /* isDropDownMode */
|
anchorView = anchor
|
||||||
).apply {
|
setDropDownGravity(Gravity.END)
|
||||||
setAnchorView(anchor)
|
|
||||||
setAdapter(adapter)
|
setAdapter(adapter)
|
||||||
|
|
||||||
setOnItemClickListener(object : AdapterView.OnItemClickListener {
|
setOnItemClickListener(object : AdapterView.OnItemClickListener {
|
||||||
override fun onItemClick(
|
override fun onItemClick(
|
||||||
parent: AdapterView<*>,
|
parent: AdapterView<*>,
|
||||||
@@ -618,7 +618,8 @@ class ControlsUiControllerImpl @Inject constructor (
|
|||||||
anchor.setOnClickListener(object : View.OnClickListener {
|
anchor.setOnClickListener(object : View.OnClickListener {
|
||||||
override fun onClick(v: View) {
|
override fun onClick(v: View) {
|
||||||
popup = ControlsPopupMenu(popupThemedContext).apply {
|
popup = ControlsPopupMenu(popupThemedContext).apply {
|
||||||
setAnchorView(anchor)
|
anchorView = anchor
|
||||||
|
width = ViewGroup.LayoutParams.MATCH_PARENT
|
||||||
setAdapter(adapter)
|
setAdapter(adapter)
|
||||||
|
|
||||||
setOnItemClickListener(object : AdapterView.OnItemClickListener {
|
setOnItemClickListener(object : AdapterView.OnItemClickListener {
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import android.graphics.drawable.ShapeDrawable
|
|||||||
import android.testing.AndroidTestingRunner
|
import android.testing.AndroidTestingRunner
|
||||||
import android.util.DisplayMetrics
|
import android.util.DisplayMetrics
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
import android.widget.PopupWindow.OnDismissListener
|
import android.widget.PopupWindow.OnDismissListener
|
||||||
import androidx.test.ext.junit.rules.ActivityScenarioRule
|
import androidx.test.ext.junit.rules.ActivityScenarioRule
|
||||||
import androidx.test.filters.SmallTest
|
import androidx.test.filters.SmallTest
|
||||||
@@ -29,13 +30,17 @@ import com.android.systemui.R
|
|||||||
import com.android.systemui.SysuiTestCase
|
import com.android.systemui.SysuiTestCase
|
||||||
import com.android.systemui.activity.EmptyTestActivity
|
import com.android.systemui.activity.EmptyTestActivity
|
||||||
import com.android.systemui.util.mockito.whenever
|
import com.android.systemui.util.mockito.whenever
|
||||||
|
import com.android.systemui.widget.FakeListAdapter
|
||||||
|
import com.android.systemui.widget.FakeListAdapter.FakeListAdapterItem
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import org.junit.Before
|
||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
import org.mockito.Mockito.mock
|
import org.mockito.Mockito.mock
|
||||||
import org.mockito.Mockito.spy
|
import org.mockito.Mockito.spy
|
||||||
import org.mockito.Mockito.verify
|
import org.mockito.Mockito.verify
|
||||||
|
import org.mockito.MockitoAnnotations
|
||||||
|
|
||||||
@SmallTest
|
@SmallTest
|
||||||
@RunWith(AndroidTestingRunner::class)
|
@RunWith(AndroidTestingRunner::class)
|
||||||
@@ -52,10 +57,16 @@ open class ControlsPopupMenuTest : SysuiTestCase() {
|
|||||||
|
|
||||||
@Rule @JvmField val activityScenarioRule = ActivityScenarioRule(EmptyTestActivity::class.java)
|
@Rule @JvmField val activityScenarioRule = ActivityScenarioRule(EmptyTestActivity::class.java)
|
||||||
|
|
||||||
private val testDisplayMetrics: DisplayMetrics = DisplayMetrics()
|
private val testDisplayMetrics = DisplayMetrics()
|
||||||
|
|
||||||
|
@Before
|
||||||
|
fun setup() {
|
||||||
|
MockitoAnnotations.initMocks(this)
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testDismissListenerWorks() = testPopup { popupMenu ->
|
fun testDismissListenerWorks() = testPopup { activity, popupMenu ->
|
||||||
|
popupMenu.setAdapter(FakeListAdapter())
|
||||||
val listener = mock(OnDismissListener::class.java)
|
val listener = mock(OnDismissListener::class.java)
|
||||||
popupMenu.setOnDismissListener(listener)
|
popupMenu.setOnDismissListener(listener)
|
||||||
popupMenu.show()
|
popupMenu.show()
|
||||||
@@ -66,7 +77,9 @@ open class ControlsPopupMenuTest : SysuiTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testPopupDoesntExceedMaxWidth() = testPopup { popupMenu ->
|
fun testPopupDoesntExceedMaxWidth() = testPopup { activity, popupMenu ->
|
||||||
|
popupMenu.setAdapter(FakeListAdapter())
|
||||||
|
popupMenu.width = ViewGroup.LayoutParams.MATCH_PARENT
|
||||||
testDisplayMetrics.widthPixels = DISPLAY_WIDTH_WIDE
|
testDisplayMetrics.widthPixels = DISPLAY_WIDTH_WIDE
|
||||||
|
|
||||||
popupMenu.show()
|
popupMenu.show()
|
||||||
@@ -75,7 +88,9 @@ open class ControlsPopupMenuTest : SysuiTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testPopupMarginsWidthLessMax() = testPopup { popupMenu ->
|
fun testPopupMarginsWidthLessMax() = testPopup { activity, popupMenu ->
|
||||||
|
popupMenu.setAdapter(FakeListAdapter())
|
||||||
|
popupMenu.width = ViewGroup.LayoutParams.MATCH_PARENT
|
||||||
testDisplayMetrics.widthPixels = DISPLAY_WIDTH_NARROW
|
testDisplayMetrics.widthPixels = DISPLAY_WIDTH_NARROW
|
||||||
|
|
||||||
popupMenu.show()
|
popupMenu.show()
|
||||||
@@ -83,10 +98,32 @@ open class ControlsPopupMenuTest : SysuiTestCase() {
|
|||||||
assertThat(popupMenu.width).isEqualTo(DISPLAY_WIDTH_NARROW - 2 * HORIZONTAL_MARGIN)
|
assertThat(popupMenu.width).isEqualTo(DISPLAY_WIDTH_NARROW - 2 * HORIZONTAL_MARGIN)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun testPopup(test: (popup: ControlsPopupMenu) -> Unit) {
|
@Test
|
||||||
|
fun testWrapContentDoesntExceedMax() = testPopup { activity, popupMenu ->
|
||||||
|
popupMenu.setAdapter(
|
||||||
|
FakeListAdapter(
|
||||||
|
listOf(
|
||||||
|
FakeListAdapterItem({ _, _, _ ->
|
||||||
|
View(activity).apply { minimumWidth = MAX_WIDTH + 1 }
|
||||||
|
})
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
popupMenu.width = ViewGroup.LayoutParams.WRAP_CONTENT
|
||||||
|
testDisplayMetrics.widthPixels = DISPLAY_WIDTH_NARROW
|
||||||
|
|
||||||
|
popupMenu.show()
|
||||||
|
|
||||||
|
assertThat(popupMenu.width).isEqualTo(DISPLAY_WIDTH_NARROW - 2 * HORIZONTAL_MARGIN)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun testPopup(test: (activity: Activity, popup: ControlsPopupMenu) -> Unit) {
|
||||||
activityScenarioRule.scenario.onActivity { activity ->
|
activityScenarioRule.scenario.onActivity { activity ->
|
||||||
val testActivity = setupActivity(activity)
|
val testActivity = setupActivity(activity)
|
||||||
test(ControlsPopupMenu(testActivity).apply { anchorView = View(testActivity) })
|
test(
|
||||||
|
testActivity,
|
||||||
|
ControlsPopupMenu(testActivity).apply { anchorView = View(testActivity) }
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2023 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.systemui.widget
|
||||||
|
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.widget.BaseAdapter
|
||||||
|
|
||||||
|
class FakeListAdapter(private var items: List<FakeListAdapterItem> = emptyList()) : BaseAdapter() {
|
||||||
|
|
||||||
|
fun setItems(items: List<FakeListAdapterItem>) {
|
||||||
|
this.items = items
|
||||||
|
notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getCount(): Int = items.size
|
||||||
|
|
||||||
|
override fun getItem(position: Int): Any = items[position].data
|
||||||
|
|
||||||
|
override fun getItemId(position: Int): Long = items[position].id
|
||||||
|
|
||||||
|
override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View =
|
||||||
|
items[position].view(position, convertView, parent)
|
||||||
|
|
||||||
|
class FakeListAdapterItem(
|
||||||
|
/** Result returned in [Adapter#getView] */
|
||||||
|
val view: (position: Int, convertView: View?, parent: ViewGroup?) -> View,
|
||||||
|
/** Returned in [Adapter#getItemId] */
|
||||||
|
val id: Long = 0,
|
||||||
|
/** Returned in [Adapter#getItem] */
|
||||||
|
val data: Any = Unit,
|
||||||
|
)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user