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
This commit is contained in:
Evan Chen
2022-01-06 18:04:57 +00:00
parent 99deef06b1
commit 557a8bd2b5
6 changed files with 111 additions and 48 deletions

View File

@@ -39,6 +39,7 @@ android_app {
static_libs: [
"androidx.lifecycle_lifecycle-livedata",
"androidx.lifecycle_lifecycle-extensions",
"androidx.recyclerview_recyclerview",
"androidx.appcompat_appcompat",
],

View File

@@ -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>

View File

@@ -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" />

View File

@@ -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. -->

View File

@@ -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<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 @@ 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);

View File

@@ -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 @@ class DeviceListAdapter extends BaseAdapter implements Observer<List<DeviceFilte
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);
}
}