ControlBarPresenter.java revision 7ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7
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 android.support.v17.leanback.R; 17import android.util.SparseArray; 18import android.view.LayoutInflater; 19import android.view.View; 20import android.view.ViewGroup; 21import android.widget.LinearLayout; 22 23/** 24 * A presenter that assumes a LinearLayout container for a series 25 * of control buttons backed by objects of type {@link Action}. 26 * 27 * Different layouts may be passed to the presenter constructor. 28 * The layout must contain a view with id control_bar. 29 */ 30class ControlBarPresenter extends Presenter { 31 32 private static final int MAX_CONTROLS = 7; 33 34 /** 35 * The data type expected by this presenter. 36 */ 37 static class BoundData { 38 /** 39 * Adapter containing objects of type {@link Action}. 40 */ 41 ObjectAdapter adapter; 42 43 /** 44 * The presenter to be used for the adapter objects. 45 */ 46 Presenter presenter; 47 } 48 49 /** 50 * A ViewHolder for an actions bar. 51 */ 52 class ViewHolder extends Presenter.ViewHolder { 53 ObjectAdapter mAdapter; 54 Presenter mPresenter; 55 LinearLayout mControlBar; 56 SparseArray<Presenter.ViewHolder> mViewHolders = 57 new SparseArray<Presenter.ViewHolder>(); 58 ObjectAdapter.DataObserver mDataObserver; 59 60 /** 61 * Constructor for the ViewHolder. 62 */ 63 ViewHolder(View rootView) { 64 super(rootView); 65 mControlBar = (LinearLayout) rootView.findViewById(R.id.control_bar); 66 if (mControlBar == null) { 67 throw new IllegalStateException("Couldn't find control_bar"); 68 } 69 mDataObserver = new ObjectAdapter.DataObserver() { 70 @Override 71 public void onChanged() { 72 showControls(mAdapter, mPresenter); 73 } 74 @Override 75 public void onItemRangeChanged(int positionStart, int itemCount) { 76 for (int i = 0; i < itemCount; i++) { 77 bindControlToAction(positionStart + i, mAdapter, mPresenter); 78 } 79 } 80 }; 81 } 82 83 void showControls(ObjectAdapter adapter, Presenter presenter) { 84 View focusedChild = mControlBar.getFocusedChild(); 85 mControlBar.removeAllViews(); 86 for (int position = 0; position < adapter.size() && position < MAX_CONTROLS; 87 position++) { 88 bindControlToAction(position, adapter, presenter); 89 } 90 if (focusedChild != null) { 91 focusedChild.requestFocus(); 92 } 93 } 94 95 void bindControlToAction(final int position, ObjectAdapter adapter, Presenter presenter) { 96 Presenter.ViewHolder vh = mViewHolders.get(position); 97 Object item = adapter.get(position); 98 if (vh == null) { 99 vh = presenter.onCreateViewHolder(mControlBar); 100 mViewHolders.put(position, vh); 101 presenter.setOnClickListener(vh, new View.OnClickListener() { 102 @Override 103 public void onClick(View v) { 104 Object item = getAdapter().get(position); 105 if (mOnActionClickedListener != null && item instanceof Action) { 106 mOnActionClickedListener.onActionClicked((Action) item); 107 } 108 } 109 }); 110 } 111 if (vh.view.getParent() == null) { 112 mControlBar.addView(vh.view); 113 } 114 presenter.onBindViewHolder(vh, item); 115 } 116 117 ObjectAdapter getAdapter() { 118 return mAdapter; 119 } 120 } 121 122 private OnActionClickedListener mOnActionClickedListener; 123 private int mLayoutResourceId; 124 125 /** 126 * Constructor for a ControlBarPresenter. 127 * 128 * @param layoutResourceId The resource id of the layout for this presenter. 129 */ 130 public ControlBarPresenter(int layoutResourceId) { 131 mLayoutResourceId = layoutResourceId; 132 } 133 134 /** 135 * Returns the layout resource id. 136 */ 137 public int getLayoutResourceId() { 138 return mLayoutResourceId; 139 } 140 141 /** 142 * Sets the listener for {@link Action} click events. 143 */ 144 public void setOnActionClickedListener(OnActionClickedListener listener) { 145 mOnActionClickedListener = listener; 146 } 147 148 /** 149 * Gets the listener for {@link Action} click events. 150 */ 151 public OnActionClickedListener getOnActionClickedListener() { 152 return mOnActionClickedListener; 153 } 154 155 @Override 156 public Presenter.ViewHolder onCreateViewHolder(ViewGroup parent) { 157 View v = LayoutInflater.from(parent.getContext()) 158 .inflate(getLayoutResourceId(), parent, false); 159 return new ViewHolder(v); 160 } 161 162 @Override 163 public void onBindViewHolder(Presenter.ViewHolder holder, Object item) { 164 ViewHolder vh = (ViewHolder) holder; 165 BoundData data = (BoundData) item; 166 if (vh.mAdapter != data.adapter) { 167 vh.mAdapter = data.adapter; 168 vh.mAdapter.registerObserver(vh.mDataObserver); 169 } 170 vh.mPresenter = data.presenter; 171 vh.showControls(vh.mAdapter, vh.mPresenter); 172 } 173 174 @Override 175 public void onUnbindViewHolder(Presenter.ViewHolder holder) { 176 ViewHolder vh = (ViewHolder) holder; 177 vh.mAdapter.unregisterObserver(vh.mDataObserver); 178 vh.mAdapter = null; 179 } 180} 181