From 816a4be1a0f34f6a48877c8afd3dbbca19eac435 Mon Sep 17 00:00:00 2001 From: Nick Chalko Date: Mon, 3 Aug 2015 15:39:56 -0700 Subject: Migrate Live Channels App Src to AOSP branch Bug: 21625152 Change-Id: I07e2830b27440556dc757e6340b4f77d1c0cbc66 --- src/com/android/tv/menu/ItemListRowView.java | 215 +++++++++++++++++++++++++++ 1 file changed, 215 insertions(+) create mode 100644 src/com/android/tv/menu/ItemListRowView.java (limited to 'src/com/android/tv/menu/ItemListRowView.java') diff --git a/src/com/android/tv/menu/ItemListRowView.java b/src/com/android/tv/menu/ItemListRowView.java new file mode 100644 index 00000000..e9362a78 --- /dev/null +++ b/src/com/android/tv/menu/ItemListRowView.java @@ -0,0 +1,215 @@ +/* + * Copyright (C) 2015 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.tv.menu; + +import android.content.Context; +import android.support.v17.leanback.widget.HorizontalGridView; +import android.support.v17.leanback.widget.OnChildSelectedListener; +import android.support.v7.widget.RecyclerView; +import android.util.AttributeSet; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import com.android.tv.MainActivity; +import com.android.tv.R; + +import java.util.Collections; +import java.util.List; + +/** + * A view that shows a title and list view. + */ +public class ItemListRowView extends MenuRowView implements OnChildSelectedListener { + private static final String TAG = MenuView.TAG; + private static final boolean DEBUG = MenuView.DEBUG; + + public interface CardView { + void onBind(T row, boolean selected); + void onSelected(); + void onDeselected(); + } + + private HorizontalGridView mListView; + private CardView mSelectedCard; + + public ItemListRowView(Context context) { + this(context, null); + } + + public ItemListRowView(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public ItemListRowView(Context context, AttributeSet attrs, int defStyle) { + this(context, attrs, defStyle, 0); + } + + public ItemListRowView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + } + + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + mListView = (HorizontalGridView) getContentsView(); + } + + @Override + protected int getContentsViewId() { + return R.id.list_view; + } + + @Override + public void onBind(MenuRow row) { + super.onBind(row); + ItemListAdapter adapter = ((ItemListRow) row).getAdapter(); + adapter.mItemListView = this; + + mListView.setOnChildSelectedListener(this); + mListView.setAdapter(adapter); + } + + @Override + public void initialize(int reason) { + super.initialize(reason); + setInitialFocusView(mListView); + mListView.setSelectedPosition(getAdapter().getInitialPosition()); + } + + private ItemListAdapter getAdapter() { + return (ItemListAdapter) mListView.getAdapter(); + } + + @Override + public void onChildSelected(ViewGroup parent, View child, int position, long id) { + if (DEBUG) Log.d(TAG, "onChildSelected: child=" + child); + if (mSelectedCard == child) { + return; + } + if (mSelectedCard != null) { + mSelectedCard.onDeselected(); + } + mSelectedCard = (CardView) child; + if (mSelectedCard != null) { + mSelectedCard.onSelected(); + } + } + + public static abstract class ItemListAdapter + extends RecyclerView.Adapter { + private final MainActivity mMainActivity; + private final LayoutInflater mLayoutInflater; + private List mItemList = Collections.emptyList(); + private ItemListRowView mItemListView; + + public ItemListAdapter(Context context) { + // Only MainActivity can use the main menu. + mMainActivity = (MainActivity) context; + mLayoutInflater = LayoutInflater.from(context); + } + + /** + * In most cases, implementation should call {@link #setItemList(java.util.List)} with + * newly update item list. + */ + public abstract void update(); + + /** + * Gets layout resource ID. It'll be used in {@link #onCreateViewHolder}. + */ + protected abstract int getLayoutResId(int viewType); + + /** + * Releases all the resources which need to be released. + */ + public void release() { + } + + /** + * The initial position of list that will be selected when the main menu appears. + * By default, the first item is initially selected. + */ + public int getInitialPosition() { + return 0; + } + + /** The MainActivity that the corresponding ItemListView belongs to. */ + protected MainActivity getMainActivity() { + return mMainActivity; + } + + /** The item list. */ + protected List getItemList() { + return mItemList; + } + + /** + * Sets the item list. + * + *

This sends an item change event, not a structural change event. The items of the same + * positions retain the same identity. + * + *

If there's any structural change and relayout and rebind is needed, call + * {@link #notifyDataSetChanged} explicitly. + */ + protected void setItemList(List itemList) { + int oldSize = mItemList.size(); + int newSize = itemList.size(); + mItemList = itemList; + if (oldSize > newSize) { + notifyItemRangeChanged(0, newSize); + notifyItemRangeRemoved(newSize, oldSize - newSize); + } else if (oldSize < newSize) { + notifyItemRangeChanged(0, oldSize); + notifyItemRangeInserted(oldSize, newSize - oldSize); + } else { + notifyItemRangeChanged(0, oldSize); + } + } + + @Override + public int getItemViewType(int position) { + return 0; + } + + @Override + public int getItemCount() { + return mItemList.size(); + } + + @Override + public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + View view = mLayoutInflater.inflate(getLayoutResId(viewType), parent, false); + return new MyViewHolder(view); + } + + @Override + public void onBindViewHolder(MyViewHolder viewHolder, int position) { + @SuppressWarnings("unchecked") + CardView cardView = (CardView) viewHolder.itemView; + cardView.onBind(mItemList.get(position), cardView.equals(mItemListView.mSelectedCard)); + } + + public static class MyViewHolder extends RecyclerView.ViewHolder { + public MyViewHolder(View view) { + super(view); + } + } + } +} -- cgit v1.2.3