Update look and feel of list preference screen am: f4dae1faf3

Change-Id: I5aaa49c020249f949a4902b2cdad4594d6135ee2
diff --git a/car-ui-lib/res/layout/car_ui_radio_button_item.xml b/car-ui-lib/res/layout/car_ui_radio_button_item.xml
deleted file mode 100644
index b7718d1..0000000
--- a/car-ui-lib/res/layout/car_ui_radio_button_item.xml
+++ /dev/null
@@ -1,65 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
-  ~ Copyright 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:background="?android:attr/selectableItemBackground"
-    android:layout_width="match_parent"
-    android:layout_height="@dimen/car_ui_list_item_radio_button_height">
-
-    <androidx.constraintlayout.widget.Guideline
-        android:id="@+id/car_ui_radio_button_start_guideline"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:orientation="vertical"
-        app:layout_constraintGuide_begin="@dimen/car_ui_list_item_radio_button_start_inset" />
-
-    <androidx.constraintlayout.widget.Guideline
-        android:id="@+id/car_ui_radio_button_end_guideline"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:orientation="vertical"
-        app:layout_constraintGuide_end="@dimen/car_ui_list_item_radio_button_end_inset" />
-
-    <FrameLayout
-        android:id="@+id/radio_button_container"
-        android:layout_width="@dimen/car_ui_list_item_radio_button_icon_container_width"
-        android:layout_height="0dp"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintStart_toStartOf="@+id/car_ui_radio_button_start_guideline"
-        app:layout_constraintTop_toTopOf="parent">
-
-        <RadioButton
-            android:id="@+id/radio_button"
-            android:clickable="false"
-            android:focusable="false"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center" />
-    </FrameLayout>
-
-    <TextView
-        android:id="@+id/text"
-        android:layout_width="0dp"
-        android:layout_height="wrap_content"
-        android:layout_marginStart="@dimen/car_ui_list_item_text_start_margin"
-        android:textAppearance="@style/TextAppearance.CarUi.ListItem"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintEnd_toEndOf="@+id/car_ui_radio_button_end_guideline"
-        app:layout_constraintStart_toEndOf="@+id/radio_button_container"
-        app:layout_constraintTop_toTopOf="parent" />
-
-</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/car-ui-lib/res/values/styles.xml b/car-ui-lib/res/values/styles.xml
index 9b9419a..d22753f 100644
--- a/car-ui-lib/res/values/styles.xml
+++ b/car-ui-lib/res/values/styles.xml
@@ -137,13 +137,6 @@
         <item name="android:scaleType">fitCenter</item>
     </style>
 
-    <style name="Preference.CarUi.ListPreference" parent="android:Theme.DeviceDefault.Dialog">
-        <item name="android:windowNoTitle">true</item>
-        <!-- Set this to true if you want Full Screen without status bar -->
-        <item name="android:windowFullscreen">true</item>
-        <item name="android:windowIsFloating">false</item>
-    </style>
-
     <!-- Preference Styles -->
 
     <style name="Preference.CarUi">
