HeadersSupportFragment.java revision 42752c860a26deacca04ea9ebeb00ddb4d8ce2fc
1/* This file is auto-generated from HeadersFragment.java. DO NOT MODIFY. */ 2 3/* 4 * Copyright (C) 2014 The Android Open Source Project 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 7 * in compliance with the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software distributed under the License 12 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 13 * or implied. See the License for the specific language governing permissions and limitations under 14 * the License. 15 */ 16 17package android.support.v17.leanback.app; 18 19import android.content.Context; 20import android.graphics.Color; 21import android.graphics.drawable.Drawable; 22import android.graphics.drawable.GradientDrawable; 23import android.os.Bundle; 24import android.support.v17.leanback.R; 25import android.support.v17.leanback.widget.FocusHighlightHelper; 26import android.support.v17.leanback.widget.ItemBridgeAdapter; 27import android.support.v17.leanback.widget.PresenterSelector; 28import android.support.v17.leanback.widget.OnItemSelectedListener; 29import android.support.v17.leanback.widget.Row; 30import android.support.v17.leanback.widget.RowHeaderPresenter; 31import android.support.v17.leanback.widget.SinglePresenterSelector; 32import android.support.v17.leanback.widget.VerticalGridView; 33import android.util.TypedValue; 34import android.view.View; 35import android.view.ViewGroup; 36import android.view.View.OnLayoutChangeListener; 37import android.widget.FrameLayout; 38 39/** 40 * An internal fragment containing a list of row headers. 41 */ 42public class HeadersSupportFragment extends BaseRowSupportFragment { 43 44 interface OnHeaderClickedListener { 45 void onHeaderClicked(); 46 } 47 48 private OnItemSelectedListener mOnItemSelectedListener; 49 private OnHeaderClickedListener mOnHeaderClickedListener; 50 private boolean mHeadersEnabled = true; 51 private boolean mHeadersGone = false; 52 private int mBackgroundColor; 53 private boolean mBackgroundColorSet; 54 55 private static final PresenterSelector sHeaderPresenter = new SinglePresenterSelector( 56 new RowHeaderPresenter(R.layout.lb_header)); 57 58 public HeadersSupportFragment() { 59 setPresenterSelector(sHeaderPresenter); 60 } 61 62 public void setOnHeaderClickedListener(OnHeaderClickedListener listener) { 63 mOnHeaderClickedListener = listener; 64 } 65 66 public void setOnItemSelectedListener(OnItemSelectedListener listener) { 67 mOnItemSelectedListener = listener; 68 } 69 70 @Override 71 VerticalGridView findGridViewFromRoot(View view) { 72 return (VerticalGridView) view.findViewById(R.id.browse_headers); 73 } 74 75 @Override 76 void onRowSelected(ViewGroup parent, View view, int position, long id) { 77 if (mOnItemSelectedListener != null) { 78 if (position >= 0) { 79 Row row = (Row) getAdapter().get(position); 80 mOnItemSelectedListener.onItemSelected(null, row); 81 } else { 82 mOnItemSelectedListener.onItemSelected(null, null); 83 } 84 } 85 } 86 87 private final ItemBridgeAdapter.AdapterListener mAdapterListener = 88 new ItemBridgeAdapter.AdapterListener() { 89 @Override 90 public void onCreate(ItemBridgeAdapter.ViewHolder viewHolder) { 91 View headerView = viewHolder.getViewHolder().view; 92 headerView.setOnClickListener(new View.OnClickListener() { 93 @Override 94 public void onClick(View v) { 95 if (mOnHeaderClickedListener != null) { 96 mOnHeaderClickedListener.onHeaderClicked(); 97 } 98 } 99 }); 100 headerView.setFocusable(true); 101 headerView.setFocusableInTouchMode(true); 102 if (mWrapper != null) { 103 viewHolder.itemView.addOnLayoutChangeListener(sLayoutChangeListener); 104 } else { 105 headerView.addOnLayoutChangeListener(sLayoutChangeListener); 106 } 107 } 108 109 }; 110 111 private static OnLayoutChangeListener sLayoutChangeListener = new OnLayoutChangeListener() { 112 @Override 113 public void onLayoutChange(View v, int left, int top, int right, int bottom, 114 int oldLeft, int oldTop, int oldRight, int oldBottom) { 115 v.setPivotX(0); 116 v.setPivotY(v.getMeasuredHeight() / 2); 117 } 118 }; 119 120 @Override 121 int getLayoutResourceId() { 122 return R.layout.lb_headers_fragment; 123 } 124 125 @Override 126 public void onViewCreated(View view, Bundle savedInstanceState) { 127 super.onViewCreated(view, savedInstanceState); 128 final VerticalGridView listView = getVerticalGridView(); 129 if (listView == null) { 130 return; 131 } 132 if (getBridgeAdapter() != null) { 133 FocusHighlightHelper.setupHeaderItemFocusHighlight(listView); 134 } 135 view.setBackgroundColor(getBackgroundColor()); 136 updateFadingEdgeToBrandColor(getBackgroundColor()); 137 updateListViewVisibility(); 138 } 139 140 private void updateListViewVisibility() { 141 final VerticalGridView listView = getVerticalGridView(); 142 if (listView != null) { 143 getView().setVisibility(mHeadersGone ? View.GONE : View.VISIBLE); 144 if (!mHeadersGone) { 145 if (mHeadersEnabled) { 146 listView.setChildrenVisibility(View.VISIBLE); 147 } else { 148 listView.setChildrenVisibility(View.INVISIBLE); 149 } 150 } 151 } 152 } 153 154 void setHeadersEnabled(boolean enabled) { 155 mHeadersEnabled = enabled; 156 updateListViewVisibility(); 157 } 158 159 void setHeadersGone(boolean gone) { 160 mHeadersGone = gone; 161 updateListViewVisibility(); 162 } 163 164 static class NoOverlappingFrameLayout extends FrameLayout { 165 166 public NoOverlappingFrameLayout(Context context) { 167 super(context); 168 } 169 170 /** 171 * Avoid creating hardware layer for header dock. 172 */ 173 @Override 174 public boolean hasOverlappingRendering() { 175 return false; 176 } 177 } 178 179 // Wrapper needed because of conflict between RecyclerView's use of alpha 180 // for ADD animations, and RowHeaderPresnter's use of alpha for selected level. 181 private final ItemBridgeAdapter.Wrapper mWrapper = new ItemBridgeAdapter.Wrapper() { 182 @Override 183 public void wrap(View wrapper, View wrapped) { 184 ((FrameLayout) wrapper).addView(wrapped); 185 } 186 187 @Override 188 public View createWrapper(View root) { 189 return new NoOverlappingFrameLayout(root.getContext()); 190 } 191 }; 192 @Override 193 void updateAdapter() { 194 super.updateAdapter(); 195 ItemBridgeAdapter adapter = getBridgeAdapter(); 196 if (adapter != null) { 197 adapter.setAdapterListener(mAdapterListener); 198 adapter.setWrapper(mWrapper); 199 } 200 if (adapter != null && getVerticalGridView() != null) { 201 FocusHighlightHelper.setupHeaderItemFocusHighlight(getVerticalGridView()); 202 } 203 } 204 205 void setBackgroundColor(int color) { 206 mBackgroundColor = color; 207 mBackgroundColorSet = true; 208 209 if (getView() != null) { 210 getView().setBackgroundColor(mBackgroundColor); 211 updateFadingEdgeToBrandColor(mBackgroundColor); 212 } 213 } 214 215 private void updateFadingEdgeToBrandColor(int backgroundColor) { 216 View fadingView = getView().findViewById(R.id.fade_out_edge); 217 Drawable background = fadingView.getBackground(); 218 if (background instanceof GradientDrawable) { 219 background.mutate(); 220 ((GradientDrawable) background).setColors( 221 new int[] {Color.TRANSPARENT, backgroundColor}); 222 } 223 } 224 225 int getBackgroundColor() { 226 if (getActivity() == null) { 227 throw new IllegalStateException("Activity must be attached"); 228 } 229 230 if (mBackgroundColorSet) { 231 return mBackgroundColor; 232 } 233 234 TypedValue outValue = new TypedValue(); 235 getActivity().getTheme().resolveAttribute(R.attr.defaultBrandColor, outValue, true); 236 return getResources().getColor(outValue.resourceId); 237 } 238 239 @Override 240 void onTransitionStart() { 241 super.onTransitionStart(); 242 if (!mHeadersEnabled) { 243 // When enabling headers fragment, the RowHeaderView gets a focus but 244 // isShown() is still false because its parent is INVSIBILE, accessibility 245 // event is not sent. 246 // Workaround is: prevent focus to a child view during transition and put 247 // focus on it after transition is done. 248 final VerticalGridView listView = getVerticalGridView(); 249 if (listView != null) { 250 listView.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS); 251 if (listView.hasFocus()) { 252 listView.requestFocus(); 253 } 254 } 255 } 256 } 257 258 @Override 259 void onTransitionEnd() { 260 if (mHeadersEnabled) { 261 final VerticalGridView listView = getVerticalGridView(); 262 if (listView != null) { 263 listView.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS); 264 if (listView.hasFocus()) { 265 listView.requestFocus(); 266 } 267 } 268 } 269 super.onTransitionEnd(); 270 } 271} 272