1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.car.radio;
18 
19 import android.content.Context;
20 import android.graphics.drawable.GradientDrawable;
21 import android.hardware.radio.ProgramSelector;
22 import android.view.View;
23 import android.widget.ImageButton;
24 import android.widget.TextView;
25 
26 import androidx.annotation.NonNull;
27 import androidx.recyclerview.widget.RecyclerView;
28 
29 import com.android.car.broadcastradio.support.Program;
30 import com.android.car.broadcastradio.support.platform.ProgramSelectorExt;
31 
32 import java.util.Objects;
33 
34 /**
35  * A {@link RecyclerView.ViewHolder} that can bind a {@link Program} to the layout
36  * {@code R.layout.radio_favorite_item}.
37  */
38 public class ProgramViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
39     private final OnPresetClickListener mPresetClickListener;
40     private final OnPresetFavoriteListener mPresetFavoriteListener;
41 
42     private final Context mContext;
43     private final View mPresetsCard;
44     private GradientDrawable mPresetItemChannelBg;
45     private final TextView mPresetItemChannel;
46     private final TextView mPresetItemMetadata;
47     private ImageButton mPresetButton;
48 
49     /**
50      * Interface for a listener when the View held by this ViewHolder has been clicked.
51      */
52     public interface OnPresetClickListener {
53         /**
54          * Method to be called when the View in this ViewHolder has been clicked.
55          *
56          * @param position The position of the View within the RecyclerView this ViewHolder is
57          *                 populating.
58          */
onPresetClicked(int position)59         void onPresetClicked(int position);
60     }
61 
62 
63     /**
64      * Interface for a listener that will be notified when a favorite in the presets list has been
65      * toggled.
66      */
67     public interface OnPresetFavoriteListener {
68 
69         /**
70          * Method called when an item's favorite status has been toggled
71          */
onPresetFavoriteChanged(int position, boolean saveAsFavorite)72         void onPresetFavoriteChanged(int position, boolean saveAsFavorite);
73     }
74 
75 
76     /**
77      * @param presetsView A view that contains the layout {@code R.layout.radio_favorite_item}.
78      */
ProgramViewHolder(@onNull View presetsView, @NonNull OnPresetClickListener listener, @NonNull OnPresetFavoriteListener favoriteListener)79     public ProgramViewHolder(@NonNull View presetsView, @NonNull OnPresetClickListener listener,
80             @NonNull OnPresetFavoriteListener favoriteListener) {
81         super(presetsView);
82 
83         mContext = presetsView.getContext();
84 
85         mPresetsCard = presetsView.findViewById(R.id.browse_card);
86         mPresetsCard.setOnClickListener(this);
87 
88         mPresetClickListener = Objects.requireNonNull(listener);
89         mPresetFavoriteListener = Objects.requireNonNull(favoriteListener);
90 
91         mPresetItemChannel = presetsView.findViewById(R.id.browse_station_channel);
92         mPresetItemMetadata = presetsView.findViewById(R.id.browse_item_metadata);
93         mPresetButton = presetsView.findViewById(R.id.browse_button);
94 
95         mPresetItemChannelBg = (GradientDrawable)
96                 presetsView.findViewById(R.id.browse_station_background).getBackground();
97     }
98 
99     @Override
onClick(View view)100     public void onClick(View view) {
101         mPresetClickListener.onPresetClicked(getAdapterPosition());
102     }
103 
104     /**
105      * Binds the given {@link Program} to this View within this ViewHolder.
106      */
bindPreset(Program program, boolean isActiveStation, int itemCount, boolean isFavorite)107     public void bindPreset(Program program, boolean isActiveStation, int itemCount,
108             boolean isFavorite) {
109         // If the preset is null, clear any existing text.
110         if (program == null) {
111             mPresetItemChannel.setText(null);
112             mPresetItemMetadata.setText(null);
113             return;
114         }
115 
116         ProgramSelector sel = program.getSelector();
117         mPresetItemChannel.setText(ProgramSelectorExt.getDisplayName(
118                 sel, ProgramSelectorExt.NAME_NO_MODULATION));
119 
120         mPresetItemChannelBg.setColor(mContext.getResources().getColor(isActiveStation
121                 ? R.color.accent_color
122                 : R.color.radio_card_color, null));
123         mPresetItemChannel.setCompoundDrawablesRelativeWithIntrinsicBounds(isActiveStation
124                 ? R.drawable.ic_equalizer
125                 : 0, 0, 0, 0);
126 
127         String programName = program.getName();
128         if (programName.isEmpty()) {
129             // If there is no metadata text, then use text to indicate the favorite number to the
130             // user so that list does not appear empty.
131             mPresetItemMetadata.setText(mContext.getString(
132                     R.string.radio_default_favorite_metadata_text, getAdapterPosition() + 1));
133         } else {
134             mPresetItemMetadata.setText(programName);
135         }
136         setFavoriteButtonFilled(isFavorite);
137         mPresetButton.setOnClickListener(v -> {
138             boolean favoriteToggleOn =
139                     ((Integer) mPresetButton.getTag() == R.drawable.ic_star_empty);
140             setFavoriteButtonFilled(favoriteToggleOn);
141             mPresetFavoriteListener.onPresetFavoriteChanged(getAdapterPosition(), favoriteToggleOn);
142         });
143     }
144 
setFavoriteButtonFilled(boolean favoriteToggleOn)145     private void setFavoriteButtonFilled(boolean favoriteToggleOn) {
146         mPresetButton.setImageResource(favoriteToggleOn
147                 ? R.drawable.ic_star_filled
148                 : R.drawable.ic_star_empty);
149         mPresetButton.setTag(favoriteToggleOn
150                 ? R.drawable.ic_star_filled
151                 : R.drawable.ic_star_empty);
152         mPresetButton.setColorFilter(mContext.getColor(favoriteToggleOn
153                 ? R.color.accent_color
154                 : R.color.control_button_color));
155     }
156 }
157