diff --git a/car-ui-lib/src/com/android/car/ui/preference/CarUiRecyclerViewRadioButtonAdapter.java b/car-ui-lib/src/com/android/car/ui/preference/CarUiRecyclerViewRadioButtonAdapter.java
deleted file mode 100644
index 41e1351..0000000
--- a/car-ui-lib/src/com/android/car/ui/preference/CarUiRecyclerViewRadioButtonAdapter.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright 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.ui.preference;
-
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.RadioButton;
-import android.widget.TextView;
-
-import androidx.annotation.NonNull;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.android.car.ui.R;
-
-import java.util.List;
-
-/**
- * The adapter for the recyclerview containing radio buttons as the items.
- */
-public class CarUiRecyclerViewRadioButtonAdapter extends
-        RecyclerView.Adapter<CarUiRecyclerViewRadioButtonAdapter.ViewHolder> {
-
-    /**
-     * Callback that will be issued after any radio button is clicked.
-     */
-    public interface OnRadioButtonClickedListener {
-        /**
-         * Will be called when radio button is clicked.
-         *
-         * @param position of the radio button.
-         */
-        void onClick(int position);
-    }
-
-    private OnRadioButtonClickedListener mOnRadioButtonClickedListener;
-
-    private final List<String> mList;
-    private int mSelectedPosition = -1;
-
-    public CarUiRecyclerViewRadioButtonAdapter(List<String> list, int position) {
-        mList = list;
-        mSelectedPosition = position;
-    }
-
-    @NonNull
-    @Override
-    public CarUiRecyclerViewRadioButtonAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
-            int viewType) {
-        View view = LayoutInflater.from(parent.getContext())
-                .inflate(R.layout.car_ui_radio_button_item, parent, false);
-        return new CarUiRecyclerViewRadioButtonAdapter.ViewHolder(view);
-    }
-
-    @Override
-    public void onBindViewHolder(CarUiRecyclerViewRadioButtonAdapter.ViewHolder holder,
-            int position) {
-        String entry = mList.get(position);
-        //since only one radio button is allowed to be selected,
-        // this condition un-checks previous selections
-        holder.mRadioButton.setChecked(mSelectedPosition == position);
-        holder.mTextView.setText(entry);
-    }
-
-    @Override
-    public int getItemCount() {
-        return mList.size();
-    }
-
-    /** Registers a new {@link OnRadioButtonClickedListener} listener. */
-    public void registerListener(OnRadioButtonClickedListener listener) {
-        mOnRadioButtonClickedListener = listener;
-    }
-
-    /** Unregisters a {@link OnRadioButtonClickedListener} listener\. */
-    public void unregisterOnBackListener(OnRadioButtonClickedListener listener) {
-        mOnRadioButtonClickedListener = null;
-    }
-
-    /** The viewholder class for recyclerview containing radio buttons. */
-    class ViewHolder extends RecyclerView.ViewHolder {
-
-        RadioButton mRadioButton;
-        TextView mTextView;
-
-        ViewHolder(View view) {
-            super(view);
-            mRadioButton = view.findViewById(R.id.radio_button);
-            mTextView = view.findViewById(R.id.text);
-
-            view.setOnClickListener(v -> {
-                mSelectedPosition = getAdapterPosition();
-                notifyDataSetChanged();
-                if (mOnRadioButtonClickedListener != null) {
-                    mOnRadioButtonClickedListener.onClick(mSelectedPosition);
-                }
-            });
-        }
-    }
-}
diff --git a/car-ui-lib/src/com/android/car/ui/preference/ListPreferenceFragment.java b/car-ui-lib/src/com/android/car/ui/preference/ListPreferenceFragment.java
index 7df7411..f8ff7c7 100644
--- a/car-ui-lib/src/com/android/car/ui/preference/ListPreferenceFragment.java
+++ b/car-ui-lib/src/com/android/car/ui/preference/ListPreferenceFragment.java
@@ -31,6 +31,9 @@
 import androidx.preference.Preference;
 
 import com.android.car.ui.R;
+import com.android.car.ui.recyclerview.CarUiContentListItem;
+import com.android.car.ui.recyclerview.CarUiListItem;
+import com.android.car.ui.recyclerview.CarUiListItemAdapter;
 import com.android.car.ui.recyclerview.CarUiRecyclerView;
 import com.android.car.ui.toolbar.Toolbar;
 
@@ -41,11 +44,10 @@
  * A fragment that provides a layout with a list of options associated with a {@link
  * ListPreference}.
  */
