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