diff --git a/packages/CompanionDeviceManager/Android.bp b/packages/CompanionDeviceManager/Android.bp
index 0e6087376d117..6ded16371e8a5 100644
--- a/packages/CompanionDeviceManager/Android.bp
+++ b/packages/CompanionDeviceManager/Android.bp
@@ -39,6 +39,7 @@ android_app {
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 0000000000000..fda827d7f9c8a
--- /dev/null
+++ b/packages/CompanionDeviceManager/res/color/selector.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
\ 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 313e164cdbef5..70cbfdf5cefc0 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">
-
diff --git a/packages/CompanionDeviceManager/res/layout/list_item_device.xml b/packages/CompanionDeviceManager/res/layout/list_item_device.xml
index d79aea6fae6bc..153fc1f35abe3 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">
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java
index 16e851be4362c..b51d3103caec8 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.text.Spanned;
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 @@ public class CompanionDeviceActivity extends AppCompatActivity {
// 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 @@ public class CompanionDeviceActivity extends AppCompatActivity {
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 @@ public class CompanionDeviceActivity extends AppCompatActivity {
mTitle.setText(title);
mSummary.setText(summary);
- mListView.setVisibility(View.GONE);
+ mRecyclerView.setVisibility(View.GONE);
}
private void initUiForSingleDevice(CharSequence appLabel) {
@@ -345,12 +347,12 @@ public class CompanionDeviceActivity extends AppCompatActivity {
deviceFilterPairs -> updateSingleDeviceUi(
deviceFilterPairs, deviceProfile, appLabel));
- mListView.setVisibility(View.GONE);
+ mRecyclerView.setVisibility(View.GONE);
}
private void updateSingleDeviceUi(List> 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 @@ public class CompanionDeviceActivity extends AppCompatActivity {
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 @@ public class CompanionDeviceActivity extends AppCompatActivity {
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 198b7780e2b87..e5513b0748651 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>> {
+class DeviceListAdapter extends RecyclerView.Adapter implements
+ Observer>> {
+ public int mSelectedPosition = RecyclerView.NO_POSITION;
+
private final Context mContext;
// List if pairs (display name, address)
private List> 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 @@ class DeviceListAdapter extends BaseAdapter implements Observer