-public class ListPreferenceFragment extends Fragment implements
-        CarUiRecyclerViewRadioButtonAdapter.OnRadioButtonClickedListener {
+public class ListPreferenceFragment extends Fragment {
 
     private ListPreference mPreference;
-    private int mClickedDialogEntryIndex;
+    private CarUiContentListItem mSelectedItem;
 
     /**
      * Returns a new instance of {@link ListPreferenceFragment} for the {@link ListPreference} with
@@ -70,21 +72,21 @@
     @Override
     public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
         super.onViewCreated(view, savedInstanceState);
-        final CarUiRecyclerView mCarUiRecyclerView = view.requireViewById(R.id.list);
+        final CarUiRecyclerView carUiRecyclerView = view.requireViewById(R.id.list);
         final Toolbar toolbar = view.requireViewById(R.id.toolbar);
 
-        mCarUiRecyclerView.setPadding(0, toolbar.getHeight(), 0, 0);
+        carUiRecyclerView.setPadding(0, toolbar.getHeight(), 0, 0);
         toolbar.registerToolbarHeightChangeListener(newHeight -> {
-            if (mCarUiRecyclerView.getPaddingTop() == newHeight) {
+            if (carUiRecyclerView.getPaddingTop() == newHeight) {
                 return;
             }
 
-            int oldHeight = mCarUiRecyclerView.getPaddingTop();
-            mCarUiRecyclerView.setPadding(0, newHeight, 0, 0);
-            mCarUiRecyclerView.scrollBy(0, oldHeight - newHeight);
+            int oldHeight = carUiRecyclerView.getPaddingTop();
+            carUiRecyclerView.setPadding(0, newHeight, 0, 0);
+            carUiRecyclerView.scrollBy(0, oldHeight - newHeight);
         });
 
-        mCarUiRecyclerView.setClipToPadding(false);
+        carUiRecyclerView.setClipToPadding(false);
         mPreference = getListPreference();
         toolbar.setTitle(mPreference.getTitle());
 
@@ -101,16 +103,42 @@
                     "ListPreference entries array length does not match entryValues array length.");
         }
 
-        mClickedDialogEntryIndex = mPreference.findIndexOfValue(mPreference.getValue());
-        List<String> entryStrings = new ArrayList<>(entries.length);
-        for (CharSequence entry : entries) {
-            entryStrings.add(entry.toString());
+        int selectedEntryIndex = mPreference.findIndexOfValue(mPreference.getValue());
+        List<CarUiListItem> listItems = new ArrayList<>();
+        CarUiListItemAdapter adapter = new CarUiListItemAdapter(listItems);
+
+        for (int i = 0; i < entries.length; i++) {
+            String entry = entries[i].toString();
+            CarUiContentListItem item = new CarUiContentListItem();
+            item.setAction(CarUiContentListItem.Action.RADIO_BUTTON);
+            item.setTitle(entry);
+
+            if (i == selectedEntryIndex) {
+                item.setChecked(true);
+                mSelectedItem = item;
+            }
+
+            item.setOnCheckedChangedListener((listItem, isChecked) -> {
+                mSelectedItem.setChecked(false);
+                adapter.notifyItemChanged(listItems.indexOf(mSelectedItem));
+                mSelectedItem = listItem;
+            });
+
+            listItems.add(item);
         }
 
-        CarUiRecyclerViewRadioButtonAdapter adapter = new CarUiRecyclerViewRadioButtonAdapter(
-                entryStrings, mClickedDialogEntryIndex);
-        mCarUiRecyclerView.setAdapter(adapter);
-        adapter.registerListener(this);
+        toolbar.registerOnBackListener(() -> {
+            int selectedIndex = listItems.indexOf(mSelectedItem);
+            String entryValue = entryValues[selectedIndex].toString();
+
+            if (mPreference.callChangeListener(entryValue)) {
+                mPreference.setValue(entryValue);
+            }
+
+            return false;
+        });
+
+        carUiRecyclerView.setAdapter(adapter);
     }
 
     private ListPreference getListPreference() {
@@ -143,27 +171,4 @@
 
         return (ListPreference) preference;
     }
-
-    @Override
-    public void onClick(int position) {
-        CharSequence[] entryValues = mPreference.getEntryValues();
-
-        if (position < 0 || position > entryValues.length - 1) {
-            throw new IllegalStateException(
-                    "Clicked preference has invalid index.");
-        }
-
-        mClickedDialogEntryIndex = position;
-        String value = entryValues[mClickedDialogEntryIndex].toString();
-        if (mPreference.callChangeListener(value)) {
-            mPreference.setValue(value);
-        }
-
-        if (getActivity() == null) {
-            throw new IllegalStateException(
-                    "ListPreference fragment is not attached to an Activity.");
-        }
-
-        getActivity().getSupportFragmentManager().popBackStack();
-    }
 }
diff --git a/car-ui-lib/src/com/android/car/ui/preference/MultiSelectListPreferenceFragment.java b/car-ui-lib/src/com/android/car/ui/preference/MultiSelectListPreferenceFragment.java
index 17362f5..e505708 100644
--- a/car-ui-lib/src/com/android/car/ui/preference/MultiSelectListPreferenceFragment.java
+++ b/car-ui-lib/src/com/android/car/ui/preference/MultiSelectListPreferenceFragment.java
@@ -118,7 +118,7 @@
             item.setAction(CarUiContentListItem.Action.CHECK_BOX);
             item.setTitle(entry);
             item.setChecked(selectedItems[i]);
-            item.setOnCheckedChangedListener(isChecked -> {
+            item.setOnCheckedChangedListener((listItem, isChecked) -> {
                 if (isChecked) {
                     mNewValues.add(entryValue);
                 } else {
diff --git a/car-ui-lib/src/com/android/car/ui/recyclerview/CarUiContentListItem.java b/car-ui-lib/src/com/android/car/ui/recyclerview/CarUiContentListItem.java
index fd5bf50..724b639 100644
--- a/car-ui-lib/src/com/android/car/ui/recyclerview/CarUiContentListItem.java
+++ b/car-ui-lib/src/com/android/car/ui/recyclerview/CarUiContentListItem.java
@@ -34,9 +34,10 @@
         /**
          * Called when the checked state of a list item has changed.
          *
+         * @param item The item whose checked state changed.
          * @param isChecked new checked state of list item.
          */
-        void onCheckedChanged(boolean isChecked);
+        void onCheckedChanged(CarUiContentListItem item, boolean isChecked);
     }
 
     /**
diff --git a/car-ui-lib/src/com/android/car/ui/recyclerview/CarUiListItemAdapter.java b/car-ui-lib/src/com/android/car/ui/recyclerview/CarUiListItemAdapter.java
index b39bbd9..1b71411 100644
--- a/car-ui-lib/src/com/android/car/ui/recyclerview/CarUiListItemAdapter.java
+++ b/car-ui-lib/src/com/android/car/ui/recyclerview/CarUiListItemAdapter.java
@@ -223,6 +223,7 @@
                     break;
                 case SWITCH:
                     mSwitch.setVisibility(View.VISIBLE);
+                    mSwitch.setOnCheckedChangeListener(null);
                     mSwitch.setChecked(item.isChecked());
                     mSwitch.setOnCheckedChangeListener(
                             (buttonView, isChecked) -> {
@@ -230,7 +231,7 @@
                                 CarUiContentListItem.OnCheckedChangedListener itemListener =
                                         item.getOnCheckedChangedListener();
                                 if (itemListener != null) {
-                                    itemListener.onCheckedChanged(isChecked);
+                                    itemListener.onCheckedChanged(item, isChecked);
                                 }
                             });
 
@@ -245,6 +246,7 @@
                     break;
                 case CHECK_BOX:
                     mCheckBox.setVisibility(View.VISIBLE);
+                    mCheckBox.setOnCheckedChangeListener(null);
                     mCheckBox.setChecked(item.isChecked());
                     mCheckBox.setOnCheckedChangeListener(
                             (buttonView, isChecked) -> {
@@ -252,7 +254,7 @@
                                 CarUiContentListItem.OnCheckedChangedListener itemListener =
                                         item.getOnCheckedChangedListener();
                                 if (itemListener != null) {
-                                    itemListener.onCheckedChanged(isChecked);
+                                    itemListener.onCheckedChanged(item, isChecked);
                                 }
                             });
 
@@ -267,6 +269,7 @@
                     break;
                 case RADIO_BUTTON:
                     mRadioButton.setVisibility(View.VISIBLE);
+                    mRadioButton.setOnCheckedChangeListener(null);
                     mRadioButton.setChecked(item.isChecked());
                     mRadioButton.setOnCheckedChangeListener(
                             (buttonView, isChecked) -> {
@@ -274,7 +277,7 @@
                                 CarUiContentListItem.OnCheckedChangedListener itemListener =
                                         item.getOnCheckedChangedListener();
                                 if (itemListener != null) {
-                                    itemListener.onCheckedChanged(isChecked);
+                                    itemListener.onCheckedChanged(item, isChecked);
                                 }
                             });
 
diff --git a/car-ui-lib/tests/apitest/current.xml b/car-ui-lib/tests/apitest/current.xml
index c428165..5f21189 100644
--- a/car-ui-lib/tests/apitest/current.xml
+++ b/car-ui-lib/tests/apitest/current.xml
@@ -208,7 +208,6 @@
   <public type="style" name="Preference.CarUi.DropDown"/>
   <public type="style" name="Preference.CarUi.Icon"/>
   <public type="style" name="Preference.CarUi.Information"/>
-  <public type="style" name="Preference.CarUi.ListPreference"/>
   <public type="style" name="Preference.CarUi.Preference"/>
   <public type="style" name="Preference.CarUi.PreferenceScreen"/>
   <public type="style" name="Preference.CarUi.SeekBarPreference"/>
diff --git a/car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/caruirecyclerview/CarUiListItemActivity.java b/car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/caruirecyclerview/CarUiListItemActivity.java
index c307cb3..a5aeeee 100644
--- a/car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/caruirecyclerview/CarUiListItemActivity.java
+++ b/car-ui-lib/tests/paintbooth/src/com/android/car/ui/paintbooth/caruirecyclerview/CarUiListItemActivity.java
@@ -88,7 +88,7 @@
         item.setTitle("Title -- Item with checkbox");
         item.setBody("Will present toast on change of selection state.");
         item.setOnCheckedChangedListener(
-                (isChecked) -> Toast.makeText(context,
+                (listItem, isChecked) -> Toast.makeText(context,
                         "Item checked state is: " + isChecked, Toast.LENGTH_SHORT).show());
         item.setAction(CarUiContentListItem.Action.CHECK_BOX);
         mData.add(item);
@@ -114,7 +114,7 @@
         radioItem1.setBody("Item is initially unchecked checked");
         radioItem1.setAction(CarUiContentListItem.Action.RADIO_BUTTON);
         radioItem1.setChecked(false);
-        radioItem1.setOnCheckedChangedListener(isChecked -> {
+        radioItem1.setOnCheckedChangedListener((listItem, isChecked) -> {
             if (isChecked) {
                 radioItem2.setChecked(false);
                 mAdapter.notifyItemChanged(mData.indexOf(radioItem2));
@@ -126,7 +126,7 @@
         radioItem2.setTitle("Item is mutually exclusive with item above");
         radioItem2.setAction(CarUiContentListItem.Action.RADIO_BUTTON);
         radioItem2.setChecked(true);
-        radioItem2.setOnCheckedChangedListener(isChecked -> {
+        radioItem2.setOnCheckedChangedListener((listItem, isChecked) -> {
             if (isChecked) {
                 radioItem1.setChecked(false);
                 mAdapter.notifyItemChanged(mData.indexOf(radioItem1));
diff --git a/car-ui-lib/tests/robotests/src/com/android/car/ui/recyclerview/CarUiListItemTest.java b/car-ui-lib/tests/robotests/src/com/android/car/ui/recyclerview/CarUiListItemTest.java
index 8c10ede..dec4c19 100644
--- a/car-ui-lib/tests/robotests/src/com/android/car/ui/recyclerview/CarUiListItemTest.java
+++ b/car-ui-lib/tests/robotests/src/com/android/car/ui/recyclerview/CarUiListItemTest.java
@@ -241,7 +241,7 @@
         switchWidget.performClick();
         assertThat(switchWidget.isChecked()).isEqualTo(false);
         verify(mOnCheckedChangedListener, times(1))
-                .onCheckedChanged(false);
+                .onCheckedChanged(item, false);
     }
 
     @Test
@@ -262,7 +262,7 @@
         checkBox.performClick();
         assertThat(checkBox.isChecked()).isEqualTo(true);
         verify(mOnCheckedChangedListener, times(1))
-                .onCheckedChanged(true);
+                .onCheckedChanged(item, true);
     }
 
     @Test