1 /* 2 * Copyright (C) 2016 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.annotation.NonNull; 20 import android.content.Context; 21 import android.graphics.drawable.GradientDrawable; 22 import android.hardware.radio.ProgramSelector; 23 import android.support.v7.widget.RecyclerView; 24 import android.util.Log; 25 import android.view.View; 26 import android.widget.ImageButton; 27 import android.widget.TextView; 28 29 import com.android.car.broadcastradio.support.Program; 30 import com.android.car.broadcastradio.support.platform.ProgramSelectorExt; 31 import com.android.car.view.CardListBackgroundResolver; 32 33 import java.util.Objects; 34 35 /** 36 * A {@link RecyclerView.ViewHolder} that can bind a {@link Program} to the layout 37 * {@code R.layout.radio_preset_item}. 38 */ 39 public class PresetsViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { 40 private static final String TAG = "Em.PresetVH"; 41 42 private final RadioChannelColorMapper mColorMapper; 43 44 private final OnPresetClickListener mPresetClickListener; 45 private final OnPresetFavoriteListener mPresetFavoriteListener; 46 47 private final Context mContext; 48 private final View mPresetsCard; 49 private GradientDrawable mPresetItemChannelBg; 50 private final TextView mPresetItemChannel; 51 private final TextView mPresetItemMetadata; 52 private ImageButton mPresetButton; 53 54 /** 55 * Interface for a listener when the View held by this ViewHolder has been clicked. 56 */ 57 public interface OnPresetClickListener { 58 /** 59 * Method to be called when the View in this ViewHolder has been clicked. 60 * 61 * @param position The position of the View within the RecyclerView this ViewHolder is 62 * populating. 63 */ onPresetClicked(int position)64 void onPresetClicked(int position); 65 } 66 67 68 /** 69 * Interface for a listener that will be notified when a favorite in the presets list has been 70 * toggled. 71 */ 72 public interface OnPresetFavoriteListener { 73 74 /** 75 * Method called when an item's favorite status has been toggled 76 */ onPresetFavoriteChanged(int position, boolean saveAsFavorite)77 void onPresetFavoriteChanged(int position, boolean saveAsFavorite); 78 } 79 80 81 /** 82 * @param presetsView A view that contains the layout {@code R.layout.radio_preset_item}. 83 */ PresetsViewHolder(@onNull View presetsView, @NonNull OnPresetClickListener listener, @NonNull OnPresetFavoriteListener favoriteListener)84 public PresetsViewHolder(@NonNull View presetsView, @NonNull OnPresetClickListener listener, 85 @NonNull OnPresetFavoriteListener favoriteListener) { 86 super(presetsView); 87 88 mContext = presetsView.getContext(); 89 90 mPresetsCard = presetsView.findViewById(R.id.preset_card);; 91 mPresetsCard.setOnClickListener(this); 92 93 mColorMapper = RadioChannelColorMapper.getInstance(mContext); 94 mPresetClickListener = Objects.requireNonNull(listener); 95 mPresetFavoriteListener = Objects.requireNonNull(favoriteListener); 96 97 mPresetItemChannel = presetsView.findViewById(R.id.preset_station_channel); 98 mPresetItemMetadata = presetsView.findViewById(R.id.preset_item_metadata); 99 mPresetButton = presetsView.findViewById(R.id.preset_button); 100 101 mPresetItemChannelBg = (GradientDrawable) 102 presetsView.findViewById(R.id.preset_station_background).getBackground(); 103 } 104 105 @Override onClick(View view)106 public void onClick(View view) { 107 if (Log.isLoggable(TAG, Log.DEBUG)) { 108 Log.d(TAG, "onClick() for view at position: " + getAdapterPosition()); 109 } 110 111 mPresetClickListener.onPresetClicked(getAdapterPosition()); 112 } 113 114 /** 115 * Binds the given {@link Program} to this View within this ViewHolder. 116 */ bindPreset(Program program, boolean isActiveStation, int itemCount, boolean isFavorite)117 public void bindPreset(Program program, boolean isActiveStation, int itemCount, 118 boolean isFavorite) { 119 // If the preset is null, clear any existing text. 120 if (program == null) { 121 mPresetItemChannel.setText(null); 122 mPresetItemMetadata.setText(null); 123 mPresetItemChannelBg.setColor(mColorMapper.getDefaultColor()); 124 return; 125 } 126 127 ProgramSelector sel = program.getSelector(); 128 129 CardListBackgroundResolver.setBackground(mPresetsCard, getAdapterPosition(), itemCount); 130 131 mPresetItemChannel.setText(ProgramSelectorExt.getDisplayName( 132 sel, ProgramSelectorExt.NAME_NO_MODULATION)); 133 if (isActiveStation) { 134 mPresetItemChannel.setCompoundDrawablesRelativeWithIntrinsicBounds( 135 R.drawable.ic_equalizer, 0, 0, 0); 136 } else { 137 mPresetItemChannel.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, 0, 0); 138 } 139 140 mPresetItemChannelBg.setColor(mColorMapper.getColorForProgram(sel)); 141 142 String programName = program.getName(); 143 if (programName.isEmpty()) { 144 // If there is no metadata text, then use text to indicate the favorite number to the 145 // user so that list does not appear empty. 146 mPresetItemMetadata.setText(mContext.getString( 147 R.string.radio_default_preset_metadata_text, getAdapterPosition() + 1)); 148 } else { 149 mPresetItemMetadata.setText(programName); 150 } 151 setFavoriteButtonFilled(isFavorite); 152 mPresetButton.setOnClickListener(v -> { 153 boolean favoriteToggleOn = 154 ((Integer) mPresetButton.getTag() == R.drawable.ic_star_empty); 155 setFavoriteButtonFilled(favoriteToggleOn); 156 mPresetFavoriteListener.onPresetFavoriteChanged(getAdapterPosition(), favoriteToggleOn); 157 }); 158 } 159 setFavoriteButtonFilled(boolean favoriteToggleOn)160 private void setFavoriteButtonFilled(boolean favoriteToggleOn) { 161 if (favoriteToggleOn) { 162 mPresetButton.setImageResource(R.drawable.ic_star_filled); 163 mPresetButton.setTag(R.drawable.ic_star_filled); 164 } else { 165 mPresetButton.setImageResource(R.drawable.ic_star_empty); 166 mPresetButton.setTag(R.drawable.ic_star_empty); 167 } 168 } 169 } 170