blob: 13a3e2144336ba27bbd6695edd56b725c5358983 [file] [log] [blame]
/*
* Copyright (C) 2016 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.car.radio;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.android.car.radio.service.RadioStation;
import java.util.List;
/**
* A {@link com.android.car.radio.CarouselView.Adapter} that supplies the views to be displayed
* from a list of {@link RadioStation}s.
*/
public class PrescannedRadioStationAdapter extends CarouselView.Adapter {
private static final String TAG = "PreScanAdapter";
private List<RadioStation> mStations;
private int mCurrentPosition;
/**
* Sets the {@link RadioStation}s that will be used to bind to the views to be displayed.
*/
public void setStations(List<RadioStation> stations) {
mStations = stations;
notifyDataSetChanged();
}
/**
* Sets the the station within the list passed to {@link #setStations(List)} that should be
* the first station displayed. A station is identified by the channel number and band.
*
* @return The index within the list of stations passed to {@link #setStations(List)} that the
* starting station can be found at.
*/
public int setStartingStation(int channelNumber, int band) {
getIndexOrInsertForStation(channelNumber, band);
return mCurrentPosition;
}
/**
* Returns the station that is currently the first station to be displayed. This value can be
* different from the value returned by {@link #setStartingStation(int, int)} if either
* {@link #getPrevStation()} or {@link #getNextStation()} have been called.
*/
public int getCurrentPosition() {
return mCurrentPosition;
}
/**
* Returns the previous station in the list based off the value returned by
* {@link #getCurrentPosition()}. After calling this method, the current position returned by
* that method will be the index of the {@link RadioStation} returned by this method.
*/
@Nullable
public RadioStation getPrevStation() {
if (mStations == null) {
return null;
}
if (--mCurrentPosition < 0) {
mCurrentPosition = mStations.size() - 1;
}
return mStations.get(mCurrentPosition);
}
/**
* Returns the next station in the list based off the value returned by
* {@link #getCurrentPosition()}. After calling this method, the current position returned by
* that method will be the index of the {@link RadioStation} returned by this method.
*/
@Nullable
public RadioStation getNextStation() {
if (mStations == null) {
return null;
}
if (++mCurrentPosition >= mStations.size()) {
mCurrentPosition = 0;
}
return mStations.get(mCurrentPosition);
}
/**
* Returns the index in the list set in {@link #setStations(List)} that corresponds to the
* given channel number and band. If the given combination does not exist within the list, then
* it will be inserted in ascending order.
*
* @return An index into the list or -1 if no list of stations has been set.
*/
public int getIndexOrInsertForStation(int channelNumber, int band) {
if (mStations == null) {
mCurrentPosition = -1;
return -1;
}
int indexToInsert = 0;
for (int i = 0, size = mStations.size(); i < size; i++) {
RadioStation station = mStations.get(i);
if (channelNumber >= station.getChannelNumber()) {
// Need to add 1 to the index because the channel should be inserted after it.
indexToInsert = i + 1;
}
if (station.getChannelNumber() == channelNumber && station.getRadioBand() == band) {
mCurrentPosition = i;
return i;
}
}
// If this path is reached, that means an exact match for the station was not found in
// the given list. Instead, insert the station into the list and return that index.
RadioStation stationToInsert = new RadioStation(channelNumber, 0 /* subChannel */,
band, null /* rds */);
mStations.add(indexToInsert, stationToInsert);
notifyDataSetChanged();
mCurrentPosition = indexToInsert;
return indexToInsert;
}
@Override
public View createView(ViewGroup parent) {
return LayoutInflater.from(parent.getContext()).inflate(R.layout.radio_channel, parent,
false);
}
@Override
public void bindView(View view, int position, boolean isFirstView) {
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "bindView(); position: " + position + "; isFirstView: " + isFirstView);
}
if (mStations == null || position >= mStations.size()) {
return;
}
TextView radioChannel = view.findViewById(R.id.radio_list_station_channel);
TextView radioBandView = view.findViewById(R.id.radio_list_station_band);
RadioStation station = mStations.get(position);
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "binding station: " + station);
}
int radioBand = station.getRadioBand();
radioChannel.setText(RadioChannelFormatter.formatRadioChannel(radioBand,
station.getChannelNumber()));
if (isFirstView) {
radioBandView.setText(RadioChannelFormatter.formatRadioBand(view.getContext(),
radioBand));
} else {
radioBandView.setText(null);
}
}
@Override
public int getItemCount() {
return mStations == null ? 0 : mStations.size();
}
}