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 17package com.android.car.radio; 18 19import android.annotation.Nullable; 20import android.hardware.radio.ProgramSelector; 21import android.support.v7.widget.RecyclerView; 22import android.util.Log; 23import android.view.LayoutInflater; 24import android.view.View; 25import android.view.ViewGroup; 26 27import androidx.car.widget.PagedListView; 28 29import com.android.car.broadcastradio.support.Program; 30 31import java.util.List; 32import java.util.Objects; 33 34/** 35 * Adapter that will display a list of radio stations that represent the user's presets. 36 */ 37public class PresetsAdapter extends RecyclerView.Adapter<PresetsViewHolder> 38 implements PagedListView.ItemCap { 39 private static final String TAG = "Em.PresetsAdapter"; 40 41 // Only one type of view in this adapter. 42 private static final int PRESETS_VIEW_TYPE = 0; 43 44 private Program mActiveProgram; 45 46 private List<Program> mPresets; 47 private OnPresetItemClickListener mPresetClickListener; 48 private OnPresetItemFavoriteListener mPresetFavoriteListener; 49 50 /** 51 * Interface for a listener that will be notified when an item in the presets list has been 52 * clicked. 53 */ 54 public interface OnPresetItemClickListener { 55 /** 56 * Method called when an item in the preset list has been clicked. 57 * 58 * @param selector The {@link ProgramSelector} corresponding to the clicked preset. 59 */ 60 void onPresetItemClicked(ProgramSelector selector); 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 OnPresetItemFavoriteListener { 68 69 /** 70 * Method called when an item's favorite status has been toggled 71 * 72 * @param program The {@link Program} corresponding to the clicked preset. 73 * @param saveAsFavorite Whether the program should be saved or removed as a favorite. 74 */ 75 void onPresetItemFavoriteChanged(Program program, boolean saveAsFavorite); 76 } 77 78 /** 79 * Set a listener to be notified whenever a preset card is pressed. 80 */ 81 public void setOnPresetItemClickListener(@Nullable OnPresetItemClickListener listener) { 82 mPresetClickListener = Objects.requireNonNull(listener); 83 } 84 85 /** 86 * Set a listener to be notified whenever a preset favorite is changed. 87 */ 88 public void setOnPresetItemFavoriteListener(@Nullable OnPresetItemFavoriteListener listener) { 89 mPresetFavoriteListener = listener; 90 } 91 92 /** 93 * Sets the given list as the list of presets to display. 94 */ 95 public void setPresets(List<Program> presets) { 96 mPresets = presets; 97 notifyDataSetChanged(); 98 } 99 100 /** 101 * Indicates which radio station is the active one inside the list of presets that are set on 102 * this adapter. This will cause that station to be highlighted in the list. If the station 103 * passed to this method does not match any of the presets, then none will be highlighted. 104 */ 105 public void setActiveProgram(Program program) { 106 mActiveProgram = program; 107 notifyDataSetChanged(); 108 } 109 110 @Override 111 public PresetsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 112 View view = LayoutInflater.from(parent.getContext()) 113 .inflate(R.layout.radio_preset_stream_card, parent, false); 114 115 return new PresetsViewHolder( 116 view, this::handlePresetClicked, this::handlePresetFavoriteChanged); 117 } 118 119 @Override 120 public void onBindViewHolder(PresetsViewHolder holder, int position) { 121 if (getPresetCount() == 0) { 122 holder.bindPreset(mActiveProgram, true, getItemCount(), false); 123 return; 124 } 125 Program station = mPresets.get(position); 126 boolean isActiveStation = station.getSelector().equals(mActiveProgram.getSelector()); 127 holder.bindPreset(station, isActiveStation, getItemCount(), true); 128 } 129 130 @Override 131 public int getItemViewType(int position) { 132 return PRESETS_VIEW_TYPE; 133 } 134 135 @Override 136 public int getItemCount() { 137 int numPresets = getPresetCount(); 138 return (numPresets == 0) ? 1 : numPresets; 139 } 140 141 private int getPresetCount() { 142 return (mPresets == null) ? 0 : mPresets.size(); 143 } 144 145 @Override 146 public void setMaxItems(int max) { 147 // No-op. A PagedListView needs the ItemCap interface to be implemented. However, the 148 // list of presets should not be limited. 149 } 150 151 private void handlePresetClicked(int position) { 152 if (Log.isLoggable(TAG, Log.VERBOSE)) { 153 Log.v(TAG, String.format("onPresetClicked(); item count: %d; position: %d", 154 getItemCount(), position)); 155 } 156 if (mPresetClickListener != null && getItemCount() > position) { 157 if (getPresetCount() == 0) { 158 mPresetClickListener.onPresetItemClicked(mActiveProgram.getSelector()); 159 return; 160 } 161 mPresetClickListener.onPresetItemClicked(mPresets.get(position).getSelector()); 162 } 163 } 164 165 private void handlePresetFavoriteChanged (int position, boolean saveAsFavorite) { 166 if (mPresetFavoriteListener != null && getItemCount() > position) { 167 if (getPresetCount() == 0) { 168 mPresetFavoriteListener.onPresetItemFavoriteChanged(mActiveProgram, saveAsFavorite); 169 return; 170 } 171 mPresetFavoriteListener.onPresetItemFavoriteChanged( 172 mPresets.get(position), saveAsFavorite); 173 } 174 } 175} 176