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:
@@ -39,6 +39,7 @@ android_app {
|
||||
static_libs: [
|
||||
"androidx.lifecycle_lifecycle-livedata",
|
||||
"androidx.lifecycle_lifecycle-extensions",
|
||||
"androidx.recyclerview_recyclerview",
|
||||
"androidx.appcompat_appcompat",
|
||||
],
|
||||
|
||||
|
||||
20
packages/CompanionDeviceManager/res/color/selector.xml
Normal file
20
packages/CompanionDeviceManager/res/color/selector.xml
Normal 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>
|
||||
@@ -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" />
|
||||
|
||||
@@ -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. -->
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user