ListRowPresenter.java revision 8b068ddbbf22a246eab49ec25a2f7c3abfbdca51
1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 * in compliance with the License. You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software distributed under the License
10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 * or implied. See the License for the specific language governing permissions and limitations under
12 * the License.
13 */
14package android.support.v17.leanback.widget;
15
16import java.util.ArrayList;
17
18import android.support.v17.leanback.widget.Presenter.ViewHolder;
19import android.view.View;
20import android.view.ViewGroup;
21
22/**
23 * Presents a ListRow as a BrowseRowView.
24 * Optionally, {@link #setHoverCardPresenterSelector(PresenterSelector)} can be used to
25 * display a view for the currently focused list item below the rendered
26 * list. This view is known as a hover card.
27 */
28public class ListRowPresenter extends RowPresenter {
29
30    private static final String TAG = "ListRowPresenter";
31    private static final boolean DEBUG = false;
32
33    public static class ViewHolder extends RowPresenter.ViewHolder {
34        final ListRowPresenter mListRowPresenter;
35        final HorizontalGridView mGridView;
36        final ItemBridgeAdapter mItemBridgeAdapter = new ItemBridgeAdapter();
37        final HorizontalHoverCardSwitcher mHoverCardViewSwitcher = new HorizontalHoverCardSwitcher();
38
39        public ViewHolder(View rootView, HorizontalGridView gridView, ListRowPresenter p) {
40            super(rootView);
41            mGridView = gridView;
42            mListRowPresenter = p;
43        }
44
45        public final ListRowPresenter getListRowPresenter() {
46            return mListRowPresenter;
47        }
48
49        public final HorizontalGridView getGridView() {
50            return mGridView;
51        }
52    }
53
54    private PresenterSelector mHoverCardPresenterSelector;
55
56    @Override
57    protected void initializeRowViewHolder(RowPresenter.ViewHolder holder) {
58        super.initializeRowViewHolder(holder);
59        final ViewHolder rowViewHolder = (ViewHolder) holder;
60        FocusHighlightHelper.setupBrowseItemFocusHighlight(rowViewHolder.mItemBridgeAdapter);
61        rowViewHolder.mGridView.setOnChildSelectedListener(
62                new OnChildSelectedListener() {
63            @Override
64            public void onChildSelected(ViewGroup parent, View view, int position, long id) {
65                selectChildView(rowViewHolder, view);
66            }
67        });
68        if (getOnItemClickedListener() != null) {
69            // Only when having an OnItemClickListner, we will attach the OnClickListener.
70            rowViewHolder.mItemBridgeAdapter.setAdapterListener(
71                    new ItemBridgeAdapter.AdapterListener() {
72                @Override
73                public void onCreate(ItemBridgeAdapter.ViewHolder viewHolder) {
74                    viewHolder.mHolder.view.setOnClickListener(new View.OnClickListener() {
75                        @Override
76                        public void onClick(View v) {
77                            ItemBridgeAdapter.ViewHolder ibh = (ItemBridgeAdapter.ViewHolder)
78                                    rowViewHolder.mGridView.getChildViewHolder(v);
79                            if (getOnItemClickedListener() != null) {
80                                getOnItemClickedListener().onItemClicked(ibh.mItem,
81                                        (ListRow) rowViewHolder.mRow);
82                            }
83                        }
84                    });
85                }
86            });
87        }
88    }
89
90    /**
91     * Set {@link PresenterSelector} used for showing a select object in a hover card.
92     */
93    public final void setHoverCardPresenterSelector(PresenterSelector selector) {
94        mHoverCardPresenterSelector = selector;
95    }
96
97    /**
98     * Get {@link PresenterSelector} used for showing a select object in a hover card.
99     */
100    public final PresenterSelector getHoverCardPresenterSelector() {
101        return mHoverCardPresenterSelector;
102    }
103
104    /*
105     * Perform operations when a child of horizontal grid view is selected.
106     */
107    private void selectChildView(ViewHolder rowViewHolder, View view) {
108        ItemBridgeAdapter.ViewHolder ibh = null;
109        if (view != null) {
110            ibh = (ItemBridgeAdapter.ViewHolder)
111                    rowViewHolder.mGridView.getChildViewHolder(view);
112        }
113        if (view == null) {
114            if (mHoverCardPresenterSelector != null) {
115                rowViewHolder.mHoverCardViewSwitcher.unselect();
116            }
117            if (getOnItemSelectedListener() != null) {
118                getOnItemSelectedListener().onItemSelected(null, rowViewHolder.mRow);
119            }
120        } else if (rowViewHolder.mExpanded && rowViewHolder.mSelected) {
121            if (mHoverCardPresenterSelector != null) {
122                rowViewHolder.mHoverCardViewSwitcher.select(rowViewHolder.mGridView, view,
123                        ibh.mItem);
124            }
125            if (getOnItemSelectedListener() != null) {
126                getOnItemSelectedListener().onItemSelected(ibh.mItem, rowViewHolder.mRow);
127            }
128        }
129    }
130
131    @Override
132    protected RowPresenter.ViewHolder createRowViewHolder(ViewGroup parent) {
133        BrowseRowView rowView = new BrowseRowView(parent.getContext());
134        return new ViewHolder(rowView, rowView.getGridView(), this);
135    }
136
137    @Override
138    protected void onRowViewSelected(RowPresenter.ViewHolder holder, boolean selected) {
139        updateFooterViewSwitcher((ViewHolder) holder);
140        updateInitialChildSelection((ViewHolder) holder);
141    }
142
143    /*
144     * Show or hide hover card when row selection or expanded state is changed.
145     */
146    private void updateFooterViewSwitcher(ViewHolder vh) {
147        if (vh.mExpanded && vh.mSelected) {
148            if (mHoverCardPresenterSelector != null) {
149                vh.mHoverCardViewSwitcher.init((ViewGroup) vh.view,
150                        mHoverCardPresenterSelector);
151            }
152        } else {
153            if (mHoverCardPresenterSelector != null) {
154                vh.mHoverCardViewSwitcher.clear();
155            }
156        }
157    }
158
159    /*
160     * Make initial child selection when row selection state is changed.
161     */
162    private void updateInitialChildSelection(ViewHolder vh) {
163        if (vh.mExpanded && vh.mSelected) {
164            ItemBridgeAdapter.ViewHolder ibh = (ItemBridgeAdapter.ViewHolder)
165                    vh.mGridView.findViewHolderForPosition(
166                            vh.mGridView.getSelectedPosition());
167            selectChildView(vh, ibh == null ? null : ibh.mHolder.view);
168        } else {
169            selectChildView(vh, null);
170        }
171    }
172
173    @Override
174    protected void onRowViewExpanded(RowPresenter.ViewHolder holder, boolean expanded) {
175        super.onRowViewExpanded(holder, expanded);
176        ViewHolder vh = (ViewHolder) holder;
177        vh.mGridView.setClipToPadding(!expanded);
178        updateFooterViewSwitcher(vh);
179    }
180
181    @Override
182    public void onBindViewHolder(Presenter.ViewHolder holder, Object item) {
183        super.onBindViewHolder(holder, item);
184        ViewHolder vh = (ViewHolder)holder;
185        ListRow rowItem = (ListRow) item;
186        vh.mItemBridgeAdapter.clear();
187        vh.mItemBridgeAdapter.setAdapter(rowItem.getAdapter());
188        vh.mGridView.setAdapter(vh.mItemBridgeAdapter);
189    }
190
191    @Override
192    public void onUnbindViewHolder(Presenter.ViewHolder holder) {
193        ViewHolder vh = (ViewHolder)holder;
194        vh.mGridView.setAdapter(null);
195        super.onUnbindViewHolder(holder);
196    }
197
198}
199