Add BT and WIFI icon for mutiple devices UI
Add BT and WIFI icon for mutiple devices ui.
Also highlight the selected item.
Test: atest CtsCompanionDeviceManagerUiAutomationTestCases:AssociationEndToEndTest
BUG: 211417476
Change-Id: I7edc2ff8734dbe440c803a8d8ab473487f383826
diff --git a/packages/CompanionDeviceManager/Android.bp b/packages/CompanionDeviceManager/Android.bp
index 0e60873..6ded1637 100644
--- a/packages/CompanionDeviceManager/Android.bp
+++ b/packages/CompanionDeviceManager/Android.bp
@@ -39,6 +39,7 @@
static_libs: [
"androidx.lifecycle_lifecycle-livedata",
"androidx.lifecycle_lifecycle-extensions",
+ "androidx.recyclerview_recyclerview",
"androidx.appcompat_appcompat",
],
diff --git a/packages/CompanionDeviceManager/res/color/selector.xml b/packages/CompanionDeviceManager/res/color/selector.xml
new file mode 100644
index 0000000..fda827d
--- /dev/null
+++ b/packages/CompanionDeviceManager/res/color/selector.xml
@@ -0,0 +1,20 @@
+<!--
+ ~ Copyright (C) 2022 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.
+ -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_pressed="true" android:color="@android:color/darker_gray"/> <!-- pressed -->
+ <item android:color="@android:color/white"/>
+</selector>
\ No newline at end of file
diff --git a/packages/CompanionDeviceManager/res/layout/activity_confirmation.xml b/packages/CompanionDeviceManager/res/layout/activity_confirmation.xml
index 313e164..70cbfdf 100644
--- a/packages/CompanionDeviceManager/res/layout/activity_confirmation.xml
+++ b/packages/CompanionDeviceManager/res/layout/activity_confirmation.xml
@@ -49,8 +49,8 @@
android:layout_height="0dp"
android:layout_weight="1">
- <ListView
- android:id="@+id/device_list"
+ <androidx.recyclerview.widget.RecyclerView
+ android:id="@+id/device_list"
style="@android:style/Widget.Material.ListView"
android:layout_width="match_parent"
android:layout_height="200dp" />
diff --git a/packages/CompanionDeviceManager/res/layout/list_item_device.xml b/packages/CompanionDeviceManager/res/layout/list_item_device.xml
index d79aea6..153fc1f 100644
--- a/packages/CompanionDeviceManager/res/layout/list_item_device.xml
+++ b/packages/CompanionDeviceManager/res/layout/list_item_device.xml
@@ -19,7 +19,8 @@
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical"
- android:padding="12dp">
+ android:padding="12dp"
+ android:background="@color/selector">
<!-- Do NOT change the ID of the root LinearLayout above: it's referenced in CTS tests. -->
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java
index 16e851b..b51d310 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java
@@ -46,10 +46,11 @@
import android.util.Log;
import android.view.View;
import android.widget.Button;
-import android.widget.ListView;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
@@ -94,9 +95,9 @@
// regular.
private Button mButtonAllow;
- // The list is only shown for multiple-device regular association request, after at least one
- // matching device is found.
- private @Nullable ListView mListView;
+ // The recycler view is only shown for multiple-device regular association request, after
+ // at least one matching device is found.
+ private @Nullable RecyclerView mRecyclerView;
private @Nullable DeviceListAdapter mAdapter;
// The flag used to prevent double taps, that may lead to sending several requests for creating
@@ -195,14 +196,15 @@
mTitle = findViewById(R.id.title);
mSummary = findViewById(R.id.summary);
- mListView = findViewById(R.id.device_list);
- mListView.setOnItemClickListener((av, iv, position, id) -> onListItemClick(position));
+ mRecyclerView = findViewById(R.id.device_list);
+ mAdapter = new DeviceListAdapter(this, this::onListItemClick);
mButtonAllow = findViewById(R.id.btn_positive);
mButtonAllow.setOnClickListener(this::onPositiveButtonClick);
findViewById(R.id.btn_negative).setOnClickListener(this::onNegativeButtonClick);
final CharSequence appLabel = getApplicationLabel(this, mRequest.getPackageName());
+
if (mRequest.isSelfManaged()) {
initUiForSelfManagedAssociation(appLabel);
} else if (mRequest.isSingleDevice()) {
@@ -333,7 +335,7 @@
mTitle.setText(title);
mSummary.setText(summary);
- mListView.setVisibility(View.GONE);
+ mRecyclerView.setVisibility(View.GONE);
}
private void initUiForSingleDevice(CharSequence appLabel) {
@@ -345,12 +347,12 @@
deviceFilterPairs -> updateSingleDeviceUi(
deviceFilterPairs, deviceProfile, appLabel));
- mListView.setVisibility(View.GONE);
+ mRecyclerView.setVisibility(View.GONE);
}
private void updateSingleDeviceUi(List<DeviceFilterPair<?>> deviceFilterPairs,
String deviceProfile, CharSequence appLabel) {
- // Ignore "empty" scan repots.
+ // Ignore "empty" scan reports.
if (deviceFilterPairs.isEmpty()) return;
mSelectedDevice = requireNonNull(deviceFilterPairs.get(0));
@@ -393,10 +395,12 @@
mTitle.setText(title);
mSummary.setText(summary);
- mAdapter = new DeviceListAdapter(this);
+ mAdapter = new DeviceListAdapter(this, this::onListItemClick);
// TODO: hide the list and show a spinner until a first device matching device is found.
- mListView.setAdapter(mAdapter);
+ mRecyclerView.setAdapter(mAdapter);
+ mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
+
CompanionDeviceDiscoveryService.getScanResult().observe(
/* lifecycleOwner */ this,
/* observer */ mAdapter);
@@ -414,6 +418,8 @@
if (DEBUG) Log.w(TAG, "Already selected.");
return;
}
+ // Notify the adapter to highlight the selected item.
+ mAdapter.setSelectedPosition(position);
mSelectedDevice = requireNonNull(selectedDevice);
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceListAdapter.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceListAdapter.java
index 198b778..e5513b0 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceListAdapter.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceListAdapter.java
@@ -15,73 +15,84 @@
*/
package com.android.companiondevicemanager;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.content.Context;
+import android.graphics.Color;
+import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.lifecycle.Observer;
+import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
-
/**
* Adapter for the list of "found" devices.
*/
-class DeviceListAdapter extends BaseAdapter implements Observer<List<DeviceFilterPair<?>>> {
+class DeviceListAdapter extends RecyclerView.Adapter<DeviceListAdapter.ViewHolder> implements
+ Observer<List<DeviceFilterPair<?>>> {
+ public int mSelectedPosition = RecyclerView.NO_POSITION;
+
private final Context mContext;
// List if pairs (display name, address)
private List<DeviceFilterPair<?>> mDevices;
- DeviceListAdapter(Context context) {
+ private OnItemClickListener mListener;
+
+ private static final int TYPE_WIFI = 0;
+ private static final int TYPE_BT = 1;
+
+ DeviceListAdapter(Context context, OnItemClickListener listener) {
mContext = context;
+ mListener = listener;
}
- @Override
- public int getCount() {
- return mDevices != null ? mDevices.size() : 0;
- }
-
- @Override
public DeviceFilterPair<?> getItem(int position) {
return mDevices.get(position);
}
@Override
+ public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ View view = LayoutInflater.from(parent.getContext()).inflate(
+ R.layout.list_item_device, parent, false);
+ ViewHolder viewHolder = new ViewHolder(view);
+ if (viewType == TYPE_WIFI) {
+ viewHolder.mImageView.setImageDrawable(getIcon(
+ com.android.internal.R.drawable.ic_wifi_signal_3));
+ } else {
+ viewHolder.mImageView.setImageDrawable(getIcon(
+ android.R.drawable.stat_sys_data_bluetooth));
+ }
+ return viewHolder;
+ }
+
+ @Override
+ public void onBindViewHolder(ViewHolder holder, int position) {
+ holder.itemView.setSelected(mSelectedPosition == position);
+ holder.mTextView.setText(mDevices.get(position).getDisplayName());
+ holder.itemView.setOnClickListener(v -> mListener.onItemClick(position));
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ return isWifiDevice(position) ? TYPE_WIFI : TYPE_BT;
+ }
+
+ @Override
public long getItemId(int position) {
return position;
}
@Override
- public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
- final View view = convertView != null
- ? convertView
- : LayoutInflater.from(mContext).inflate(R.layout.list_item_device, parent, false);
-
- final DeviceFilterPair<?> item = getItem(position);
- bindView(view, item);
-
- return view;
+ public int getItemCount() {
+ return mDevices != null ? mDevices.size() : 0;
}
- private void bindView(@NonNull View view, DeviceFilterPair<?> item) {
- final TextView textView = view.findViewById(android.R.id.text1);
- textView.setText(item.getDisplayName());
-
- final ImageView iconView = view.findViewById(android.R.id.icon);
-
- // TODO(b/211417476): Set either Bluetooth or WiFi icon.
- iconView.setVisibility(View.GONE);
- // final int iconRes = isBt ? android.R.drawable.stat_sys_data_bluetooth
- // : com.android.internal.R.drawable.ic_wifi_signal_3;
- // final Drawable icon = getTintedIcon(mResources, iconRes);
- // iconView.setImageDrawable(icon);
+ public void setSelectedPosition(int position) {
+ mSelectedPosition = position;
}
@Override
@@ -89,4 +100,28 @@
mDevices = deviceFilterPairs;
notifyDataSetChanged();
}
+
+ static class ViewHolder extends RecyclerView.ViewHolder {
+ private TextView mTextView;
+ private ImageView mImageView;
+ ViewHolder(View itemView) {
+ super(itemView);
+ mTextView = itemView.findViewById(android.R.id.text1);
+ mImageView = itemView.findViewById(android.R.id.icon);
+ }
+ }
+
+ private boolean isWifiDevice(int position) {
+ return mDevices.get(position).getDevice() instanceof android.net.wifi.ScanResult;
+ }
+
+ private Drawable getIcon(int resId) {
+ Drawable icon = mContext.getResources().getDrawable(resId, null);
+ icon.setTint(Color.DKGRAY);
+ return icon;
+ }
+
+ public interface OnItemClickListener {
+ void onItemClick(int position);
+ }
}