Merge "Theme fixit for Car Sys UI"
This commit is contained in:
@@ -32,7 +32,6 @@ android_app {
|
||||
"SystemUISharedLib",
|
||||
"SettingsLib",
|
||||
"android.car.userlib",
|
||||
"androidx.car_car",
|
||||
"androidx.legacy_legacy-support-v4",
|
||||
"androidx.recyclerview_recyclerview",
|
||||
"androidx.preference_preference",
|
||||
@@ -46,7 +45,6 @@ android_app {
|
||||
"androidx.slice_slice-builders",
|
||||
"androidx.arch.core_core-runtime",
|
||||
"androidx.lifecycle_lifecycle-extensions",
|
||||
"car-theme-lib-bp",
|
||||
"SystemUI-tags",
|
||||
"SystemUI-proto",
|
||||
],
|
||||
|
||||
@@ -14,12 +14,12 @@
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:fitsSystemWindows="true"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:visibility="gone">
|
||||
<FrameLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true"
|
||||
android:visibility="gone">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/container"
|
||||
@@ -27,20 +27,21 @@
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<include layout="@layout/car_status_bar_header"
|
||||
android:theme="@android:style/Theme"
|
||||
android:layout_alignParentTop="true"/>
|
||||
<include
|
||||
layout="@layout/car_status_bar_header"
|
||||
android:layout_alignParentTop="true"
|
||||
android:theme="@android:style/Theme"/>
|
||||
|
||||
<com.android.systemui.statusbar.car.UserGridRecyclerView
|
||||
android:id="@+id/user_grid"
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="@dimen/car_user_switcher_margin_top"
|
||||
android:theme="@style/PagedListTheme"
|
||||
app:verticallyCenterListContent="true"
|
||||
app:showPagedListViewDivider="false"
|
||||
app:gutter="both"
|
||||
app:itemSpacing="@dimen/car_user_switcher_vertical_spacing_between_users"/>
|
||||
android:layout_height="match_parent">
|
||||
<com.android.systemui.statusbar.car.UserGridRecyclerView
|
||||
android:id="@+id/user_grid"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginTop="@dimen/car_user_switcher_margin_top"/>
|
||||
</FrameLayout>
|
||||
|
||||
</LinearLayout>
|
||||
</FrameLayout>
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
|
||||
<RelativeLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/user_switcher_container"
|
||||
android:clipChildren="false"
|
||||
android:layout_width="match_parent"
|
||||
@@ -37,11 +36,7 @@
|
||||
<com.android.systemui.statusbar.car.UserGridRecyclerView
|
||||
android:id="@+id/user_grid"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:theme="@style/PagedListTheme"
|
||||
app:showPagedListViewDivider="false"
|
||||
app:gutter="both"
|
||||
app:itemSpacing="@dimen/car_user_switcher_vertical_spacing_between_users"/>
|
||||
android:layout_height="match_parent"/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
|
||||
@@ -14,15 +14,9 @@
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License
|
||||
-->
|
||||
<androidx.car.widget.PagedListView
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/volume_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minWidth="@dimen/volume_dialog_panel_width"
|
||||
android:theme="@style/PagedListViewTheme"
|
||||
app:gutter="none"
|
||||
app:scrollBarEnabled="false"
|
||||
app:listDividerColor="@color/list_divider_color"
|
||||
app:showPagedListViewDivider="true"/>
|
||||
android:minWidth="@dimen/volume_dialog_panel_width"/>
|
||||
|
||||
71
packages/CarSystemUI/res/layout/car_volume_item.xml
Normal file
71
packages/CarSystemUI/res/layout/car_volume_item.xml
Normal file
@@ -0,0 +1,71 @@
|
||||
<?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.
|
||||
-->
|
||||
|
||||
<RelativeLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="@dimen/car_volume_item_height">
|
||||
|
||||
<!-- Primary Action. -->
|
||||
<ImageView
|
||||
android:id="@+id/primary_icon"
|
||||
android:layout_width="@dimen/car_primary_icon_size"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginStart="@dimen/car_volume_item_margin_horizontal"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_height="@dimen/car_primary_icon_size"/>
|
||||
|
||||
<!-- Note: the horizontal padding and offset are set to 0 so that the track and thumb
|
||||
aligns with the proper keylines. -->
|
||||
<SeekBar
|
||||
android:id="@+id/seek_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/car_volume_item_seekbar_margin_vertical"
|
||||
android:layout_marginTop="@dimen/car_volume_item_seekbar_margin_vertical"
|
||||
android:min="0"
|
||||
android:paddingBottom="@dimen/car_volume_item_seekbar_padding_vertical"
|
||||
android:layout_centerVertical="true"
|
||||
android:paddingEnd="0dp"
|
||||
android:paddingStart="0dp"
|
||||
android:paddingTop="@dimen/car_volume_item_seekbar_padding_vertical"
|
||||
android:splitTrack="false"
|
||||
android:layout_toStartOf="@id/supplemental_icon_divider"
|
||||
android:layout_marginStart="@dimen/car_volume_item_seekbar_margin_start"
|
||||
android:layout_marginEnd="@dimen/car_volume_item_seekbar_margin_end"
|
||||
android:thumbOffset="0dp"/>
|
||||
|
||||
<!-- Supplemental action. -->
|
||||
<View
|
||||
android:id="@+id/supplemental_icon_divider"
|
||||
android:layout_width="@dimen/car_volume_item_divider_width"
|
||||
android:layout_height="@dimen/car_volume_item_divider_height"
|
||||
android:layout_marginEnd="@dimen/car_volume_item_divider_margin_end"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_toStartOf="@id/supplemental_icon"
|
||||
android:background="@color/car_volume_item_divider_color"/>
|
||||
<ImageView
|
||||
android:id="@+id/supplemental_icon"
|
||||
android:layout_width="@dimen/car_primary_icon_size"
|
||||
android:layout_height="@dimen/car_primary_icon_size"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_marginEnd="@dimen/car_volume_item_margin_horizontal"
|
||||
android:scaleType="fitCenter"/>
|
||||
</RelativeLayout>
|
||||
@@ -32,19 +32,14 @@
|
||||
android:translationZ="2dp"
|
||||
/>
|
||||
|
||||
<androidx.car.widget.PagedListView
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/notifications"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:orientation="vertical"
|
||||
android:theme="@style/PagedListTheme"
|
||||
app:gutter="none"
|
||||
app:itemSpacing="@dimen/item_spacing"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:scrollBarEnabled="false"
|
||||
app:showPagedListViewDivider="false"/>
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
|
||||
</com.android.car.notification.CarNotificationView>
|
||||
|
||||
@@ -45,4 +45,6 @@
|
||||
<color name="keyguard_button_text_color">@android:color/black</color>
|
||||
|
||||
<color name="list_divider_color">@*android:color/car_list_divider_light</color>
|
||||
<color name="car_volume_item_divider_color">@*android:color/car_list_divider</color>
|
||||
<color name="car_volume_item_background_color">@*android:color/car_card_dark</color>
|
||||
</resources>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<!-- The amount by which to scale up the status bar icons. -->
|
||||
<item name="status_bar_icon_scale_factor" format="float" type="dimen">1.75</item>
|
||||
|
||||
<dimen name="car_primary_icon_size">36dp</dimen>
|
||||
<dimen name="car_primary_icon_size">@*android:dimen/car_primary_icon_size</dimen>
|
||||
|
||||
<!-- dimensions for the car user switcher -->
|
||||
<dimen name="car_user_switcher_name_text_size">@dimen/car_body1_size</dimen>
|
||||
@@ -59,4 +59,33 @@
|
||||
<dimen name="car_keyline_1">24dp</dimen>
|
||||
<dimen name="car_keyline_2">96dp</dimen>
|
||||
<dimen name="car_keyline_3">128dp</dimen>
|
||||
|
||||
<dimen name="privacy_chip_icon_max_height">100dp</dimen>
|
||||
|
||||
<!-- Height of icons in Ongoing App Ops dialog. Both App Op icon and application icon -->
|
||||
<dimen name="ongoing_appops_dialog_icon_height">48dp</dimen>
|
||||
<!-- Margin between text lines in Ongoing App Ops dialog -->
|
||||
<dimen name="ongoing_appops_dialog_text_margin">15dp</dimen>
|
||||
<!-- Padding around Ongoing App Ops dialog content -->
|
||||
<dimen name="ongoing_appops_dialog_content_padding">24dp</dimen>
|
||||
<!-- Margins around the Ongoing App Ops chip. In landscape, the side margins are 0 -->
|
||||
<dimen name="ongoing_appops_chip_margin">12dp</dimen>
|
||||
<!-- Start and End padding for Ongoing App Ops chip -->
|
||||
<dimen name="ongoing_appops_chip_side_padding">6dp</dimen>
|
||||
<!-- Padding between background of Ongoing App Ops chip and content -->
|
||||
<dimen name="ongoing_appops_chip_bg_padding">4dp</dimen>
|
||||
<!-- Radius of Ongoing App Ops chip corners -->
|
||||
<dimen name="ongoing_appops_chip_bg_corner_radius">12dp</dimen>
|
||||
|
||||
<!-- Car volume dimens. -->
|
||||
<dimen name="car_volume_item_height">@*android:dimen/car_single_line_list_item_height</dimen>
|
||||
<dimen name="car_volume_item_margin_horizontal">@*android:dimen/car_keyline_1</dimen>
|
||||
<dimen name="car_volume_item_seekbar_margin_vertical">@*android:dimen/car_padding_1</dimen>
|
||||
<dimen name="car_volume_item_seekbar_margin_start">@*android:dimen/car_keyline_3</dimen>
|
||||
<dimen name="car_volume_item_seekbar_margin_end">@*android:dimen/car_padding_4</dimen>
|
||||
<dimen name="car_volume_item_seekbar_padding_vertical">@*android:dimen/car_seekbar_padding</dimen>
|
||||
<dimen name="car_volume_item_divider_height">60dp</dimen>
|
||||
<dimen name="car_volume_item_divider_width">1dp</dimen>
|
||||
<dimen name="car_volume_item_divider_margin_end">@*android:dimen/car_padding_4</dimen>
|
||||
<dimen name="car_volume_item_corner_radius">@*android:dimen/car_radius_3</dimen>
|
||||
</resources>
|
||||
|
||||
@@ -46,11 +46,4 @@
|
||||
<item name="android:layout_width">96dp</item>
|
||||
<item name="android:background">@drawable/nav_button_background</item>
|
||||
</style>
|
||||
|
||||
<style name="PagedListViewTheme" parent="@style/Theme.CarSupportWrapper.NoActionBar">
|
||||
<item name="android:background">@*android:color/car_background</item>
|
||||
<item name="listItemBackgroundColor">@*android:color/car_background</item>
|
||||
<item name="dividerEndMargin">@dimen/car_keyline_1</item>
|
||||
<item name="dividerStartMargin">@dimen/car_keyline_1</item>
|
||||
</style>
|
||||
</resources>
|
||||
@@ -18,10 +18,6 @@
|
||||
-->
|
||||
|
||||
<resources>
|
||||
<!--This Theme contains attributes required for components from the car support lib -->
|
||||
<style name="PagedListTheme" parent="Theme.CarSupportWrapper.NoActionBar">
|
||||
</style>
|
||||
|
||||
<style name="Theme.Notification" parent="Theme.DeviceDefault.NoActionBar.Notification">
|
||||
</style>
|
||||
</resources>
|
||||
|
||||
@@ -16,11 +16,11 @@
|
||||
|
||||
package com.android.systemui.notifications;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.ActivityManager;
|
||||
import android.car.Car;
|
||||
import android.car.CarNotConnectedException;
|
||||
import android.car.drivingstate.CarUxRestrictionsManager;
|
||||
@@ -113,7 +113,7 @@ public class NotificationsUI extends SystemUI
|
||||
ServiceManager.getService(Context.STATUS_BAR_SERVICE)),
|
||||
launchResult -> {
|
||||
if (launchResult == ActivityManager.START_TASK_TO_FRONT
|
||||
|| launchResult == ActivityManager.START_SUCCESS){
|
||||
|| launchResult == ActivityManager.START_SUCCESS) {
|
||||
closeCarNotifications(DEFAULT_FLING_VELOCITY);
|
||||
}
|
||||
});
|
||||
@@ -179,8 +179,7 @@ public class NotificationsUI extends SystemUI
|
||||
}
|
||||
});
|
||||
|
||||
RecyclerView notificationList = mCarNotificationWindow
|
||||
.findViewById(com.android.car.notification.R.id.recycler_view);
|
||||
RecyclerView notificationList = mCarNotificationWindow.findViewById(R.id.notifications);
|
||||
// register a scroll listener so we can figure out if we are at the bottom of the
|
||||
// list of notifications
|
||||
notificationList.addOnScrollListener(new RecyclerView.OnScrollListener() {
|
||||
@@ -202,7 +201,7 @@ public class NotificationsUI extends SystemUI
|
||||
// There's a view installed at a higher z-order such that we can intercept the ACTION_DOWN
|
||||
// to set the initial click state.
|
||||
mCarNotificationWindow.findViewById(R.id.glass_pane).setOnTouchListener((v, event) -> {
|
||||
if (event.getActionMasked() == MotionEvent.ACTION_UP ) {
|
||||
if (event.getActionMasked() == MotionEvent.ACTION_UP) {
|
||||
mNotificationListAtBottomAtTimeOfTouch = false;
|
||||
}
|
||||
if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
|
||||
@@ -259,7 +258,7 @@ public class NotificationsUI extends SystemUI
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
// reset mNotificationListAtBottomAtTimeOfTouch here since the "glass pane" will not
|
||||
// get the up event
|
||||
if (event.getActionMasked() == MotionEvent.ACTION_UP ) {
|
||||
if (event.getActionMasked() == MotionEvent.ACTION_UP) {
|
||||
mNotificationListAtBottomAtTimeOfTouch = false;
|
||||
}
|
||||
boolean wasScrolledUp = mScrollUpDetector.onTouchEvent(event);
|
||||
@@ -351,7 +350,7 @@ public class NotificationsUI extends SystemUI
|
||||
public boolean onFling(MotionEvent event1, MotionEvent event2,
|
||||
float velocityX, float velocityY) {
|
||||
if (Math.abs(event1.getX() - event2.getX()) > SWIPE_MAX_OFF_PATH
|
||||
|| Math.abs(velocityY) < SWIPE_THRESHOLD_VELOCITY){
|
||||
|| Math.abs(velocityY) < SWIPE_THRESHOLD_VELOCITY) {
|
||||
// swipe was not vertical or was not fast enough
|
||||
return false;
|
||||
}
|
||||
@@ -435,8 +434,7 @@ public class NotificationsUI extends SystemUI
|
||||
mNotificationViewController.disable();
|
||||
mIsShowing = false;
|
||||
mIsTracking = false;
|
||||
RecyclerView notificationListView = mCarNotificationWindow.findViewById(
|
||||
com.android.car.notification.R.id.recycler_view);
|
||||
RecyclerView notificationListView = mCarNotificationWindow.findViewById(R.id.notifications);
|
||||
notificationListView.scrollToPosition(0);
|
||||
}
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@ public class CarQSFragment extends Fragment implements QS {
|
||||
mUserGridView = mUserSwitcherContainer.findViewById(R.id.user_grid);
|
||||
GridLayoutManager layoutManager = new GridLayoutManager(context,
|
||||
context.getResources().getInteger(R.integer.user_fullscreen_switcher_num_col));
|
||||
mUserGridView.getRecyclerView().setLayoutManager(layoutManager);
|
||||
mUserGridView.setLayoutManager(layoutManager);
|
||||
mUserGridView.buildAdapter();
|
||||
|
||||
mUserSwitchCallback = new UserSwitchCallback();
|
||||
|
||||
@@ -45,7 +45,7 @@ public class FullscreenUserSwitcher {
|
||||
mUserGridView = container.findViewById(R.id.user_grid);
|
||||
GridLayoutManager layoutManager = new GridLayoutManager(context,
|
||||
context.getResources().getInteger(R.integer.user_fullscreen_switcher_num_col));
|
||||
mUserGridView.getRecyclerView().setLayoutManager(layoutManager);
|
||||
mUserGridView.setLayoutManager(layoutManager);
|
||||
mUserGridView.buildAdapter();
|
||||
mUserGridView.setUserSelectionListener(this::onUserSelected);
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ import android.content.DialogInterface;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Rect;
|
||||
import android.os.AsyncTask;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
@@ -36,9 +37,9 @@ import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.car.widget.PagedListView;
|
||||
import androidx.core.graphics.drawable.RoundedBitmapDrawable;
|
||||
import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory;
|
||||
import androidx.recyclerview.widget.GridLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.android.internal.util.UserIcons;
|
||||
@@ -52,7 +53,7 @@ import java.util.List;
|
||||
* Displays a GridLayout with icons for the users in the system to allow switching between users.
|
||||
* One of the uses of this is for the lock screen in auto.
|
||||
*/
|
||||
public class UserGridRecyclerView extends PagedListView implements
|
||||
public class UserGridRecyclerView extends RecyclerView implements
|
||||
CarUserManagerHelper.OnUsersUpdateListener {
|
||||
private UserSelectionListener mUserSelectionListener;
|
||||
private UserAdapter mAdapter;
|
||||
@@ -63,6 +64,9 @@ public class UserGridRecyclerView extends PagedListView implements
|
||||
super(context, attrs);
|
||||
mContext = context;
|
||||
mCarUserManagerHelper = new CarUserManagerHelper(mContext);
|
||||
|
||||
addItemDecoration(new ItemSpacingDecoration(context.getResources().getDimensionPixelSize(
|
||||
R.dimen.car_user_switcher_vertical_spacing_between_users)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -391,4 +395,31 @@ public class UserGridRecyclerView extends PagedListView implements
|
||||
|
||||
void onUserSelected(UserRecord record);
|
||||
}
|
||||
|
||||
/**
|
||||
* A {@link RecyclerView.ItemDecoration} that will add spacing between each item in the
|
||||
* RecyclerView that it is added to.
|
||||
*/
|
||||
private static class ItemSpacingDecoration extends RecyclerView.ItemDecoration {
|
||||
private int mItemSpacing;
|
||||
|
||||
private ItemSpacingDecoration(int itemSpacing) {
|
||||
mItemSpacing = itemSpacing;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getItemOffsets(Rect outRect, View view, RecyclerView parent,
|
||||
RecyclerView.State state) {
|
||||
super.getItemOffsets(outRect, view, parent, state);
|
||||
int position = parent.getChildAdapterPosition(view);
|
||||
|
||||
// Skip offset for last item except for GridLayoutManager.
|
||||
if (position == state.getItemCount() - 1
|
||||
&& !(parent.getLayoutManager() instanceof GridLayoutManager)) {
|
||||
return;
|
||||
}
|
||||
|
||||
outRect.bottom = mItemSpacing;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,9 +32,7 @@ import android.content.DialogInterface;
|
||||
import android.content.ServiceConnection;
|
||||
import android.content.res.TypedArray;
|
||||
import android.content.res.XmlResourceParser;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.media.AudioManager;
|
||||
import android.os.Debug;
|
||||
@@ -46,7 +44,6 @@ import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.util.SparseArray;
|
||||
import android.util.Xml;
|
||||
import android.view.ContextThemeWrapper;
|
||||
import android.view.Gravity;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
@@ -56,12 +53,8 @@ import android.view.WindowManager;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.SeekBar.OnSeekBarChangeListener;
|
||||
|
||||
import androidx.car.widget.ListItem;
|
||||
import androidx.car.widget.ListItemAdapter;
|
||||
import androidx.car.widget.ListItemAdapter.BackgroundStyle;
|
||||
import androidx.car.widget.ListItemProvider.ListProvider;
|
||||
import androidx.car.widget.PagedListView;
|
||||
import androidx.car.widget.SeekbarListItem;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.plugins.VolumeDialog;
|
||||
@@ -96,13 +89,13 @@ public class CarVolumeDialogImpl implements VolumeDialog {
|
||||
private final SparseArray<VolumeItem> mVolumeItems = new SparseArray<>();
|
||||
// Available volume items in car audio manager.
|
||||
private final List<VolumeItem> mAvailableVolumeItems = new ArrayList<>();
|
||||
// Volume items in the PagedListView.
|
||||
private final List<ListItem> mVolumeLineItems = new ArrayList<>();
|
||||
// Volume items in the RecyclerView.
|
||||
private final List<CarVolumeItem> mCarVolumeLineItems = new ArrayList<>();
|
||||
private final KeyguardManager mKeyguard;
|
||||
private Window mWindow;
|
||||
private CustomDialog mDialog;
|
||||
private PagedListView mListView;
|
||||
private ListItemAdapter mPagedListAdapter;
|
||||
private RecyclerView mListView;
|
||||
private CarVolumeItemAdapter mVolumeItemsAdapter;
|
||||
private Car mCar;
|
||||
private CarAudioManager mCarAudioManager;
|
||||
private final CarAudioManager.CarVolumeCallback mVolumeChangeCallback =
|
||||
@@ -126,7 +119,7 @@ public class CarVolumeDialogImpl implements VolumeDialog {
|
||||
// callback. Updating the seekbar at the same time could block the continuous
|
||||
// seeking.
|
||||
if (value != volumeItem.progress) {
|
||||
volumeItem.listItem.setProgress(value);
|
||||
volumeItem.carVolumeItem.setProgress(value);
|
||||
volumeItem.progress = value;
|
||||
}
|
||||
if ((flags & AudioManager.FLAG_SHOW_UI) != 0) {
|
||||
@@ -160,13 +153,13 @@ public class CarVolumeDialogImpl implements VolumeDialog {
|
||||
// The first one is the default item.
|
||||
if (groupId == 0) {
|
||||
mDefaultVolumeItem = volumeItem;
|
||||
setupDefaultListItem();
|
||||
setupDefaultCarVolumeItem();
|
||||
}
|
||||
}
|
||||
|
||||
// If list is already initiated, update its content.
|
||||
if (mPagedListAdapter != null) {
|
||||
mPagedListAdapter.notifyDataSetChanged();
|
||||
if (mVolumeItemsAdapter != null) {
|
||||
mVolumeItemsAdapter.notifyDataSetChanged();
|
||||
}
|
||||
mCarAudioManager.registerCarVolumeCallback(mVolumeChangeCallback);
|
||||
} catch (CarNotConnectedException e) {
|
||||
@@ -184,15 +177,15 @@ public class CarVolumeDialogImpl implements VolumeDialog {
|
||||
}
|
||||
};
|
||||
|
||||
private void setupDefaultListItem() {
|
||||
private void setupDefaultCarVolumeItem() {
|
||||
mDefaultVolumeItem.defaultItem = true;
|
||||
addSeekbarListItem(mDefaultVolumeItem, /* volumeGroupId = */0,
|
||||
addCarVolumeListItem(mDefaultVolumeItem, /* volumeGroupId = */0,
|
||||
R.drawable.car_ic_keyboard_arrow_down, new ExpandIconListener()
|
||||
);
|
||||
}
|
||||
|
||||
public CarVolumeDialogImpl(Context context) {
|
||||
mContext = new ContextThemeWrapper(context, com.android.systemui.R.style.qs_theme);
|
||||
mContext = context;
|
||||
mKeyguard = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
|
||||
mCar = Car.createCar(mContext, mServiceConnection);
|
||||
}
|
||||
@@ -238,7 +231,7 @@ public class CarVolumeDialogImpl implements VolumeDialog {
|
||||
|
||||
private void initDialog() {
|
||||
loadAudioUsageItems();
|
||||
mVolumeLineItems.clear();
|
||||
mCarVolumeLineItems.clear();
|
||||
mDialog = new CustomDialog(mContext);
|
||||
|
||||
mHovering = false;
|
||||
@@ -246,7 +239,6 @@ public class CarVolumeDialogImpl implements VolumeDialog {
|
||||
mExpanded = false;
|
||||
mWindow = mDialog.getWindow();
|
||||
mWindow.requestFeature(Window.FEATURE_NO_TITLE);
|
||||
mWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
|
||||
mWindow.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND
|
||||
| WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR);
|
||||
mWindow.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
|
||||
@@ -263,10 +255,11 @@ public class CarVolumeDialogImpl implements VolumeDialog {
|
||||
lp.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
|
||||
lp.windowAnimations = -1;
|
||||
mWindow.setAttributes(lp);
|
||||
mWindow.setLayout(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||
|
||||
mDialog.setContentView(R.layout.car_volume_dialog);
|
||||
mWindow.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||
|
||||
mDialog.setCanceledOnTouchOutside(true);
|
||||
mDialog.setContentView(R.layout.car_volume_dialog);
|
||||
mDialog.setOnShowListener(dialog -> {
|
||||
mListView.setTranslationY(-mListView.getHeight());
|
||||
mListView.setAlpha(0);
|
||||
@@ -277,7 +270,7 @@ public class CarVolumeDialogImpl implements VolumeDialog {
|
||||
.setInterpolator(new SystemUIInterpolators.LogDecelerateInterpolator())
|
||||
.start();
|
||||
});
|
||||
mListView = (PagedListView) mWindow.findViewById(R.id.volume_list);
|
||||
mListView = mWindow.findViewById(R.id.volume_list);
|
||||
mListView.setOnHoverListener((v, event) -> {
|
||||
int action = event.getActionMasked();
|
||||
mHovering = (action == MotionEvent.ACTION_HOVER_ENTER)
|
||||
@@ -286,10 +279,9 @@ public class CarVolumeDialogImpl implements VolumeDialog {
|
||||
return true;
|
||||
});
|
||||
|
||||
mPagedListAdapter = new ListItemAdapter(mContext, new ListProvider(mVolumeLineItems),
|
||||
BackgroundStyle.PANEL);
|
||||
mListView.setAdapter(mPagedListAdapter);
|
||||
mListView.setMaxPages(PagedListView.UNLIMITED_PAGES);
|
||||
mVolumeItemsAdapter = new CarVolumeItemAdapter(mContext, mCarVolumeLineItems);
|
||||
mListView.setAdapter(mVolumeItemsAdapter);
|
||||
mListView.setLayoutManager(new LinearLayoutManager(mContext));
|
||||
}
|
||||
|
||||
|
||||
@@ -302,13 +294,13 @@ public class CarVolumeDialogImpl implements VolumeDialog {
|
||||
mHandler.removeMessages(H.DISMISS);
|
||||
rescheduleTimeoutH();
|
||||
// Refresh the data set before showing.
|
||||
mPagedListAdapter.notifyDataSetChanged();
|
||||
mVolumeItemsAdapter.notifyDataSetChanged();
|
||||
if (mShowing) {
|
||||
return;
|
||||
}
|
||||
mShowing = true;
|
||||
if (mVolumeLineItems.isEmpty()) {
|
||||
setupDefaultListItem();
|
||||
if (mCarVolumeLineItems.isEmpty()) {
|
||||
setupDefaultCarVolumeItem();
|
||||
}
|
||||
mDialog.show();
|
||||
Events.writeEvent(mContext, Events.EVENT_SHOW_DIALOG, reason, mKeyguard.isKeyguardLocked());
|
||||
@@ -421,40 +413,41 @@ public class CarVolumeDialogImpl implements VolumeDialog {
|
||||
return result;
|
||||
}
|
||||
|
||||
private SeekbarListItem addSeekbarListItem(VolumeItem volumeItem,
|
||||
int volumeGroupId,
|
||||
private CarVolumeItem addCarVolumeListItem(VolumeItem volumeItem, int volumeGroupId,
|
||||
int supplementalIconId,
|
||||
@Nullable View.OnClickListener supplementalIconOnClickListener) {
|
||||
SeekbarListItem listItem = new SeekbarListItem(mContext);
|
||||
listItem.setMax(getMaxSeekbarValue(mCarAudioManager, volumeGroupId));
|
||||
CarVolumeItem carVolumeItem = new CarVolumeItem();
|
||||
carVolumeItem.setMax(getMaxSeekbarValue(mCarAudioManager, volumeGroupId));
|
||||
int color = mContext.getResources().getColor(R.color.car_volume_dialog_tint);
|
||||
int progress = getSeekbarValue(mCarAudioManager, volumeGroupId);
|
||||
listItem.setProgress(progress);
|
||||
listItem.setOnSeekBarChangeListener(new CarVolumeDialogImpl
|
||||
.VolumeSeekBarChangeListener(volumeGroupId, mCarAudioManager));
|
||||
carVolumeItem.setProgress(progress);
|
||||
carVolumeItem.setOnSeekBarChangeListener(
|
||||
new CarVolumeDialogImpl.VolumeSeekBarChangeListener(volumeGroupId,
|
||||
mCarAudioManager));
|
||||
Drawable primaryIcon = mContext.getResources().getDrawable(volumeItem.icon);
|
||||
primaryIcon.mutate().setTint(color);
|
||||
listItem.setPrimaryActionIcon(primaryIcon);
|
||||
carVolumeItem.setPrimaryIcon(primaryIcon);
|
||||
if (supplementalIconId != 0) {
|
||||
Drawable supplementalIcon = mContext.getResources().getDrawable(supplementalIconId);
|
||||
supplementalIcon.mutate().setTint(color);
|
||||
listItem.setSupplementalIcon(supplementalIcon, true);
|
||||
listItem.setSupplementalIconListener(supplementalIconOnClickListener);
|
||||
carVolumeItem.setSupplementalIcon(supplementalIcon,
|
||||
/* showSupplementalIconDivider= */ true);
|
||||
carVolumeItem.setSupplementalIconListener(supplementalIconOnClickListener);
|
||||
} else {
|
||||
listItem.setSupplementalEmptyIcon(true);
|
||||
listItem.setSupplementalIconListener(null);
|
||||
carVolumeItem.setSupplementalIcon(/* drawable= */ null,
|
||||
/* showSupplementalIconDivider= */ false);
|
||||
}
|
||||
|
||||
mVolumeLineItems.add(listItem);
|
||||
volumeItem.listItem = listItem;
|
||||
mCarVolumeLineItems.add(carVolumeItem);
|
||||
volumeItem.carVolumeItem = carVolumeItem;
|
||||
volumeItem.progress = progress;
|
||||
return listItem;
|
||||
return carVolumeItem;
|
||||
}
|
||||
|
||||
private VolumeItem findVolumeItem(SeekbarListItem targetItem) {
|
||||
private VolumeItem findVolumeItem(CarVolumeItem targetItem) {
|
||||
for (int i = 0; i < mVolumeItems.size(); ++i) {
|
||||
VolumeItem volumeItem = mVolumeItems.valueAt(i);
|
||||
if (volumeItem.listItem == targetItem) {
|
||||
if (volumeItem.carVolumeItem == targetItem) {
|
||||
return volumeItem;
|
||||
}
|
||||
}
|
||||
@@ -463,7 +456,7 @@ public class CarVolumeDialogImpl implements VolumeDialog {
|
||||
|
||||
private void cleanupAudioManager() {
|
||||
mCarAudioManager.unregisterCarVolumeCallback(mVolumeChangeCallback);
|
||||
mVolumeLineItems.clear();
|
||||
mCarVolumeLineItems.clear();
|
||||
mCarAudioManager = null;
|
||||
}
|
||||
|
||||
@@ -474,8 +467,9 @@ public class CarVolumeDialogImpl implements VolumeDialog {
|
||||
|
||||
private int rank;
|
||||
private boolean defaultItem = false;
|
||||
private @DrawableRes int icon;
|
||||
private SeekbarListItem listItem;
|
||||
@DrawableRes
|
||||
private int icon;
|
||||
private CarVolumeItem carVolumeItem;
|
||||
private int progress;
|
||||
}
|
||||
|
||||
@@ -554,9 +548,9 @@ public class CarVolumeDialogImpl implements VolumeDialog {
|
||||
// Adding the items which are not coming from the default item.
|
||||
VolumeItem volumeItem = mAvailableVolumeItems.get(groupId);
|
||||
if (volumeItem.defaultItem) {
|
||||
updateDefaultVolumeItem(volumeItem.listItem);
|
||||
updateDefaultVolumeItem(volumeItem.carVolumeItem);
|
||||
} else {
|
||||
addSeekbarListItem(volumeItem, groupId, 0, null);
|
||||
addCarVolumeListItem(volumeItem, groupId, 0, null);
|
||||
}
|
||||
}
|
||||
inAnimator = AnimatorInflater.loadAnimator(
|
||||
@@ -564,14 +558,14 @@ public class CarVolumeDialogImpl implements VolumeDialog {
|
||||
|
||||
} else {
|
||||
// Only keeping the default stream if it is not expended.
|
||||
Iterator itr = mVolumeLineItems.iterator();
|
||||
Iterator itr = mCarVolumeLineItems.iterator();
|
||||
while (itr.hasNext()) {
|
||||
SeekbarListItem seekbarListItem = (SeekbarListItem) itr.next();
|
||||
VolumeItem volumeItem = findVolumeItem(seekbarListItem);
|
||||
CarVolumeItem carVolumeItem = (CarVolumeItem) itr.next();
|
||||
VolumeItem volumeItem = findVolumeItem(carVolumeItem);
|
||||
if (!volumeItem.defaultItem) {
|
||||
itr.remove();
|
||||
} else {
|
||||
updateDefaultVolumeItem(seekbarListItem);
|
||||
updateDefaultVolumeItem(carVolumeItem);
|
||||
}
|
||||
}
|
||||
inAnimator = AnimatorInflater.loadAnimator(
|
||||
@@ -590,22 +584,22 @@ public class CarVolumeDialogImpl implements VolumeDialog {
|
||||
}
|
||||
animators.setTarget(mExpandIcon);
|
||||
animators.start();
|
||||
mPagedListAdapter.notifyDataSetChanged();
|
||||
mVolumeItemsAdapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
private void updateDefaultVolumeItem(SeekbarListItem seekbarListItem){
|
||||
VolumeItem volumeItem = findVolumeItem(seekbarListItem);
|
||||
private void updateDefaultVolumeItem(CarVolumeItem carVolumeItem) {
|
||||
VolumeItem volumeItem = findVolumeItem(carVolumeItem);
|
||||
|
||||
// When volume dialog is expanded or collapsed the default list item is never
|
||||
// reset. Whereas all other list items are removed when the dialog is collapsed and then
|
||||
// added when the dialog is expanded using {@link CarVolumeDialogImpl#addSeekbarListItem}.
|
||||
// added when the dialog is expanded using {@link CarVolumeDialogImpl#addCarVolumeListItem}.
|
||||
// This sets the progressbar and the tint color of icons for all items other than default
|
||||
// if they were changed. For default list item it should be done manually here.
|
||||
int color = mContext.getResources().getColor(R.color.car_volume_dialog_tint);
|
||||
Drawable primaryIcon = mContext.getResources().getDrawable(volumeItem.icon);
|
||||
primaryIcon.mutate().setTint(color);
|
||||
volumeItem.listItem.setPrimaryActionIcon(primaryIcon);
|
||||
volumeItem.listItem.setProgress(volumeItem.progress);
|
||||
volumeItem.carVolumeItem.setPrimaryIcon(primaryIcon);
|
||||
volumeItem.carVolumeItem.setProgress(volumeItem.progress);
|
||||
}
|
||||
|
||||
private final class VolumeSeekBarChangeListener implements OnSeekBarChangeListener {
|
||||
@@ -646,4 +640,4 @@ public class CarVolumeDialogImpl implements VolumeDialog {
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* 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.systemui.volume;
|
||||
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.SeekBar;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.android.systemui.R;
|
||||
|
||||
/** Holds all related data to represent a volume group. */
|
||||
public class CarVolumeItem {
|
||||
|
||||
private boolean mIsDirty;
|
||||
|
||||
private Drawable mPrimaryIcon;
|
||||
private Drawable mSupplementalIcon;
|
||||
private View.OnClickListener mSupplementalIconOnClickListener;
|
||||
private boolean mShowSupplementalIconDivider;
|
||||
|
||||
private int mMax;
|
||||
private int mProgress;
|
||||
private SeekBar.OnSeekBarChangeListener mOnSeekBarChangeListener;
|
||||
|
||||
public CarVolumeItem() {
|
||||
mIsDirty = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when {@link CarVolumeItem} is bound to its ViewHolder.
|
||||
*/
|
||||
void bind(CarVolumeItemViewHolder viewHolder) {
|
||||
if (mIsDirty) {
|
||||
viewHolder.bind(/* carVolumeItem= */ this);
|
||||
mIsDirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
/** Sets progress of seekbar. */
|
||||
public void setProgress(int progress) {
|
||||
mProgress = progress;
|
||||
mIsDirty = true;
|
||||
}
|
||||
|
||||
/** Sets max value of seekbar. */
|
||||
public void setMax(int max) {
|
||||
mMax = max;
|
||||
mIsDirty = true;
|
||||
}
|
||||
|
||||
/** Sets {@link SeekBar.OnSeekBarChangeListener}. */
|
||||
public void setOnSeekBarChangeListener(SeekBar.OnSeekBarChangeListener listener) {
|
||||
mOnSeekBarChangeListener = listener;
|
||||
mIsDirty = true;
|
||||
}
|
||||
|
||||
/** Sets the primary icon. */
|
||||
public void setPrimaryIcon(Drawable drawable) {
|
||||
mPrimaryIcon = drawable;
|
||||
mIsDirty = true;
|
||||
}
|
||||
|
||||
/** Sets the supplemental icon and the visibility of the supplemental icon divider. */
|
||||
public void setSupplementalIcon(Drawable drawable, boolean showSupplementalIconDivider) {
|
||||
mSupplementalIcon = drawable;
|
||||
mShowSupplementalIconDivider = showSupplementalIconDivider;
|
||||
mIsDirty = true;
|
||||
}
|
||||
|
||||
/** Sets {@code OnClickListener} for the supplemental icon. */
|
||||
public void setSupplementalIconListener(View.OnClickListener listener) {
|
||||
mSupplementalIconOnClickListener = listener;
|
||||
mIsDirty = true;
|
||||
}
|
||||
|
||||
/** Defines the view holder which shows the information held by {@link CarVolumeItem}. */
|
||||
public static class CarVolumeItemViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
private SeekBar mSeekBar;
|
||||
private ImageView mPrimaryIcon;
|
||||
private View mSupplementalIconDivider;
|
||||
private ImageView mSupplementalIcon;
|
||||
|
||||
public CarVolumeItemViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
|
||||
mSeekBar = itemView.findViewById(R.id.seek_bar);
|
||||
mPrimaryIcon = itemView.findViewById(R.id.primary_icon);
|
||||
mSupplementalIcon = itemView.findViewById(R.id.supplemental_icon);
|
||||
mSupplementalIconDivider = itemView.findViewById(R.id.supplemental_icon_divider);
|
||||
}
|
||||
|
||||
/**
|
||||
* Binds {@link CarVolumeItem} to the {@link CarVolumeItemViewHolder}.
|
||||
*/
|
||||
void bind(CarVolumeItem carVolumeItem) {
|
||||
// Progress bar
|
||||
mSeekBar.setMax(carVolumeItem.mMax);
|
||||
mSeekBar.setProgress(carVolumeItem.mProgress);
|
||||
mSeekBar.setOnSeekBarChangeListener(carVolumeItem.mOnSeekBarChangeListener);
|
||||
|
||||
// Primary icon
|
||||
mPrimaryIcon.setVisibility(View.VISIBLE);
|
||||
mPrimaryIcon.setImageDrawable(carVolumeItem.mPrimaryIcon);
|
||||
|
||||
// Supplemental icon
|
||||
mSupplementalIcon.setVisibility(View.VISIBLE);
|
||||
mSupplementalIconDivider.setVisibility(
|
||||
carVolumeItem.mShowSupplementalIconDivider ? View.VISIBLE : View.INVISIBLE);
|
||||
mSupplementalIcon.setImageDrawable(carVolumeItem.mSupplementalIcon);
|
||||
mSupplementalIcon.setOnClickListener(
|
||||
carVolumeItem.mSupplementalIconOnClickListener);
|
||||
mSupplementalIcon.setClickable(
|
||||
carVolumeItem.mSupplementalIconOnClickListener != null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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.systemui.volume;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.android.systemui.R;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/** The {@link RecyclerView.Adapter} to show the volume items in the sysUI volume dialog. */
|
||||
public class CarVolumeItemAdapter extends
|
||||
RecyclerView.Adapter<CarVolumeItem.CarVolumeItemViewHolder> {
|
||||
|
||||
private final Context mContext;
|
||||
private final List<CarVolumeItem> mItems;
|
||||
|
||||
public CarVolumeItemAdapter(Context context, List<CarVolumeItem> items) {
|
||||
mContext = context;
|
||||
mItems = items;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CarVolumeItem.CarVolumeItemViewHolder onCreateViewHolder(ViewGroup parent,
|
||||
int viewType) {
|
||||
LayoutInflater inflater = LayoutInflater.from(mContext);
|
||||
View view = inflater.inflate(R.layout.car_volume_item, parent, false);
|
||||
return new CarVolumeItem.CarVolumeItemViewHolder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(CarVolumeItem.CarVolumeItemViewHolder holder, int position) {
|
||||
mItems.get(position).bind(holder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return mItems.size();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user