Loading packages/SystemUI/res/drawable/bluetooth_tile_dialog_bg_off.xml 0 → 100644 +26 −0 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <!-- ~ 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. --> <ripple xmlns:android="http://schemas.android.com/apk/res/android" android:color="?android:attr/colorControlHighlight"> <item android:id="@android:id/mask"> <shape android:shape="rectangle"> <solid android:color="@android:color/white"/> <corners android:radius="@dimen/settingslib_switch_bar_radius"/> </shape> </item> </ripple> No newline at end of file packages/SystemUI/res/drawable/bluetooth_tile_dialog_bg_off_busy.xml 0 → 100644 +25 −0 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <!-- ~ 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. --> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@android:id/background"> <shape> <solid android:color="?android:attr/colorControlHighlight" /> <corners android:radius="@dimen/settingslib_switch_bar_radius"/> </shape> </item> </layer-list> No newline at end of file packages/SystemUI/res/layout/bluetooth_device_item.xml +63 −70 Original line number Diff line number Diff line Loading @@ -14,22 +14,16 @@ ~ limitations under the License. --> <!-- TODO(b/298124674) remove this root --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/bluetooth_device_list_container" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:layout_marginBottom="4dp"> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/bluetooth_device_row" style="@style/BluetoothTileDialog.Device" android:layout_width="match_parent" android:layout_height="@dimen/bluetooth_dialog_device_height" android:paddingEnd="24dp" android:paddingStart="20dp" android:baselineAligned="false"> android:layout_marginBottom="4dp"> <ImageView android:id="@+id/bluetooth_device_icon" Loading @@ -41,15 +35,6 @@ app:layout_constraintBottom_toBottomOf="parent" android:layout_gravity="center_vertical" /> <View android:id="@+id/bluetooth_device" android:layout_width="0dp" android:layout_height="0dp" app:layout_constraintTop_toTopOf="@+id/bluetooth_device_name" app:layout_constraintBottom_toBottomOf="@+id/bluetooth_device_summary" app:layout_constraintStart_toStartOf="@+id/bluetooth_device_name" app:layout_constraintEnd_toEndOf="@+id/bluetooth_device_name" /> <TextView android:layout_width="0dp" android:id="@+id/bluetooth_device_name" Loading Loading @@ -77,8 +62,17 @@ app:layout_constraintBottom_toBottomOf="parent" android:gravity="center_vertical" /> <ImageView <View android:id="@+id/gear_icon" android:layout_width="0dp" android:layout_height="0dp" app:layout_constraintStart_toEndOf="@+id/bluetooth_device_name" app:layout_constraintEnd_toEndOf="@+id/gear_icon_image" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" /> <ImageView android:id="@+id/gear_icon_image" android:src="@drawable/ic_settings_24dp" android:contentDescription="@string/accessibility_bluetooth_device_settings_gear" android:layout_width="0dp" Loading @@ -91,4 +85,3 @@ android:gravity="center_vertical" android:paddingStart="10dp" /> </androidx.constraintlayout.widget.ConstraintLayout> No newline at end of file </LinearLayout> No newline at end of file packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothStateInteractor.kt +1 −1 Original line number Diff line number Diff line Loading @@ -40,7 +40,7 @@ constructor( @Application private val coroutineScope: CoroutineScope, ) { internal val updateBluetoothStateFlow: StateFlow<Boolean?> = internal val bluetoothStateUpdate: StateFlow<Boolean?> = conflatedCallbackFlow { val listener = object : BluetoothCallback { Loading packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialog.kt +50 −35 Original line number Diff line number Diff line Loading @@ -26,6 +26,8 @@ import android.view.ViewGroup import android.widget.ImageView import android.widget.Switch import android.widget.TextView import androidx.recyclerview.widget.AsyncListDiffer import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.android.internal.logging.UiEventLogger Loading @@ -42,24 +44,26 @@ import kotlinx.coroutines.flow.asStateFlow internal class BluetoothTileDialog constructor( private val bluetoothToggleInitialValue: Boolean, private val subtitleResIdInitialValue: Int, private val bluetoothTileDialogCallback: BluetoothTileDialogCallback, private val uiEventLogger: UiEventLogger, context: Context, ) : SystemUIDialog(context, DEFAULT_THEME, DEFAULT_DISMISS_ON_DEVICE_LOCK) { private val mutableBluetoothStateSwitchedFlow: MutableStateFlow<Boolean> = private val mutableBluetoothStateToggle: MutableStateFlow<Boolean> = MutableStateFlow(bluetoothToggleInitialValue) internal val bluetoothStateSwitchedFlow get() = mutableBluetoothStateSwitchedFlow.asStateFlow() internal val bluetoothStateToggle get() = mutableBluetoothStateToggle.asStateFlow() private val mutableClickedFlow: MutableSharedFlow<Pair<DeviceItem, Int>> = private val mutableDeviceItemClick: MutableSharedFlow<DeviceItem> = MutableSharedFlow(extraBufferCapacity = 1) internal val deviceItemClickedFlow get() = mutableClickedFlow.asSharedFlow() internal val deviceItemClick get() = mutableDeviceItemClick.asSharedFlow() private val deviceItemAdapter: Adapter = Adapter(bluetoothTileDialogCallback) private lateinit var toggleView: Switch private lateinit var subtitleTextView: TextView private lateinit var doneButton: View private lateinit var seeAllViewGroup: View private lateinit var pairNewDeviceViewGroup: View Loading @@ -74,6 +78,7 @@ constructor( setContentView(LayoutInflater.from(context).inflate(R.layout.bluetooth_tile_dialog, null)) toggleView = requireViewById(R.id.bluetooth_toggle) subtitleTextView = requireViewById(R.id.bluetooth_tile_dialog_subtitle) as TextView doneButton = requireViewById(R.id.done_button) seeAllViewGroup = requireViewById(R.id.see_all_layout_group) pairNewDeviceViewGroup = requireViewById(R.id.pair_new_device_layout_group) Loading @@ -84,6 +89,7 @@ constructor( setupToggle() setupRecyclerView() subtitleTextView.text = context.getString(subtitleResIdInitialValue) doneButton.setOnClickListener { dismiss() } seeAllText.setOnClickListener { bluetoothTileDialogCallback.onSeeAllClicked(it) } pairNewDeviceText.setOnClickListener { Loading @@ -91,7 +97,6 @@ constructor( } } // TODO(b/298124674): use DiffUtil or AsyncListDiffer to avoid updating the whole list internal fun onDeviceItemUpdated( deviceItem: List<DeviceItem>, showSeeAll: Boolean, Loading @@ -102,18 +107,15 @@ constructor( deviceItemAdapter.refreshDeviceItemList(deviceItem) } internal fun onDeviceItemUpdatedAtPosition(deviceItem: DeviceItem, position: Int) { deviceItemAdapter.refreshDeviceItem(deviceItem, position) } internal fun onBluetoothStateUpdated(isEnabled: Boolean) { internal fun onBluetoothStateUpdated(isEnabled: Boolean, subtitleResId: Int) { toggleView.isChecked = isEnabled subtitleTextView.text = context.getString(subtitleResId) } private fun setupToggle() { toggleView.isChecked = bluetoothToggleInitialValue toggleView.setOnCheckedChangeListener { _, isChecked -> mutableBluetoothStateSwitchedFlow.value = isChecked mutableBluetoothStateToggle.value = isChecked uiEventLogger.log(BluetoothTileDialogUiEvent.BLUETOOTH_TOGGLE_CLICKED) } } Loading @@ -128,7 +130,32 @@ constructor( internal inner class Adapter(private val onClickCallback: BluetoothTileDialogCallback) : RecyclerView.Adapter<Adapter.DeviceItemViewHolder>() { private val deviceItem: MutableList<DeviceItem> = mutableListOf() private val diffUtilCallback = object : DiffUtil.ItemCallback<DeviceItem>() { override fun areItemsTheSame( deviceItem1: DeviceItem, deviceItem2: DeviceItem ): Boolean { return deviceItem1.cachedBluetoothDevice == deviceItem2.cachedBluetoothDevice } override fun areContentsTheSame( deviceItem1: DeviceItem, deviceItem2: DeviceItem ): Boolean { return deviceItem1.type == deviceItem2.type && deviceItem1.cachedBluetoothDevice == deviceItem2.cachedBluetoothDevice && deviceItem1.deviceName == deviceItem2.deviceName && deviceItem1.connectionSummary == deviceItem2.connectionSummary && // Ignored the icon drawable deviceItem1.iconWithDescription?.second == deviceItem2.iconWithDescription?.second && deviceItem1.background == deviceItem2.background && deviceItem1.isEnabled == deviceItem2.isEnabled } } private val asyncListDiffer = AsyncListDiffer(this, diffUtilCallback) override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DeviceItemViewHolder { val view = Loading @@ -137,29 +164,21 @@ constructor( return DeviceItemViewHolder(view) } override fun getItemCount() = deviceItem.size override fun getItemCount() = asyncListDiffer.currentList.size override fun onBindViewHolder(holder: DeviceItemViewHolder, position: Int) { val item = getItem(position) holder.bind(item, position, onClickCallback) holder.bind(item, onClickCallback) } internal fun getItem(position: Int) = deviceItem[position] internal fun getItem(position: Int) = asyncListDiffer.currentList[position] internal fun refreshDeviceItemList(updated: List<DeviceItem>) { deviceItem.clear() deviceItem.addAll(updated) notifyDataSetChanged() } internal fun refreshDeviceItem(updated: DeviceItem, position: Int) { deviceItem[position] = updated notifyItemChanged(position) asyncListDiffer.submitList(updated) } internal inner class DeviceItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { private val container = view.requireViewById<View>(R.id.bluetooth_device_row) private val deviceView = view.requireViewById<View>(R.id.bluetooth_device) private val nameView = view.requireViewById<TextView>(R.id.bluetooth_device_name) private val summaryView = view.requireViewById<TextView>(R.id.bluetooth_device_summary) private val iconView = view.requireViewById<ImageView>(R.id.bluetooth_device_icon) Loading @@ -167,18 +186,16 @@ constructor( internal fun bind( item: DeviceItem, position: Int, deviceItemOnClickCallback: BluetoothTileDialogCallback ) { container.apply { isEnabled = item.isEnabled alpha = item.alpha background = item.background } deviceView.setOnClickListener { mutableClickedFlow.tryEmit(Pair(item, position)) background = item.background?.let { context.getDrawable(it) } setOnClickListener { mutableDeviceItemClick.tryEmit(item) uiEventLogger.log(BluetoothTileDialogUiEvent.DEVICE_CLICKED) } } nameView.text = item.deviceName summaryView.text = item.connectionSummary iconView.apply { Loading @@ -195,8 +212,6 @@ constructor( } internal companion object { const val ENABLED_ALPHA = 1.0f const val DISABLED_ALPHA = 0.3f const val MAX_DEVICE_ITEM_ENTRY = 3 const val ACTION_BLUETOOTH_DEVICE_DETAILS = "com.android.settings.BLUETOOTH_DEVICE_DETAIL_SETTINGS" Loading Loading
packages/SystemUI/res/drawable/bluetooth_tile_dialog_bg_off.xml 0 → 100644 +26 −0 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <!-- ~ 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. --> <ripple xmlns:android="http://schemas.android.com/apk/res/android" android:color="?android:attr/colorControlHighlight"> <item android:id="@android:id/mask"> <shape android:shape="rectangle"> <solid android:color="@android:color/white"/> <corners android:radius="@dimen/settingslib_switch_bar_radius"/> </shape> </item> </ripple> No newline at end of file
packages/SystemUI/res/drawable/bluetooth_tile_dialog_bg_off_busy.xml 0 → 100644 +25 −0 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <!-- ~ 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. --> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@android:id/background"> <shape> <solid android:color="?android:attr/colorControlHighlight" /> <corners android:radius="@dimen/settingslib_switch_bar_radius"/> </shape> </item> </layer-list> No newline at end of file
packages/SystemUI/res/layout/bluetooth_device_item.xml +63 −70 Original line number Diff line number Diff line Loading @@ -14,22 +14,16 @@ ~ limitations under the License. --> <!-- TODO(b/298124674) remove this root --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/bluetooth_device_list_container" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:layout_marginBottom="4dp"> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/bluetooth_device_row" style="@style/BluetoothTileDialog.Device" android:layout_width="match_parent" android:layout_height="@dimen/bluetooth_dialog_device_height" android:paddingEnd="24dp" android:paddingStart="20dp" android:baselineAligned="false"> android:layout_marginBottom="4dp"> <ImageView android:id="@+id/bluetooth_device_icon" Loading @@ -41,15 +35,6 @@ app:layout_constraintBottom_toBottomOf="parent" android:layout_gravity="center_vertical" /> <View android:id="@+id/bluetooth_device" android:layout_width="0dp" android:layout_height="0dp" app:layout_constraintTop_toTopOf="@+id/bluetooth_device_name" app:layout_constraintBottom_toBottomOf="@+id/bluetooth_device_summary" app:layout_constraintStart_toStartOf="@+id/bluetooth_device_name" app:layout_constraintEnd_toEndOf="@+id/bluetooth_device_name" /> <TextView android:layout_width="0dp" android:id="@+id/bluetooth_device_name" Loading Loading @@ -77,8 +62,17 @@ app:layout_constraintBottom_toBottomOf="parent" android:gravity="center_vertical" /> <ImageView <View android:id="@+id/gear_icon" android:layout_width="0dp" android:layout_height="0dp" app:layout_constraintStart_toEndOf="@+id/bluetooth_device_name" app:layout_constraintEnd_toEndOf="@+id/gear_icon_image" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" /> <ImageView android:id="@+id/gear_icon_image" android:src="@drawable/ic_settings_24dp" android:contentDescription="@string/accessibility_bluetooth_device_settings_gear" android:layout_width="0dp" Loading @@ -91,4 +85,3 @@ android:gravity="center_vertical" android:paddingStart="10dp" /> </androidx.constraintlayout.widget.ConstraintLayout> No newline at end of file </LinearLayout> No newline at end of file
packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothStateInteractor.kt +1 −1 Original line number Diff line number Diff line Loading @@ -40,7 +40,7 @@ constructor( @Application private val coroutineScope: CoroutineScope, ) { internal val updateBluetoothStateFlow: StateFlow<Boolean?> = internal val bluetoothStateUpdate: StateFlow<Boolean?> = conflatedCallbackFlow { val listener = object : BluetoothCallback { Loading
packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialog.kt +50 −35 Original line number Diff line number Diff line Loading @@ -26,6 +26,8 @@ import android.view.ViewGroup import android.widget.ImageView import android.widget.Switch import android.widget.TextView import androidx.recyclerview.widget.AsyncListDiffer import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.android.internal.logging.UiEventLogger Loading @@ -42,24 +44,26 @@ import kotlinx.coroutines.flow.asStateFlow internal class BluetoothTileDialog constructor( private val bluetoothToggleInitialValue: Boolean, private val subtitleResIdInitialValue: Int, private val bluetoothTileDialogCallback: BluetoothTileDialogCallback, private val uiEventLogger: UiEventLogger, context: Context, ) : SystemUIDialog(context, DEFAULT_THEME, DEFAULT_DISMISS_ON_DEVICE_LOCK) { private val mutableBluetoothStateSwitchedFlow: MutableStateFlow<Boolean> = private val mutableBluetoothStateToggle: MutableStateFlow<Boolean> = MutableStateFlow(bluetoothToggleInitialValue) internal val bluetoothStateSwitchedFlow get() = mutableBluetoothStateSwitchedFlow.asStateFlow() internal val bluetoothStateToggle get() = mutableBluetoothStateToggle.asStateFlow() private val mutableClickedFlow: MutableSharedFlow<Pair<DeviceItem, Int>> = private val mutableDeviceItemClick: MutableSharedFlow<DeviceItem> = MutableSharedFlow(extraBufferCapacity = 1) internal val deviceItemClickedFlow get() = mutableClickedFlow.asSharedFlow() internal val deviceItemClick get() = mutableDeviceItemClick.asSharedFlow() private val deviceItemAdapter: Adapter = Adapter(bluetoothTileDialogCallback) private lateinit var toggleView: Switch private lateinit var subtitleTextView: TextView private lateinit var doneButton: View private lateinit var seeAllViewGroup: View private lateinit var pairNewDeviceViewGroup: View Loading @@ -74,6 +78,7 @@ constructor( setContentView(LayoutInflater.from(context).inflate(R.layout.bluetooth_tile_dialog, null)) toggleView = requireViewById(R.id.bluetooth_toggle) subtitleTextView = requireViewById(R.id.bluetooth_tile_dialog_subtitle) as TextView doneButton = requireViewById(R.id.done_button) seeAllViewGroup = requireViewById(R.id.see_all_layout_group) pairNewDeviceViewGroup = requireViewById(R.id.pair_new_device_layout_group) Loading @@ -84,6 +89,7 @@ constructor( setupToggle() setupRecyclerView() subtitleTextView.text = context.getString(subtitleResIdInitialValue) doneButton.setOnClickListener { dismiss() } seeAllText.setOnClickListener { bluetoothTileDialogCallback.onSeeAllClicked(it) } pairNewDeviceText.setOnClickListener { Loading @@ -91,7 +97,6 @@ constructor( } } // TODO(b/298124674): use DiffUtil or AsyncListDiffer to avoid updating the whole list internal fun onDeviceItemUpdated( deviceItem: List<DeviceItem>, showSeeAll: Boolean, Loading @@ -102,18 +107,15 @@ constructor( deviceItemAdapter.refreshDeviceItemList(deviceItem) } internal fun onDeviceItemUpdatedAtPosition(deviceItem: DeviceItem, position: Int) { deviceItemAdapter.refreshDeviceItem(deviceItem, position) } internal fun onBluetoothStateUpdated(isEnabled: Boolean) { internal fun onBluetoothStateUpdated(isEnabled: Boolean, subtitleResId: Int) { toggleView.isChecked = isEnabled subtitleTextView.text = context.getString(subtitleResId) } private fun setupToggle() { toggleView.isChecked = bluetoothToggleInitialValue toggleView.setOnCheckedChangeListener { _, isChecked -> mutableBluetoothStateSwitchedFlow.value = isChecked mutableBluetoothStateToggle.value = isChecked uiEventLogger.log(BluetoothTileDialogUiEvent.BLUETOOTH_TOGGLE_CLICKED) } } Loading @@ -128,7 +130,32 @@ constructor( internal inner class Adapter(private val onClickCallback: BluetoothTileDialogCallback) : RecyclerView.Adapter<Adapter.DeviceItemViewHolder>() { private val deviceItem: MutableList<DeviceItem> = mutableListOf() private val diffUtilCallback = object : DiffUtil.ItemCallback<DeviceItem>() { override fun areItemsTheSame( deviceItem1: DeviceItem, deviceItem2: DeviceItem ): Boolean { return deviceItem1.cachedBluetoothDevice == deviceItem2.cachedBluetoothDevice } override fun areContentsTheSame( deviceItem1: DeviceItem, deviceItem2: DeviceItem ): Boolean { return deviceItem1.type == deviceItem2.type && deviceItem1.cachedBluetoothDevice == deviceItem2.cachedBluetoothDevice && deviceItem1.deviceName == deviceItem2.deviceName && deviceItem1.connectionSummary == deviceItem2.connectionSummary && // Ignored the icon drawable deviceItem1.iconWithDescription?.second == deviceItem2.iconWithDescription?.second && deviceItem1.background == deviceItem2.background && deviceItem1.isEnabled == deviceItem2.isEnabled } } private val asyncListDiffer = AsyncListDiffer(this, diffUtilCallback) override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DeviceItemViewHolder { val view = Loading @@ -137,29 +164,21 @@ constructor( return DeviceItemViewHolder(view) } override fun getItemCount() = deviceItem.size override fun getItemCount() = asyncListDiffer.currentList.size override fun onBindViewHolder(holder: DeviceItemViewHolder, position: Int) { val item = getItem(position) holder.bind(item, position, onClickCallback) holder.bind(item, onClickCallback) } internal fun getItem(position: Int) = deviceItem[position] internal fun getItem(position: Int) = asyncListDiffer.currentList[position] internal fun refreshDeviceItemList(updated: List<DeviceItem>) { deviceItem.clear() deviceItem.addAll(updated) notifyDataSetChanged() } internal fun refreshDeviceItem(updated: DeviceItem, position: Int) { deviceItem[position] = updated notifyItemChanged(position) asyncListDiffer.submitList(updated) } internal inner class DeviceItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { private val container = view.requireViewById<View>(R.id.bluetooth_device_row) private val deviceView = view.requireViewById<View>(R.id.bluetooth_device) private val nameView = view.requireViewById<TextView>(R.id.bluetooth_device_name) private val summaryView = view.requireViewById<TextView>(R.id.bluetooth_device_summary) private val iconView = view.requireViewById<ImageView>(R.id.bluetooth_device_icon) Loading @@ -167,18 +186,16 @@ constructor( internal fun bind( item: DeviceItem, position: Int, deviceItemOnClickCallback: BluetoothTileDialogCallback ) { container.apply { isEnabled = item.isEnabled alpha = item.alpha background = item.background } deviceView.setOnClickListener { mutableClickedFlow.tryEmit(Pair(item, position)) background = item.background?.let { context.getDrawable(it) } setOnClickListener { mutableDeviceItemClick.tryEmit(item) uiEventLogger.log(BluetoothTileDialogUiEvent.DEVICE_CLICKED) } } nameView.text = item.deviceName summaryView.text = item.connectionSummary iconView.apply { Loading @@ -195,8 +212,6 @@ constructor( } internal companion object { const val ENABLED_ALPHA = 1.0f const val DISABLED_ALPHA = 0.3f const val MAX_DEVICE_ITEM_ENTRY = 3 const val ACTION_BLUETOOTH_DEVICE_DETAILS = "com.android.settings.BLUETOOTH_DEVICE_DETAIL_SETTINGS" Loading