Update AlertDialogs UI
Fix: 147614686
Fix: 147615554
Test: Manual
Change-Id: I600220e2ac723ea98012cdb39e26e5a8590f2e7d
(cherry picked from commit cb0a7a8300a7b5ef4d7ce2300787c9755fe50ee4)
diff --git a/res/color/icon_accent_activatable.xml b/res/color/icon_accent_activatable.xml
index cf4b9e7..c652f07 100644
--- a/res/color/icon_accent_activatable.xml
+++ b/res/color/icon_accent_activatable.xml
@@ -16,6 +16,6 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/primary_icon_color"
android:state_activated="false"/>
- <item android:color="?android:colorAccent"
+ <item android:color="@color/audio_output_accent"
android:state_activated="true"/>
</selector>
diff --git a/res/color/text_accent_activatable.xml b/res/color/text_accent_activatable.xml
deleted file mode 100644
index 4f1dc0f..0000000
--- a/res/color/text_accent_activatable.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version='1.0' encoding='UTF-8'?>
-<!-- Copyright (C) 2019 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:color="@color/primary_text_color"
- android:state_activated="false"/>
- <item android:color="?android:colorAccent"
- android:state_activated="true"/>
-</selector>
diff --git a/res/layout/add_favorite_number_list_item.xml b/res/layout/add_favorite_number_list_item.xml
deleted file mode 100644
index ffe5445..0000000
--- a/res/layout/add_favorite_number_list_item.xml
+++ /dev/null
@@ -1,60 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2019 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.
--->
-
-<androidx.constraintlayout.widget.ConstraintLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:layout_width="match_parent"
- android:layout_height="@dimen/add_favorite_number_list_height"
- android:background="?android:attr/selectableItemBackground"
- android:paddingStart="@dimen/add_favorite_number_list_padding"
- android:paddingEnd="@dimen/add_favorite_number_list_padding">
-
- <TextView
- android:id="@+id/phone_number"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:textAppearance="@style/TextAppearance.AddFavoriteNumberTitle"
- android:duplicateParentState="true"
- app:layout_constraintVertical_chainStyle="packed"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toTopOf="@+id/phone_number_description"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toStartOf="@+id/phone_number_checkbox"/>
-
- <TextView
- android:id="@+id/phone_number_description"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:textAppearance="@style/TextAppearance.AddFavoriteNumberSubtitle"
- android:duplicateParentState="true"
- app:layout_constraintTop_toBottomOf="@id/phone_number"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toStartOf="@id/phone_number_checkbox"/>
-
- <ImageView
- android:id="@+id/phone_number_checkbox"
- android:src="@drawable/ic_favorite_activatable"
- android:layout_width="@dimen/primary_icon_size"
- android:layout_height="@dimen/primary_icon_size"
- android:tint="@color/primary_icon_selector"
- android:duplicateParentState="true"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintEnd_toEndOf="parent"/>
-
-</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/res/layout/audio_route_list_item.xml b/res/layout/audio_route_list_item.xml
deleted file mode 100644
index c1510ef..0000000
--- a/res/layout/audio_route_list_item.xml
+++ /dev/null
@@ -1,49 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 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.
--->
-<androidx.constraintlayout.widget.ConstraintLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:layout_width="match_parent"
- android:layout_height="@dimen/audio_route_height"
- android:background="?android:attr/selectableItemBackground"
- android:elevation="@dimen/dialer_card_elevation">
- <androidx.constraintlayout.widget.Guideline
- android:id="@+id/text_start"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- app:layout_constraintGuide_begin="@dimen/audio_route_constraint_guide_begin"/>
- <ImageView
- android:id="@+id/icon"
- android:layout_width="@dimen/audio_route_icon_size"
- android:layout_height="@dimen/audio_route_icon_size"
- android:scaleType="fitCenter"
- android:layout_marginStart="@dimen/audio_route_content_padding"
- android:tint="@color/icon_accent_activatable"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toTopOf="parent"/>
- <TextView
- android:id="@+id/body"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:textAppearance="?android:attr/textAppearanceLarge"
- android:textColor="@color/text_accent_activatable"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintStart_toStartOf="@+id/text_start"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintTop_toTopOf="parent"/>
-</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/res/layout/audio_route_switch_dialog.xml b/res/layout/audio_route_switch_dialog.xml
deleted file mode 100644
index 7a5013c..0000000
--- a/res/layout/audio_route_switch_dialog.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 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.
--->
-<androidx.recyclerview.widget.RecyclerView
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/list"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:clipChildren="false"/>
diff --git a/res/layout/phone_number_list_item.xml b/res/layout/phone_number_list_item.xml
deleted file mode 100644
index 04e1b61..0000000
--- a/res/layout/phone_number_list_item.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 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.
--->
-<com.android.car.dialer.widget.CheckableRelativeLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingStart="?android:listPreferredItemPaddingStart"
- android:paddingEnd="?android:listPreferredItemPaddingEnd">
-
- <RadioButton
- android:id="@+id/phone_number_checkbox"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_centerVertical="true"
- android:layout_marginEnd="@dimen/phone_number_radio_list_padding"/>
- <TextView
- android:id="@+id/phone_number"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_toEndOf="@id/phone_number_checkbox"
- android:textAppearance="?android:attr/textAppearanceMedium"/>
- <TextView
- android:id="@+id/phone_number_description"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_below="@id/phone_number"
- android:layout_toEndOf="@id/phone_number_checkbox"
- android:textAppearance="?android:attr/textAppearanceSmall"/>
-
-</com.android.car.dialer.widget.CheckableRelativeLayout>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 5f6707d..49d2e52 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -18,6 +18,7 @@
<color name="phone_call">@*android:color/car_green_700</color>
<color name="phone_end_call">@*android:color/car_red_500a</color>
<color name="onhold_call_background">@*android:color/car_grey_868</color>
+ <color name="audio_output_accent">@*android:color/car_accent</color>
<!-- Dialpad page -->
<color name="call_button_outline">@*android:color/car_green_500</color>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 010fca4..edc9bc3 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -17,13 +17,10 @@
<!-- Dialer -->
<dimen name="dialer_card_elevation">2dp</dimen>
- <!-- Audio route dimentions -->
- <dimen name="audio_route_height">@dimen/control_bar_height</dimen>
- <dimen name="audio_route_content_padding">@dimen/list_item_padding</dimen>
- <dimen name="audio_route_icon_size">@dimen/primary_icon_size</dimen>
+ <!-- TODO: UNUSED! REMOVE THIS. b/149125789-->
<dimen name="audio_route_constraint_guide_begin">@dimen/list_item_guideline</dimen>
- <!-- Call list dimentions -->
+ <!-- Call list dimensions -->
<dimen name="call_history_item_height">@dimen/list_item_height</dimen>
<dimen name="call_history_item_padding">@dimen/list_item_padding</dimen>
<dimen name="call_history_guideline_begin">@dimen/list_item_guideline_begin</dimen>
@@ -99,10 +96,6 @@
<dimen name="favorite_card_space_vertical">@*android:dimen/car_padding_2</dimen>
<dimen name="favorites_avatar_margin_bottom">@*android:dimen/car_padding_3</dimen>
- <!-- Add faovirte flow dimensions -->
- <dimen name="add_favorite_number_list_height">@dimen/list_item_height</dimen>
- <dimen name="add_favorite_number_list_padding">@dimen/list_item_padding</dimen>
-
<dimen name="call_fab_elevation">8dp</dimen>
<dimen name="bksp_button_width">@dimen/touch_target_size</dimen>
@@ -145,7 +138,6 @@
<dimen name="touch_target_width">156dp</dimen>
<dimen name="subheader_list_height">76dp</dimen>
<dimen name="control_bar_height">96dp</dimen>
- <dimen name="phone_number_radio_list_padding">@*android:dimen/car_padding_2</dimen>
<!-- Loading status view dimensions -->
<dimen name="loading_info_icon_size">56dp</dimen>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 490b564..a890cd1 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -205,4 +205,8 @@
<string name="given_name_first_title">First name</string>
<!-- Title of family name [CHAR LIMIT=40]-->
<string name="family_name_first_title">Last name</string>
+
+ <!-- Audio route selection dialog. Placeholder resources for overriding -->
+ <string name="audio_route_dialog_title">Output call audio to:</string>
+ <string name="audio_route_dialog_subtitle"></string>
</resources>
diff --git a/src/com/android/car/dialer/ui/activecall/OnGoingCallControllerBarFragment.java b/src/com/android/car/dialer/ui/activecall/OnGoingCallControllerBarFragment.java
index ad01d06..bae306b 100644
--- a/src/com/android/car/dialer/ui/activecall/OnGoingCallControllerBarFragment.java
+++ b/src/com/android/car/dialer/ui/activecall/OnGoingCallControllerBarFragment.java
@@ -17,11 +17,13 @@
package com.android.car.dialer.ui.activecall;
import android.app.AlertDialog;
-import android.content.Context;
+import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.telecom.Call;
import android.telecom.CallAudioState;
import android.telecom.CallAudioState.CallAudioRoute;
+import android.text.SpannableString;
+import android.text.style.ForegroundColorSpan;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -36,16 +38,19 @@
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModelProviders;
-import androidx.recyclerview.widget.LinearLayoutManager;
-import androidx.recyclerview.widget.RecyclerView;
import com.android.car.apps.common.util.ViewUtils;
import com.android.car.dialer.R;
import com.android.car.dialer.log.L;
import com.android.car.dialer.telecom.UiCallManager;
+import com.android.car.ui.AlertDialogBuilder;
+import com.android.car.ui.recyclerview.CarUiContentListItem;
+import com.android.car.ui.recyclerview.CarUiListItem;
+import com.android.car.ui.recyclerview.CarUiListItemAdapter;
import com.google.common.collect.ImmutableMap;
+import java.util.ArrayList;
import java.util.List;
/** A Fragment of the bar which controls on going call. */
@@ -73,7 +78,6 @@
.build();
private AlertDialog mAudioRouteSelectionDialog;
- private AudioRouteListAdapter mAudioRouteAdapter;
private View mMuteButton;
private View mAudioRouteView;
private ImageView mAudioRouteButton;
@@ -83,24 +87,65 @@
private MutableLiveData<Boolean> mDialpadState;
private LiveData<List<Call>> mCallListLiveData;
private int mPrimaryCallState;
+ private int mActiveRoute;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- View dialogView = LayoutInflater.from(getContext()).inflate(
- R.layout.audio_route_switch_dialog, null, false);
- RecyclerView list = dialogView.findViewById(R.id.list);
- list.setLayoutManager(new LinearLayoutManager(getContext()));
-
- mAudioRouteSelectionDialog = new AlertDialog.Builder(getContext())
- .setView(dialogView)
- .create();
-
List<Integer> availableRoutes = UiCallManager.get().getSupportedAudioRoute();
- int activeRoute = UiCallManager.get().getAudioRoute();
- mAudioRouteAdapter = new AudioRouteListAdapter(getContext(), availableRoutes, activeRoute);
- list.setAdapter(mAudioRouteAdapter);
+ mActiveRoute = UiCallManager.get().getAudioRoute();
+
+ if (availableRoutes.contains(CallAudioState.ROUTE_EARPIECE)
+ && availableRoutes.contains(CallAudioState.ROUTE_WIRED_HEADSET)) {
+ // Keep either ROUTE_EARPIECE or ROUTE_WIRED_HEADSET, but not both of them.
+ availableRoutes.remove(CallAudioState.ROUTE_WIRED_HEADSET);
+ }
+
+ List<CarUiListItem> listItems = new ArrayList<>();
+ CarUiListItemAdapter adapter = new CarUiListItemAdapter(listItems);
+
+ for (Integer audioRoute : availableRoutes) {
+ CarUiContentListItem item = new CarUiContentListItem(CarUiContentListItem.Action.NONE);
+ AudioRouteInfo routeInfo = getAudioRouteInfo(audioRoute);
+ Drawable drawable = getResources().getDrawable(routeInfo.mIcon, null);
+ drawable.setTintList(
+ getResources().getColorStateList(R.color.icon_accent_activatable, null));
+ item.setIcon(drawable);
+ item.setOnItemClickedListener((i) -> {
+ onSetAudioRoute(audioRoute);
+ // Reset the spannable titles for each item
+ for (CarUiListItem listItem : listItems) {
+ CarUiContentListItem contentItem = (CarUiContentListItem) listItem;
+ CharSequence title = contentItem.getTitle();
+ contentItem.setTitle(title.toString());
+ contentItem.setActivated(false);
+ }
+ i.setActivated(true);
+ // Set the spannable title for clicked item
+ String routeTitle = getString(routeInfo.mLabel);
+ item.setTitle(mActiveRoute == audioRoute
+ ? withAccentColor(routeTitle)
+ : routeTitle);
+ adapter.notifyDataSetChanged();
+ });
+ String routeTitle = getString(routeInfo.mLabel);
+
+ item.setTitle(mActiveRoute == audioRoute ? withAccentColor(routeTitle) : routeTitle);
+ item.setActivated(mActiveRoute == audioRoute);
+ listItems.add(item);
+ }
+
+ AlertDialogBuilder audioRouteSelectionDialogBuilder = new AlertDialogBuilder(getContext())
+ .setAdapter(adapter)
+ .setTitle(getString(R.string.audio_route_dialog_title));
+
+ String subtitle = getString(R.string.audio_route_dialog_subtitle);
+ if (!subtitle.isEmpty()) {
+ audioRouteSelectionDialogBuilder.setSubtitle(subtitle);
+ }
+
+ mAudioRouteSelectionDialog = audioRouteSelectionDialogBuilder.create();
InCallViewModel inCallViewModel = ViewModelProviders.of(getActivity()).get(
InCallViewModel.class);
@@ -147,7 +192,6 @@
if (audioRoutes.size() > 1) {
mAudioRouteView.setOnClickListener((v) -> {
mAudioRouteView.setActivated(true);
- mAudioRouteAdapter.setActiveAudioRoute(UiCallManager.get().getAudioRoute());
mAudioRouteSelectionDialog.show();
});
}
@@ -179,6 +223,14 @@
}
}
+ private CharSequence withAccentColor(String routeTitle) {
+ ForegroundColorSpan activeRouteSpan = new ForegroundColorSpan(
+ getResources().getColor(R.color.audio_output_accent, null));
+ SpannableString spannableTitle = new SpannableString(routeTitle);
+ spannableTitle.setSpan(activeRouteSpan, 0, routeTitle.length(), 0);
+ return spannableTitle;
+ }
+
/** Set the call state and change the view for the pause button accordingly */
private void setCallState(int callState) {
L.d(TAG, "Call State: %s", callState);
@@ -224,17 +276,16 @@
private void onSetAudioRoute(@CallAudioRoute int audioRoute) {
UiCallManager.get().setAudioRoute(audioRoute);
+ mActiveRoute = audioRoute;
mAudioRouteSelectionDialog.dismiss();
}
private void updateViewBasedOnAudioRoute(@Nullable Integer audioRoute) {
if (audioRoute == null) {
- mAudioRouteAdapter.setActiveAudioRoute(0);
return;
}
L.i(TAG, "Audio Route State: " + audioRoute);
- mAudioRouteAdapter.setActiveAudioRoute(audioRoute.intValue());
AudioRouteInfo audioRouteInfo = getAudioRouteInfo(audioRoute);
if (mAudioRouteButton != null) {
@@ -277,64 +328,4 @@
mIconActivatable = iconActivatable;
}
}
-
- private class AudioRouteListAdapter extends
- RecyclerView.Adapter<AudioRouteItemViewHolder> {
- private List<Integer> mSupportedRoutes;
- private Context mContext;
- private int mActiveAudioRoute;
-
- AudioRouteListAdapter(Context context,
- List<Integer> supportedRoutes,
- int activeAudioRoute) {
- mSupportedRoutes = supportedRoutes;
- mActiveAudioRoute = activeAudioRoute;
- mContext = context;
- if (mSupportedRoutes.contains(CallAudioState.ROUTE_EARPIECE)
- && mSupportedRoutes.contains(CallAudioState.ROUTE_WIRED_HEADSET)) {
- // Keep either ROUTE_EARPIECE or ROUTE_WIRED_HEADSET, but not both of them.
- mSupportedRoutes.remove(CallAudioState.ROUTE_WIRED_HEADSET);
- }
- }
-
- public void setActiveAudioRoute(int route) {
- if (mActiveAudioRoute != route) {
- mActiveAudioRoute = route;
- notifyDataSetChanged();
- }
- }
-
- @Override
- public AudioRouteItemViewHolder onCreateViewHolder(ViewGroup container, int position) {
- View listItemView = LayoutInflater.from(mContext).inflate(
- R.layout.audio_route_list_item, container, false);
- return new AudioRouteItemViewHolder(listItemView);
- }
-
- @Override
- public void onBindViewHolder(AudioRouteItemViewHolder viewHolder, int position) {
- int audioRoute = mSupportedRoutes.get(position);
- AudioRouteInfo routeInfo = getAudioRouteInfo(audioRoute);
- viewHolder.mBody.setText(routeInfo.mLabel);
- viewHolder.mIcon.setImageResource(routeInfo.mIcon);
- viewHolder.itemView.setActivated(audioRoute == mActiveAudioRoute);
- viewHolder.itemView.setOnClickListener((v) -> onSetAudioRoute(audioRoute));
- }
-
- @Override
- public int getItemCount() {
- return mSupportedRoutes.size();
- }
- }
-
- private static class AudioRouteItemViewHolder extends RecyclerView.ViewHolder {
- public final ImageView mIcon;
- public final TextView mBody;
-
- public AudioRouteItemViewHolder(View itemView) {
- super(itemView);
- mIcon = itemView.findViewById(R.id.icon);
- mBody = itemView.findViewById(R.id.body);
- }
- }
}
diff --git a/src/com/android/car/dialer/ui/common/DialerUtils.java b/src/com/android/car/dialer/ui/common/DialerUtils.java
index 01e6931..5826e42 100644
--- a/src/com/android/car/dialer/ui/common/DialerUtils.java
+++ b/src/com/android/car/dialer/ui/common/DialerUtils.java
@@ -28,6 +28,8 @@
import com.android.car.telephony.common.PhoneNumber;
import com.android.car.telephony.common.TelecomUtils;
import com.android.car.ui.AlertDialogBuilder;
+import com.android.car.ui.recyclerview.CarUiRadioButtonListItem;
+import com.android.car.ui.recyclerview.CarUiRadioButtonListItemAdapter;
import java.util.ArrayList;
import java.util.List;
@@ -45,8 +47,9 @@
public interface PhoneNumberSelectionCallback {
/**
* Called when a phone number is chosen.
+ *
* @param phoneNumber The phone number
- * @param always Whether the user pressed "aways" or "just once"
+ * @param always Whether the user pressed "aways" or "just once"
*/
void onPhoneNumberSelected(PhoneNumber phoneNumber, boolean always);
}
@@ -58,16 +61,28 @@
public static void showPhoneNumberSelector(Context context,
List<PhoneNumber> numbers,
PhoneNumberSelectionCallback callback) {
+
final List<PhoneNumber> selectedPhoneNumber = new ArrayList<>();
+ List<CarUiRadioButtonListItem> items = new ArrayList<>();
+ CarUiRadioButtonListItemAdapter adapter = new CarUiRadioButtonListItemAdapter(items);
+
+ for (PhoneNumber number : numbers) {
+ CharSequence readableLabel = number.getReadableLabel(context.getResources());
+ CarUiRadioButtonListItem item = new CarUiRadioButtonListItem();
+ item.setTitle(number.isPrimary()
+ ? context.getString(R.string.primary_number_description, readableLabel)
+ : readableLabel);
+ item.setBody(number.getNumber());
+ item.setOnCheckedChangeListener((i, isChecked) -> {
+ selectedPhoneNumber.clear();
+ selectedPhoneNumber.add(number);
+ });
+ items.add(item);
+ }
+
new AlertDialogBuilder(context)
.setTitle(R.string.select_number_dialog_title)
- .setSingleChoiceItems(
- new PhoneNumberListAdapter(context, numbers),
- -1,
- ((dialog, which) -> {
- selectedPhoneNumber.clear();
- selectedPhoneNumber.add(numbers.get(which));
- }))
+ .setSingleChoiceItems(adapter, null)
.setNeutralButton(R.string.select_number_dialog_just_once_button,
(dialog, which) -> {
if (!selectedPhoneNumber.isEmpty()) {
diff --git a/src/com/android/car/dialer/ui/common/FavoritePhoneNumberListAdapter.java b/src/com/android/car/dialer/ui/common/FavoritePhoneNumberListAdapter.java
deleted file mode 100644
index 9e7c652..0000000
--- a/src/com/android/car/dialer/ui/common/FavoritePhoneNumberListAdapter.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- */
-
-package com.android.car.dialer.ui.common;
-
-import android.content.Context;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.BaseAdapter;
-import android.widget.TextView;
-
-import com.android.car.dialer.R;
-import com.android.car.telephony.common.Contact;
-import com.android.car.telephony.common.PhoneNumber;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * {@link BaseAdapter} that presents the {@link PhoneNumber} and its type as two line list item with
- * stars to indicate favorite state or user selection to add to favorite. Currently favorite phone
- * number is set to disabled so user can not take any action for an existing favorite phone number.
- */
-public class FavoritePhoneNumberListAdapter extends BaseAdapter {
- private final Context mContext;
- private final FavoritePhoneNumberPresenter mFavoritePhoneNumberPresenter;
- private final List<PhoneNumber> mPhoneNumbers;
- private Contact mContact;
-
- /**
- * A presenter that presents the favorite state for phone number and provides the click
- * listener.
- */
- public interface FavoritePhoneNumberPresenter {
- /**
- * Provides the click listener for the given phone number and its present view.
- */
- void onItemClicked(PhoneNumber phoneNumber, View itemView);
- }
-
- public FavoritePhoneNumberListAdapter(Context context,
- FavoritePhoneNumberPresenter favoritePhoneNumberPresenter) {
- mContext = context;
- mFavoritePhoneNumberPresenter = favoritePhoneNumberPresenter;
- mPhoneNumbers = new ArrayList<>();
- }
-
- /**
- * Sets the phone numbers to display
- */
- public void setPhoneNumbers(Contact contact, List<PhoneNumber> phoneNumbers) {
- mPhoneNumbers.clear();
- mContact = contact;
- mPhoneNumbers.addAll(phoneNumbers);
-
- notifyDataSetChanged();
- }
-
- public Contact getContact() {
- return mContact;
- }
-
- @Override
- public int getCount() {
- return mPhoneNumbers.size();
- }
-
- @Override
- public PhoneNumber getItem(int position) {
- return mPhoneNumbers.get(position);
- }
-
- @Override
- public long getItemId(int position) {
- return position;
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- View itemView;
- if (convertView == null) {
- itemView = LayoutInflater.from(mContext).inflate(
- R.layout.add_favorite_number_list_item, parent, false);
- } else {
- itemView = convertView;
- }
- PhoneNumber phoneNumber = getItem(position);
- bind(phoneNumber, itemView);
- return itemView;
- }
-
- void bind(PhoneNumber phoneNumber, View itemView) {
- TextView phoneNumberView = itemView.findViewById(R.id.phone_number);
- TextView phoneNumberDescriptionView = itemView.findViewById(R.id.phone_number_description);
- phoneNumberView.setText(phoneNumber.getRawNumber());
- CharSequence readableLabel = phoneNumber.getReadableLabel(itemView.getResources());
-
- if (phoneNumber.isFavorite()) {
- // This phone number is marked as favorite locally. Disable the favorite action button.
- phoneNumberDescriptionView.setText(
- itemView.getResources().getString(R.string.local_favorite_number_description,
- readableLabel));
- itemView.setActivated(true);
- itemView.setEnabled(false);
- } else if (mContact.isStarred()) {
- // This contact is downloaded from phone, all phone numbers under this contact will show
- // under the favorite tab. Disable the favorite action button.
- phoneNumberDescriptionView.setText(
- itemView.getResources().getString(R.string.favorite_number_description,
- readableLabel));
- itemView.setActivated(false);
- itemView.setEnabled(false);
- } else {
- phoneNumberDescriptionView.setText(readableLabel);
- itemView.setActivated(false);
- itemView.setEnabled(true);
- itemView.setOnClickListener(
- view -> mFavoritePhoneNumberPresenter.onItemClicked(phoneNumber, itemView));
- }
- }
-}
diff --git a/src/com/android/car/dialer/ui/common/PhoneNumberListAdapter.java b/src/com/android/car/dialer/ui/common/PhoneNumberListAdapter.java
deleted file mode 100644
index 923fb51..0000000
--- a/src/com/android/car/dialer/ui/common/PhoneNumberListAdapter.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- */
-
-package com.android.car.dialer.ui.common;
-
-import android.content.Context;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ArrayAdapter;
-import android.widget.TextView;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import com.android.car.dialer.R;
-import com.android.car.telephony.common.PhoneNumber;
-
-import java.util.List;
-
-/**
- * {@link ArrayAdapter} that simply presents the {@link PhoneNumber} and its type as two line list
- * item.
- */
-public class PhoneNumberListAdapter extends ArrayAdapter<PhoneNumber> {
- private final Context mContext;
-
- public PhoneNumberListAdapter(Context context, List<PhoneNumber> phoneNumbers) {
- super(context, R.layout.phone_number_list_item, R.id.phone_number, phoneNumbers);
- mContext = context;
- }
-
- @Override
- public View getView(int position, @Nullable View convertView,
- @NonNull ViewGroup parent) {
- View view = super.getView(position, convertView, parent);
- PhoneNumber phoneNumber = getItem(position);
- if (phoneNumber == null) {
- return view;
- }
- TextView phoneNumberView = view.findViewById(R.id.phone_number);
- phoneNumberView.setText(phoneNumber.getRawNumber());
- TextView phoneNumberDescriptionView = view.findViewById(R.id.phone_number_description);
- CharSequence readableLabel = phoneNumber.getReadableLabel(mContext.getResources());
- if (phoneNumber.isPrimary()) {
- phoneNumberDescriptionView.setText(
- mContext.getString(R.string.primary_number_description, readableLabel));
- } else {
- phoneNumberDescriptionView.setText(readableLabel);
- }
- return view;
- }
-}
diff --git a/src/com/android/car/dialer/ui/favorite/AddFavoriteFragment.java b/src/com/android/car/dialer/ui/favorite/AddFavoriteFragment.java
index 6ddbad7..a45d5bc 100644
--- a/src/com/android/car/dialer/ui/favorite/AddFavoriteFragment.java
+++ b/src/com/android/car/dialer/ui/favorite/AddFavoriteFragment.java
@@ -17,19 +17,24 @@
package com.android.car.dialer.ui.favorite;
import android.app.AlertDialog;
+import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.widget.Toast;
import androidx.lifecycle.ViewModelProviders;
import com.android.car.dialer.R;
-import com.android.car.dialer.ui.common.FavoritePhoneNumberListAdapter;
import com.android.car.dialer.ui.search.ContactResultsFragment;
import com.android.car.telephony.common.Contact;
import com.android.car.telephony.common.PhoneNumber;
import com.android.car.ui.AlertDialogBuilder;
+import com.android.car.ui.recyclerview.CarUiContentListItem;
+import com.android.car.ui.recyclerview.CarUiListItem;
+import com.android.car.ui.recyclerview.CarUiListItemAdapter;
+import java.util.ArrayList;
import java.util.HashSet;
+import java.util.List;
import java.util.Set;
/**
@@ -45,7 +50,12 @@
}
private AlertDialog mCurrentDialog;
- private FavoritePhoneNumberListAdapter mDialogAdapter;
+ private CarUiListItemAdapter mDialogAdapter;
+ private List<CarUiListItem> mFavoritePhoneNumberList;
+ private Set<PhoneNumber> mSelectedNumbers;
+ private Contact mSelectedContact;
+ private Drawable mFavoriteIcon;
+ private Drawable mFavoriteIconEmpty;
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -53,36 +63,77 @@
FavoriteViewModel favoriteViewModel = ViewModelProviders.of(getActivity()).get(
FavoriteViewModel.class);
- Set<PhoneNumber> selectedNumbers = new HashSet<>();
+ mSelectedNumbers = new HashSet<>();
- mDialogAdapter = new FavoritePhoneNumberListAdapter(getContext(),
- (phoneNumber, itemView) -> {
- boolean isActivated = itemView.isActivated();
- itemView.setActivated(!isActivated);
- if (isActivated) {
- selectedNumbers.remove(phoneNumber);
- } else {
- selectedNumbers.add(phoneNumber);
- }
- }
- );
+ mFavoriteIcon = getResources().getDrawable(R.drawable.ic_favorite_activatable, null);
+ mFavoriteIcon.setTintList(
+ getResources().getColorStateList(R.color.primary_icon_selector, null));
+
+ mFavoritePhoneNumberList = new ArrayList<>();
+ mDialogAdapter = new CarUiListItemAdapter(mFavoritePhoneNumberList);
mCurrentDialog = new AlertDialogBuilder(getContext())
.setTitle(R.string.select_number_dialog_title)
- .setAdapter(mDialogAdapter, null)
+ .setAdapter(mDialogAdapter)
.setNegativeButton(R.string.cancel_add_favorites_dialog, null)
.setPositiveButton(R.string.confirm_add_favorites_dialog,
(d, which) -> {
- for (PhoneNumber number : selectedNumbers) {
- favoriteViewModel.addToFavorite(mDialogAdapter.getContact(),
+ for (PhoneNumber number : mSelectedNumbers) {
+ favoriteViewModel.addToFavorite(mSelectedContact,
number);
}
- selectedNumbers.clear();
+ mSelectedNumbers.clear();
getFragmentManager().popBackStackImmediate();
})
.create();
}
+ private void setPhoneNumbers(List<PhoneNumber> phoneNumbers) {
+ mFavoritePhoneNumberList.clear();
+ for (PhoneNumber number : phoneNumbers) {
+ CarUiContentListItem item = new CarUiContentListItem(CarUiContentListItem.Action.ICON);
+ item.setTitle(number.getNumber());
+ item.setSupplementalIcon(mFavoriteIcon.getConstantState().newDrawable());
+ setFavoriteItemState(item, number);
+
+ item.setOnItemClickedListener((listItem) -> {
+ if (mSelectedNumbers.contains(number)) {
+ mSelectedNumbers.remove(number);
+ listItem.setActivated(false);
+ } else {
+ mSelectedNumbers.add(number);
+ listItem.setActivated(true);
+ }
+ mDialogAdapter.notifyItemChanged(mFavoritePhoneNumberList.indexOf(listItem));
+ });
+ mFavoritePhoneNumberList.add(item);
+ }
+ mDialogAdapter.notifyDataSetChanged();
+ }
+
+ private void setFavoriteItemState(CarUiContentListItem item, PhoneNumber number) {
+ CharSequence readableLabel = number.getReadableLabel(getResources());
+
+ if (number.isFavorite()) {
+ // This phone number is marked as favorite locally. Disable the favorite action button.
+ item.setEnabled(false);
+ item.setActivated(true);
+ item.setBody(getResources().getString(R.string.favorite_number_description,
+ readableLabel));
+ } else if (mSelectedContact.isStarred()) {
+ // This contact is downloaded from phone, all phone numbers under this contact will show
+ // under the favorite tab. Disable the favorite action button.
+ item.setActivated(false);
+ item.setEnabled(false);
+ item.setBody(getResources().getString(R.string.favorite_number_description,
+ readableLabel));
+ } else {
+ item.setEnabled(true);
+ item.setActivated(false);
+ item.setBody(readableLabel);
+ }
+ }
+
@Override
public void onShowContactDetail(Contact contact) {
if (contact == null) {
@@ -90,11 +141,12 @@
return;
}
+ mSelectedContact = contact;
if (contact.getNumbers().isEmpty()) {
Toast.makeText(getContext(), R.string.no_phone_numbers, Toast.LENGTH_SHORT).show();
mCurrentDialog.dismiss();
} else {
- mDialogAdapter.setPhoneNumbers(contact, contact.getNumbers());
+ setPhoneNumbers(contact.getNumbers());
mCurrentDialog.show();
}
}