aboutsummaryrefslogtreecommitdiff
path: root/src/com/android/tv/menu/ChannelsRowAdapter.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/tv/menu/ChannelsRowAdapter.java')
-rw-r--r--src/com/android/tv/menu/ChannelsRowAdapter.java198
1 files changed, 137 insertions, 61 deletions
diff --git a/src/com/android/tv/menu/ChannelsRowAdapter.java b/src/com/android/tv/menu/ChannelsRowAdapter.java
index c8e1bd05..7ff44ea6 100644
--- a/src/com/android/tv/menu/ChannelsRowAdapter.java
+++ b/src/com/android/tv/menu/ChannelsRowAdapter.java
@@ -31,17 +31,15 @@ import com.android.tv.dvr.DvrDataManager;
import com.android.tv.recommendation.Recommender;
import com.android.tv.util.SetupUtils;
import com.android.tv.util.TvInputManagerHelper;
-import com.android.tv.util.Utils;
+import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.List;
/**
* An adapter of the Channels row.
*/
-public class ChannelsRowAdapter extends ItemListRowView.ItemListAdapter<Channel> {
- private static final String TAG = "ChannelsRowAdapter";
-
+public class ChannelsRowAdapter extends ItemListRowView.ItemListAdapter<ChannelsRowItem> {
// There are four special cards: guide, setup, dvr, applink.
private static final int SIZE_OF_VIEW_TYPE = 5;
@@ -51,7 +49,6 @@ public class ChannelsRowAdapter extends ItemListRowView.ItemListAdapter<Channel>
private final DvrDataManager mDvrDataManager;
private final int mMaxCount;
private final int mMinCount;
- private final int[] mViewType = new int[SIZE_OF_VIEW_TYPE];
private final View.OnClickListener mGuideOnClickListener = new View.OnClickListener() {
@Override
@@ -113,14 +110,12 @@ public class ChannelsRowAdapter extends ItemListRowView.ItemListAdapter<Channel>
mRecommender = recommender;
mMinCount = minCount;
mMaxCount = maxCount;
+ setHasStableIds(true);
}
@Override
public int getItemViewType(int position) {
- if (position >= SIZE_OF_VIEW_TYPE) {
- return R.layout.menu_card_channel;
- }
- return mViewType[position];
+ return getItemList().get(position).getLayoutId();
}
@Override
@@ -129,9 +124,12 @@ public class ChannelsRowAdapter extends ItemListRowView.ItemListAdapter<Channel>
}
@Override
- public void onBindViewHolder(MyViewHolder viewHolder, int position) {
- super.onBindViewHolder(viewHolder, position);
+ public long getItemId(int position) {
+ return getItemList().get(position).getItemId();
+ }
+ @Override
+ public void onBindViewHolder(MyViewHolder viewHolder, int position) {
int viewType = getItemViewType(position);
if (viewType == R.layout.menu_card_guide) {
viewHolder.itemView.setOnClickListener(mGuideOnClickListener);
@@ -144,80 +142,158 @@ public class ChannelsRowAdapter extends ItemListRowView.ItemListAdapter<Channel>
SimpleCardView view = (SimpleCardView) viewHolder.itemView;
view.setText(R.string.channels_item_dvr);
} else {
- viewHolder.itemView.setTag(getItemList().get(position));
+ viewHolder.itemView.setTag(getItemList().get(position).getChannel());
viewHolder.itemView.setOnClickListener(mChannelOnClickListener);
}
+ super.onBindViewHolder(viewHolder, position);
}
@Override
public void update() {
- List<Channel> channelList = new ArrayList<>();
- Channel dummyChannel = new Channel.Builder().build();
- // For guide item
- channelList.add(dummyChannel);
- // For setup item
- TvInputManagerHelper inputManager = TvApplication.getSingletons(mContext)
- .getTvInputManagerHelper();
- boolean showSetupCard = SetupUtils.getInstance(mContext).hasNewInput(inputManager);
- Channel currentChannel = getMainActivity().getCurrentChannel();
- boolean showAppLinkCard = currentChannel != null
- && currentChannel.getAppLinkType(mContext) != Channel.APP_LINK_TYPE_NONE
- // Sometimes applicationInfo can be null. b/28932537
- && inputManager.getTvInputAppInfo(currentChannel.getInputId()) != null;
- boolean showDvrCard = false;
+ if (getItemCount() == 0) {
+ createItems();
+ } else {
+ updateItems();
+ }
+ }
+
+ private void createItems() {
+ List<ChannelsRowItem> items = new ArrayList<>();
+ items.add(ChannelsRowItem.GUIDE_ITEM);
+ if (needToShowSetupItem()) {
+ items.add(ChannelsRowItem.SETUP_ITEM);
+ }
+ if (needToShowDvrItem()) {
+ items.add(ChannelsRowItem.DVR_ITEM);
+ }
+ if (needToShowAppLinkItem()) {
+ ChannelsRowItem.APP_LINK_ITEM.setChannel(
+ new Channel.Builder(getMainActivity().getCurrentChannel()).build());
+ items.add(ChannelsRowItem.APP_LINK_ITEM);
+ }
+ for (Channel channel : getRecentChannels()) {
+ items.add(new ChannelsRowItem(channel, R.layout.menu_card_channel));
+ }
+ setItemList(items);
+ }
+
+ private void updateItems() {
+ List<ChannelsRowItem> items = getItemList();
+ // The current index of the item list to iterate. It starts from 1 because the first item
+ // (GUIDE) is always visible and not updated.
+ int currentIndex = 1;
+ if (updateItem(needToShowSetupItem(), ChannelsRowItem.SETUP_ITEM, currentIndex)) {
+ ++currentIndex;
+ }
+ if (updateItem(needToShowDvrItem(), ChannelsRowItem.DVR_ITEM, currentIndex)) {
+ ++currentIndex;
+ }
+ if (updateItem(needToShowAppLinkItem(), ChannelsRowItem.APP_LINK_ITEM, currentIndex)) {
+ if (!getMainActivity().getCurrentChannel()
+ .hasSameReadOnlyInfo(ChannelsRowItem.APP_LINK_ITEM.getChannel())) {
+ ChannelsRowItem.APP_LINK_ITEM.setChannel(
+ new Channel.Builder(getMainActivity().getCurrentChannel()).build());
+ notifyItemChanged(currentIndex);
+ }
+ ++currentIndex;
+ }
+ int numOldChannels = items.size() - currentIndex;
+ if (numOldChannels > 0) {
+ while (items.size() > currentIndex) {
+ items.remove(items.size() - 1);
+ }
+ notifyItemRangeRemoved(currentIndex, numOldChannels);
+ }
+ for (Channel channel : getRecentChannels()) {
+ items.add(new ChannelsRowItem(channel, R.layout.menu_card_channel));
+ }
+ int numNewChannels = items.size() - currentIndex;
+ if (numNewChannels > 0) {
+ notifyItemRangeInserted(currentIndex, numNewChannels);
+ }
+ }
+
+ /**
+ * Returns {@code true} if the item should be shown.
+ */
+ private boolean updateItem(boolean needToShow, ChannelsRowItem item, int index) {
+ List<ChannelsRowItem> items = getItemList();
+ boolean isItemInList = index < items.size() && item.equals(items.get(index));
+ if (needToShow && !isItemInList) {
+ items.add(index, item);
+ notifyItemInserted(index);
+ } else if (!needToShow && isItemInList) {
+ items.remove(index);
+ notifyItemRemoved(index);
+ }
+ return needToShow;
+ }
+
+ private boolean needToShowSetupItem() {
+ TvInputManagerHelper inputManager =
+ TvApplication.getSingletons(mContext).getTvInputManagerHelper();
+ return SetupUtils.getInstance(mContext).hasNewInput(inputManager);
+ }
+
+ private boolean needToShowDvrItem() {
+ TvInputManagerHelper inputManager =
+ TvApplication.getSingletons(mContext).getTvInputManagerHelper();
if (mDvrDataManager != null) {
for (TvInputInfo info : inputManager.getTvInputInfos(true, true)) {
if (info.canRecord()) {
- showDvrCard = true;
- break;
+ return true;
}
}
}
+ return false;
+ }
- mViewType[0] = R.layout.menu_card_guide;
- int index = 1;
- if (showSetupCard) {
- channelList.add(dummyChannel);
- mViewType[index++] = R.layout.menu_card_setup;
- }
- if (showDvrCard) {
- channelList.add(dummyChannel);
- mViewType[index++] = R.layout.menu_card_dvr;
- }
- if (showAppLinkCard) {
- channelList.add(currentChannel);
- mViewType[index++] = R.layout.menu_card_app_link;
- }
- for ( ; index < mViewType.length; ++index) {
- mViewType[index] = R.layout.menu_card_channel;
- }
- channelList.addAll(getRecentChannels());
- setItemList(channelList);
+ private boolean needToShowAppLinkItem() {
+ TvInputManagerHelper inputManager =
+ TvApplication.getSingletons(mContext).getTvInputManagerHelper();
+ Channel currentChannel = getMainActivity().getCurrentChannel();
+ return currentChannel != null
+ && currentChannel.getAppLinkType(mContext) != Channel.APP_LINK_TYPE_NONE
+ // Sometimes applicationInfo can be null. b/28932537
+ && inputManager.getTvInputAppInfo(currentChannel.getInputId()) != null;
}
private List<Channel> getRecentChannels() {
List<Channel> channelList = new ArrayList<>();
+ long currentChannelId = getMainActivity().getCurrentChannelId();
+ ArrayDeque<Long> recentChannels = getMainActivity().getRecentChannels();
+ // Add the last watched channel as the first one.
+ for (long channelId : recentChannels) {
+ if (addChannelToList(
+ channelList, mRecommender.getChannel(channelId), currentChannelId)) {
+ break;
+ }
+ }
+ // Add the recommended channels.
for (Channel channel : mRecommender.recommendChannels(mMaxCount)) {
- if (channel.isBrowsable()) {
- channelList.add(channel);
+ if (channelList.size() >= mMaxCount) {
+ break;
}
+ addChannelToList(channelList, channel, currentChannelId);
}
- int count = channelList.size();
// If the number of recommended channels is not enough, add more from the recent channel
// list.
- if (count < mMinCount) {
- for (long channelId : getMainActivity().getRecentChannels()) {
- Channel channel = mRecommender.getChannel(channelId);
- if (channel == null || channelList.contains(channel)
- || !channel.isBrowsable()) {
- continue;
- }
- channelList.add(channel);
- if (++count >= mMinCount) {
- break;
- }
+ for (long channelId : recentChannels) {
+ if (channelList.size() >= mMinCount) {
+ break;
}
+ addChannelToList(channelList, mRecommender.getChannel(channelId), currentChannelId);
}
return channelList;
}
+
+ private static boolean addChannelToList(
+ List<Channel> channelList, Channel channel, long currentChannelId) {
+ if (channel == null || channel.getId() == currentChannelId
+ || channelList.contains(channel) || !channel.isBrowsable()) {
+ return false;
+ }
+ channelList.add(channel);
+ return true;
+ }
}