155c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout/* 255c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout * Copyright (C) 2014 The Android Open Source Project 355c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout * 455c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 555c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout * in compliance with the License. You may obtain a copy of the License at 655c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout * 755c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout * http://www.apache.org/licenses/LICENSE-2.0 855c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout * 955c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout * Unless required by applicable law or agreed to in writing, software distributed under the License 1055c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 1155c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout * or implied. See the License for the specific language governing permissions and limitations under 1255c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout * the License. 1355c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout */ 1455c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout 1555c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stoutpackage android.support.v17.leanback.app; 1655c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout 173659dc62f9e55b1043edb4105c311c8ef997f2aeDake Guimport android.content.Context; 187a208cd35be79a69b1f4f36724b85ab96eb23e75Dake Guimport android.graphics.Color; 199a49e322d10c1a67860d812352a5ea710843b75eDake Guimport android.graphics.drawable.ColorDrawable; 207a208cd35be79a69b1f4f36724b85ab96eb23e75Dake Guimport android.graphics.drawable.Drawable; 217a208cd35be79a69b1f4f36724b85ab96eb23e75Dake Guimport android.graphics.drawable.GradientDrawable; 223c23ada8bc25a05bbaa8c479a9df72e8172c4349Dake Guimport android.os.Bundle; 2355c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stoutimport android.support.v17.leanback.R; 248ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Guimport android.support.v17.leanback.widget.ClassPresenterSelector; 258ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Guimport android.support.v17.leanback.widget.DividerPresenter; 268ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Guimport android.support.v17.leanback.widget.DividerRow; 2755c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stoutimport android.support.v17.leanback.widget.FocusHighlightHelper; 282f5ebf3f6f7bb6a24856f389e369b247118ba119susnataimport android.support.v17.leanback.widget.HorizontalGridView; 2955c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stoutimport android.support.v17.leanback.widget.ItemBridgeAdapter; 3055c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stoutimport android.support.v17.leanback.widget.PresenterSelector; 3155c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stoutimport android.support.v17.leanback.widget.Row; 323c23ada8bc25a05bbaa8c479a9df72e8172c4349Dake Guimport android.support.v17.leanback.widget.RowHeaderPresenter; 338ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Guimport android.support.v17.leanback.widget.SectionRow; 343c23ada8bc25a05bbaa8c479a9df72e8172c4349Dake Guimport android.support.v17.leanback.widget.VerticalGridView; 350246318f27a905a31df5a8af445cfe67d31dfb68Dake Guimport android.support.v7.widget.RecyclerView; 3655c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stoutimport android.view.View; 3755c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stoutimport android.view.ViewGroup; 382f97594742886d045ca1ce409ebc6e6e780452f6Dake Guimport android.view.View.OnLayoutChangeListener; 39e51474af2c4b5192a75fd283cb737d02fccc58a4Craig Stoutimport android.widget.FrameLayout; 4055c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout 4155c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout/** 4255c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout * An internal fragment containing a list of row headers. 4355c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout */ 44a8a3b898da49324e83ea32c3f08776a481312166Tim Kilbournpublic class HeadersFragment extends BaseRowFragment { 453c23ada8bc25a05bbaa8c479a9df72e8172c4349Dake Gu 46729cbf4cd57c87bcd569db5974c8cbd51a942581Dake Gu /** 47729cbf4cd57c87bcd569db5974c8cbd51a942581Dake Gu * Interface definition for a callback to be invoked when a header item is clicked. 48729cbf4cd57c87bcd569db5974c8cbd51a942581Dake Gu */ 49729cbf4cd57c87bcd569db5974c8cbd51a942581Dake Gu public interface OnHeaderClickedListener { 50729cbf4cd57c87bcd569db5974c8cbd51a942581Dake Gu /** 51729cbf4cd57c87bcd569db5974c8cbd51a942581Dake Gu * Called when a header item has been clicked. 52729cbf4cd57c87bcd569db5974c8cbd51a942581Dake Gu * 53729cbf4cd57c87bcd569db5974c8cbd51a942581Dake Gu * @param viewHolder Row ViewHolder object corresponding to the selected Header. 54729cbf4cd57c87bcd569db5974c8cbd51a942581Dake Gu * @param row Row object corresponding to the selected Header. 55729cbf4cd57c87bcd569db5974c8cbd51a942581Dake Gu */ 56729cbf4cd57c87bcd569db5974c8cbd51a942581Dake Gu void onHeaderClicked(RowHeaderPresenter.ViewHolder viewHolder, Row row); 573c23ada8bc25a05bbaa8c479a9df72e8172c4349Dake Gu } 583c23ada8bc25a05bbaa8c479a9df72e8172c4349Dake Gu 59729cbf4cd57c87bcd569db5974c8cbd51a942581Dake Gu /** 60729cbf4cd57c87bcd569db5974c8cbd51a942581Dake Gu * Interface definition for a callback to be invoked when a header item is selected. 61729cbf4cd57c87bcd569db5974c8cbd51a942581Dake Gu */ 62729cbf4cd57c87bcd569db5974c8cbd51a942581Dake Gu public interface OnHeaderViewSelectedListener { 63729cbf4cd57c87bcd569db5974c8cbd51a942581Dake Gu /** 64729cbf4cd57c87bcd569db5974c8cbd51a942581Dake Gu * Called when a header item has been selected. 65729cbf4cd57c87bcd569db5974c8cbd51a942581Dake Gu * 66729cbf4cd57c87bcd569db5974c8cbd51a942581Dake Gu * @param viewHolder Row ViewHolder object corresponding to the selected Header. 67729cbf4cd57c87bcd569db5974c8cbd51a942581Dake Gu * @param row Row object corresponding to the selected Header. 68729cbf4cd57c87bcd569db5974c8cbd51a942581Dake Gu */ 698df88a1ead9ea62456fc3bbda41657ccf61d5721Dake Gu void onHeaderSelected(RowHeaderPresenter.ViewHolder viewHolder, Row row); 708df88a1ead9ea62456fc3bbda41657ccf61d5721Dake Gu } 718df88a1ead9ea62456fc3bbda41657ccf61d5721Dake Gu 728df88a1ead9ea62456fc3bbda41657ccf61d5721Dake Gu private OnHeaderViewSelectedListener mOnHeaderViewSelectedListener; 733c23ada8bc25a05bbaa8c479a9df72e8172c4349Dake Gu private OnHeaderClickedListener mOnHeaderClickedListener; 74d559710c8763acb37fd444735da7ee770b84df07Craig Stout private boolean mHeadersEnabled = true; 75d559710c8763acb37fd444735da7ee770b84df07Craig Stout private boolean mHeadersGone = false; 764cf79b1c4d38a190317961891f9fd052836710fdCraig Stout private int mBackgroundColor; 774cf79b1c4d38a190317961891f9fd052836710fdCraig Stout private boolean mBackgroundColorSet; 783c23ada8bc25a05bbaa8c479a9df72e8172c4349Dake Gu 798ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu private static final PresenterSelector sHeaderPresenter = new ClassPresenterSelector() 808ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu .addClassPresenter(DividerRow.class, new DividerPresenter()) 818ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu .addClassPresenter(SectionRow.class, 828ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu new RowHeaderPresenter(R.layout.lb_section_header, false)) 838ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu .addClassPresenter(Row.class, new RowHeaderPresenter(R.layout.lb_header)); 8455c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout 85a8a3b898da49324e83ea32c3f08776a481312166Tim Kilbourn public HeadersFragment() { 86bd80644186ff8622c565f067dc3a4136a4dc0586Dake Gu setPresenterSelector(sHeaderPresenter); 8755c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout } 8855c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout 893c23ada8bc25a05bbaa8c479a9df72e8172c4349Dake Gu public void setOnHeaderClickedListener(OnHeaderClickedListener listener) { 903c23ada8bc25a05bbaa8c479a9df72e8172c4349Dake Gu mOnHeaderClickedListener = listener; 9155c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout } 9255c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout 938df88a1ead9ea62456fc3bbda41657ccf61d5721Dake Gu public void setOnHeaderViewSelectedListener(OnHeaderViewSelectedListener listener) { 948df88a1ead9ea62456fc3bbda41657ccf61d5721Dake Gu mOnHeaderViewSelectedListener = listener; 9555c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout } 9655c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout 9755c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout @Override 9842752c860a26deacca04ea9ebeb00ddb4d8ce2fcDake Gu VerticalGridView findGridViewFromRoot(View view) { 997a208cd35be79a69b1f4f36724b85ab96eb23e75Dake Gu return (VerticalGridView) view.findViewById(R.id.browse_headers); 1007a208cd35be79a69b1f4f36724b85ab96eb23e75Dake Gu } 1017a208cd35be79a69b1f4f36724b85ab96eb23e75Dake Gu 1027a208cd35be79a69b1f4f36724b85ab96eb23e75Dake Gu @Override 1030246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu void onRowSelected(RecyclerView parent, RecyclerView.ViewHolder viewHolder, 1040246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu int position, int subposition) { 1058df88a1ead9ea62456fc3bbda41657ccf61d5721Dake Gu if (mOnHeaderViewSelectedListener != null) { 1060246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu if (viewHolder != null && position >= 0) { 1070246318f27a905a31df5a8af445cfe67d31dfb68Dake Gu ItemBridgeAdapter.ViewHolder vh = (ItemBridgeAdapter.ViewHolder) viewHolder; 1088df88a1ead9ea62456fc3bbda41657ccf61d5721Dake Gu mOnHeaderViewSelectedListener.onHeaderSelected( 109729cbf4cd57c87bcd569db5974c8cbd51a942581Dake Gu (RowHeaderPresenter.ViewHolder) vh.getViewHolder(), (Row) vh.getItem()); 110d736653bfee7fc83fc68d57d0e0bee5fa807287fDake Gu } else { 1118df88a1ead9ea62456fc3bbda41657ccf61d5721Dake Gu mOnHeaderViewSelectedListener.onHeaderSelected(null, null); 1122f5fbc79d656fc4966119141aaef48161f08376fAndrew Wilson } 11355c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout } 11455c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout } 11555c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout 1163c23ada8bc25a05bbaa8c479a9df72e8172c4349Dake Gu private final ItemBridgeAdapter.AdapterListener mAdapterListener = 1173c23ada8bc25a05bbaa8c479a9df72e8172c4349Dake Gu new ItemBridgeAdapter.AdapterListener() { 1183c23ada8bc25a05bbaa8c479a9df72e8172c4349Dake Gu @Override 119729cbf4cd57c87bcd569db5974c8cbd51a942581Dake Gu public void onCreate(final ItemBridgeAdapter.ViewHolder viewHolder) { 1203c23ada8bc25a05bbaa8c479a9df72e8172c4349Dake Gu View headerView = viewHolder.getViewHolder().view; 1213c23ada8bc25a05bbaa8c479a9df72e8172c4349Dake Gu headerView.setOnClickListener(new View.OnClickListener() { 1223c23ada8bc25a05bbaa8c479a9df72e8172c4349Dake Gu @Override 1233c23ada8bc25a05bbaa8c479a9df72e8172c4349Dake Gu public void onClick(View v) { 1243c23ada8bc25a05bbaa8c479a9df72e8172c4349Dake Gu if (mOnHeaderClickedListener != null) { 125729cbf4cd57c87bcd569db5974c8cbd51a942581Dake Gu mOnHeaderClickedListener.onHeaderClicked( 126729cbf4cd57c87bcd569db5974c8cbd51a942581Dake Gu (RowHeaderPresenter.ViewHolder) viewHolder.getViewHolder(), 127729cbf4cd57c87bcd569db5974c8cbd51a942581Dake Gu (Row) viewHolder.getItem()); 1283c23ada8bc25a05bbaa8c479a9df72e8172c4349Dake Gu } 1293c23ada8bc25a05bbaa8c479a9df72e8172c4349Dake Gu } 1303c23ada8bc25a05bbaa8c479a9df72e8172c4349Dake Gu }); 131e51474af2c4b5192a75fd283cb737d02fccc58a4Craig Stout if (mWrapper != null) { 132e51474af2c4b5192a75fd283cb737d02fccc58a4Craig Stout viewHolder.itemView.addOnLayoutChangeListener(sLayoutChangeListener); 133e51474af2c4b5192a75fd283cb737d02fccc58a4Craig Stout } else { 134e51474af2c4b5192a75fd283cb737d02fccc58a4Craig Stout headerView.addOnLayoutChangeListener(sLayoutChangeListener); 135e51474af2c4b5192a75fd283cb737d02fccc58a4Craig Stout } 1363c23ada8bc25a05bbaa8c479a9df72e8172c4349Dake Gu } 1373c23ada8bc25a05bbaa8c479a9df72e8172c4349Dake Gu 1383c23ada8bc25a05bbaa8c479a9df72e8172c4349Dake Gu }; 1393c23ada8bc25a05bbaa8c479a9df72e8172c4349Dake Gu 1402f97594742886d045ca1ce409ebc6e6e780452f6Dake Gu private static OnLayoutChangeListener sLayoutChangeListener = new OnLayoutChangeListener() { 1412f97594742886d045ca1ce409ebc6e6e780452f6Dake Gu @Override 1422f97594742886d045ca1ce409ebc6e6e780452f6Dake Gu public void onLayoutChange(View v, int left, int top, int right, int bottom, 1432f97594742886d045ca1ce409ebc6e6e780452f6Dake Gu int oldLeft, int oldTop, int oldRight, int oldBottom) { 1448e3566285de4ac771d6188f62fe947e23d371a3dKris Giesing v.setPivotX(v.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL ? v.getWidth() : 0); 1452f97594742886d045ca1ce409ebc6e6e780452f6Dake Gu v.setPivotY(v.getMeasuredHeight() / 2); 1462f97594742886d045ca1ce409ebc6e6e780452f6Dake Gu } 1472f97594742886d045ca1ce409ebc6e6e780452f6Dake Gu }; 1482f97594742886d045ca1ce409ebc6e6e780452f6Dake Gu 1492f97594742886d045ca1ce409ebc6e6e780452f6Dake Gu @Override 15042752c860a26deacca04ea9ebeb00ddb4d8ce2fcDake Gu int getLayoutResourceId() { 1512f97594742886d045ca1ce409ebc6e6e780452f6Dake Gu return R.layout.lb_headers_fragment; 1522f97594742886d045ca1ce409ebc6e6e780452f6Dake Gu } 1532f97594742886d045ca1ce409ebc6e6e780452f6Dake Gu 1542f97594742886d045ca1ce409ebc6e6e780452f6Dake Gu @Override 1552f97594742886d045ca1ce409ebc6e6e780452f6Dake Gu public void onViewCreated(View view, Bundle savedInstanceState) { 1562f97594742886d045ca1ce409ebc6e6e780452f6Dake Gu super.onViewCreated(view, savedInstanceState); 1574cf79b1c4d38a190317961891f9fd052836710fdCraig Stout final VerticalGridView listView = getVerticalGridView(); 1584cf79b1c4d38a190317961891f9fd052836710fdCraig Stout if (listView == null) { 1594cf79b1c4d38a190317961891f9fd052836710fdCraig Stout return; 1603c23ada8bc25a05bbaa8c479a9df72e8172c4349Dake Gu } 1614cf79b1c4d38a190317961891f9fd052836710fdCraig Stout if (getBridgeAdapter() != null) { 1624cf79b1c4d38a190317961891f9fd052836710fdCraig Stout FocusHighlightHelper.setupHeaderItemFocusHighlight(listView); 1634cf79b1c4d38a190317961891f9fd052836710fdCraig Stout } 1647f43e18536eae40705d5c63830e9edb283f196adDake Gu if (mBackgroundColorSet) { 1659a49e322d10c1a67860d812352a5ea710843b75eDake Gu listView.setBackgroundColor(mBackgroundColor); 1667f43e18536eae40705d5c63830e9edb283f196adDake Gu updateFadingEdgeToBrandColor(mBackgroundColor); 1679a49e322d10c1a67860d812352a5ea710843b75eDake Gu } else { 1689a49e322d10c1a67860d812352a5ea710843b75eDake Gu Drawable d = listView.getBackground(); 1699a49e322d10c1a67860d812352a5ea710843b75eDake Gu if (d instanceof ColorDrawable) { 1709a49e322d10c1a67860d812352a5ea710843b75eDake Gu updateFadingEdgeToBrandColor(((ColorDrawable) d).getColor()); 1719a49e322d10c1a67860d812352a5ea710843b75eDake Gu } 1727f43e18536eae40705d5c63830e9edb283f196adDake Gu } 173d7618ab69ef591dd5342b9481c4954bfc7e9110cDake Gu updateListViewVisibility(); 1743c23ada8bc25a05bbaa8c479a9df72e8172c4349Dake Gu } 1753c23ada8bc25a05bbaa8c479a9df72e8172c4349Dake Gu 176d7618ab69ef591dd5342b9481c4954bfc7e9110cDake Gu private void updateListViewVisibility() { 1773c23ada8bc25a05bbaa8c479a9df72e8172c4349Dake Gu final VerticalGridView listView = getVerticalGridView(); 1782f97594742886d045ca1ce409ebc6e6e780452f6Dake Gu if (listView != null) { 1799652881bb6af5a2b76f89d683bd420336f4bf463Dake Gu getView().setVisibility(mHeadersGone ? View.GONE : View.VISIBLE); 180d7618ab69ef591dd5342b9481c4954bfc7e9110cDake Gu if (!mHeadersGone) { 181d7618ab69ef591dd5342b9481c4954bfc7e9110cDake Gu if (mHeadersEnabled) { 182d7618ab69ef591dd5342b9481c4954bfc7e9110cDake Gu listView.setChildrenVisibility(View.VISIBLE); 183d7618ab69ef591dd5342b9481c4954bfc7e9110cDake Gu } else { 184d7618ab69ef591dd5342b9481c4954bfc7e9110cDake Gu listView.setChildrenVisibility(View.INVISIBLE); 185d7618ab69ef591dd5342b9481c4954bfc7e9110cDake Gu } 186d7618ab69ef591dd5342b9481c4954bfc7e9110cDake Gu } 187d559710c8763acb37fd444735da7ee770b84df07Craig Stout } 188d559710c8763acb37fd444735da7ee770b84df07Craig Stout } 189d559710c8763acb37fd444735da7ee770b84df07Craig Stout 190d7618ab69ef591dd5342b9481c4954bfc7e9110cDake Gu void setHeadersEnabled(boolean enabled) { 191d7618ab69ef591dd5342b9481c4954bfc7e9110cDake Gu mHeadersEnabled = enabled; 192d7618ab69ef591dd5342b9481c4954bfc7e9110cDake Gu updateListViewVisibility(); 193d7618ab69ef591dd5342b9481c4954bfc7e9110cDake Gu } 194d7618ab69ef591dd5342b9481c4954bfc7e9110cDake Gu 195d559710c8763acb37fd444735da7ee770b84df07Craig Stout void setHeadersGone(boolean gone) { 196d559710c8763acb37fd444735da7ee770b84df07Craig Stout mHeadersGone = gone; 197d7618ab69ef591dd5342b9481c4954bfc7e9110cDake Gu updateListViewVisibility(); 1983c23ada8bc25a05bbaa8c479a9df72e8172c4349Dake Gu } 1993c23ada8bc25a05bbaa8c479a9df72e8172c4349Dake Gu 2003659dc62f9e55b1043edb4105c311c8ef997f2aeDake Gu static class NoOverlappingFrameLayout extends FrameLayout { 2013659dc62f9e55b1043edb4105c311c8ef997f2aeDake Gu 2023659dc62f9e55b1043edb4105c311c8ef997f2aeDake Gu public NoOverlappingFrameLayout(Context context) { 2033659dc62f9e55b1043edb4105c311c8ef997f2aeDake Gu super(context); 2043659dc62f9e55b1043edb4105c311c8ef997f2aeDake Gu } 2053659dc62f9e55b1043edb4105c311c8ef997f2aeDake Gu 2063659dc62f9e55b1043edb4105c311c8ef997f2aeDake Gu /** 2073659dc62f9e55b1043edb4105c311c8ef997f2aeDake Gu * Avoid creating hardware layer for header dock. 2083659dc62f9e55b1043edb4105c311c8ef997f2aeDake Gu */ 2093659dc62f9e55b1043edb4105c311c8ef997f2aeDake Gu @Override 2103659dc62f9e55b1043edb4105c311c8ef997f2aeDake Gu public boolean hasOverlappingRendering() { 2113659dc62f9e55b1043edb4105c311c8ef997f2aeDake Gu return false; 2123659dc62f9e55b1043edb4105c311c8ef997f2aeDake Gu } 2133659dc62f9e55b1043edb4105c311c8ef997f2aeDake Gu } 2143659dc62f9e55b1043edb4105c311c8ef997f2aeDake Gu 215e51474af2c4b5192a75fd283cb737d02fccc58a4Craig Stout // Wrapper needed because of conflict between RecyclerView's use of alpha 216e51474af2c4b5192a75fd283cb737d02fccc58a4Craig Stout // for ADD animations, and RowHeaderPresnter's use of alpha for selected level. 217e51474af2c4b5192a75fd283cb737d02fccc58a4Craig Stout private final ItemBridgeAdapter.Wrapper mWrapper = new ItemBridgeAdapter.Wrapper() { 218e51474af2c4b5192a75fd283cb737d02fccc58a4Craig Stout @Override 219e51474af2c4b5192a75fd283cb737d02fccc58a4Craig Stout public void wrap(View wrapper, View wrapped) { 220e51474af2c4b5192a75fd283cb737d02fccc58a4Craig Stout ((FrameLayout) wrapper).addView(wrapped); 221e51474af2c4b5192a75fd283cb737d02fccc58a4Craig Stout } 222e51474af2c4b5192a75fd283cb737d02fccc58a4Craig Stout 223e51474af2c4b5192a75fd283cb737d02fccc58a4Craig Stout @Override 224e51474af2c4b5192a75fd283cb737d02fccc58a4Craig Stout public View createWrapper(View root) { 2253659dc62f9e55b1043edb4105c311c8ef997f2aeDake Gu return new NoOverlappingFrameLayout(root.getContext()); 226e51474af2c4b5192a75fd283cb737d02fccc58a4Craig Stout } 227e51474af2c4b5192a75fd283cb737d02fccc58a4Craig Stout }; 2283c23ada8bc25a05bbaa8c479a9df72e8172c4349Dake Gu @Override 22942752c860a26deacca04ea9ebeb00ddb4d8ce2fcDake Gu void updateAdapter() { 23055c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout super.updateAdapter(); 23155c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout ItemBridgeAdapter adapter = getBridgeAdapter(); 23255c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout if (adapter != null) { 2333c23ada8bc25a05bbaa8c479a9df72e8172c4349Dake Gu adapter.setAdapterListener(mAdapterListener); 234e51474af2c4b5192a75fd283cb737d02fccc58a4Craig Stout adapter.setWrapper(mWrapper); 2353c23ada8bc25a05bbaa8c479a9df72e8172c4349Dake Gu } 2363c23ada8bc25a05bbaa8c479a9df72e8172c4349Dake Gu if (adapter != null && getVerticalGridView() != null) { 2373c23ada8bc25a05bbaa8c479a9df72e8172c4349Dake Gu FocusHighlightHelper.setupHeaderItemFocusHighlight(getVerticalGridView()); 23855c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout } 23955c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout } 2404cf79b1c4d38a190317961891f9fd052836710fdCraig Stout 2414cf79b1c4d38a190317961891f9fd052836710fdCraig Stout void setBackgroundColor(int color) { 2424cf79b1c4d38a190317961891f9fd052836710fdCraig Stout mBackgroundColor = color; 2434cf79b1c4d38a190317961891f9fd052836710fdCraig Stout mBackgroundColorSet = true; 2444cf79b1c4d38a190317961891f9fd052836710fdCraig Stout 2459a49e322d10c1a67860d812352a5ea710843b75eDake Gu if (getVerticalGridView() != null) { 2469a49e322d10c1a67860d812352a5ea710843b75eDake Gu getVerticalGridView().setBackgroundColor(mBackgroundColor); 247b74149016854eb172c0ef121ccfef749c6ef7eb1Dake Gu updateFadingEdgeToBrandColor(mBackgroundColor); 2487a208cd35be79a69b1f4f36724b85ab96eb23e75Dake Gu } 2497a208cd35be79a69b1f4f36724b85ab96eb23e75Dake Gu } 2507a208cd35be79a69b1f4f36724b85ab96eb23e75Dake Gu 251b74149016854eb172c0ef121ccfef749c6ef7eb1Dake Gu private void updateFadingEdgeToBrandColor(int backgroundColor) { 2527a208cd35be79a69b1f4f36724b85ab96eb23e75Dake Gu View fadingView = getView().findViewById(R.id.fade_out_edge); 2537a208cd35be79a69b1f4f36724b85ab96eb23e75Dake Gu Drawable background = fadingView.getBackground(); 2547a208cd35be79a69b1f4f36724b85ab96eb23e75Dake Gu if (background instanceof GradientDrawable) { 2557a208cd35be79a69b1f4f36724b85ab96eb23e75Dake Gu background.mutate(); 2567a208cd35be79a69b1f4f36724b85ab96eb23e75Dake Gu ((GradientDrawable) background).setColors( 257b74149016854eb172c0ef121ccfef749c6ef7eb1Dake Gu new int[] {Color.TRANSPARENT, backgroundColor}); 2584cf79b1c4d38a190317961891f9fd052836710fdCraig Stout } 2594cf79b1c4d38a190317961891f9fd052836710fdCraig Stout } 2604cf79b1c4d38a190317961891f9fd052836710fdCraig Stout 26149e6a6cd81f3a1117b306323064c53230a7f01adDake Gu @Override 2622f5ebf3f6f7bb6a24856f389e369b247118ba119susnata public void onTransitionStart() { 26349e6a6cd81f3a1117b306323064c53230a7f01adDake Gu super.onTransitionStart(); 26449e6a6cd81f3a1117b306323064c53230a7f01adDake Gu if (!mHeadersEnabled) { 26549e6a6cd81f3a1117b306323064c53230a7f01adDake Gu // When enabling headers fragment, the RowHeaderView gets a focus but 26649e6a6cd81f3a1117b306323064c53230a7f01adDake Gu // isShown() is still false because its parent is INVSIBILE, accessibility 26749e6a6cd81f3a1117b306323064c53230a7f01adDake Gu // event is not sent. 26849e6a6cd81f3a1117b306323064c53230a7f01adDake Gu // Workaround is: prevent focus to a child view during transition and put 26949e6a6cd81f3a1117b306323064c53230a7f01adDake Gu // focus on it after transition is done. 27049e6a6cd81f3a1117b306323064c53230a7f01adDake Gu final VerticalGridView listView = getVerticalGridView(); 27149e6a6cd81f3a1117b306323064c53230a7f01adDake Gu if (listView != null) { 27249e6a6cd81f3a1117b306323064c53230a7f01adDake Gu listView.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS); 27349e6a6cd81f3a1117b306323064c53230a7f01adDake Gu if (listView.hasFocus()) { 27449e6a6cd81f3a1117b306323064c53230a7f01adDake Gu listView.requestFocus(); 27549e6a6cd81f3a1117b306323064c53230a7f01adDake Gu } 27649e6a6cd81f3a1117b306323064c53230a7f01adDake Gu } 27749e6a6cd81f3a1117b306323064c53230a7f01adDake Gu } 27849e6a6cd81f3a1117b306323064c53230a7f01adDake Gu } 27949e6a6cd81f3a1117b306323064c53230a7f01adDake Gu 28049e6a6cd81f3a1117b306323064c53230a7f01adDake Gu @Override 2812f5ebf3f6f7bb6a24856f389e369b247118ba119susnata public void onTransitionEnd() { 28249e6a6cd81f3a1117b306323064c53230a7f01adDake Gu if (mHeadersEnabled) { 28349e6a6cd81f3a1117b306323064c53230a7f01adDake Gu final VerticalGridView listView = getVerticalGridView(); 28449e6a6cd81f3a1117b306323064c53230a7f01adDake Gu if (listView != null) { 28549e6a6cd81f3a1117b306323064c53230a7f01adDake Gu listView.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS); 28649e6a6cd81f3a1117b306323064c53230a7f01adDake Gu if (listView.hasFocus()) { 28749e6a6cd81f3a1117b306323064c53230a7f01adDake Gu listView.requestFocus(); 28849e6a6cd81f3a1117b306323064c53230a7f01adDake Gu } 28949e6a6cd81f3a1117b306323064c53230a7f01adDake Gu } 29049e6a6cd81f3a1117b306323064c53230a7f01adDake Gu } 29149e6a6cd81f3a1117b306323064c53230a7f01adDake Gu super.onTransitionEnd(); 29249e6a6cd81f3a1117b306323064c53230a7f01adDake Gu } 2932f5ebf3f6f7bb6a24856f389e369b247118ba119susnata 2942f5ebf3f6f7bb6a24856f389e369b247118ba119susnata public boolean isScrolling() { 2952f5ebf3f6f7bb6a24856f389e369b247118ba119susnata return getVerticalGridView().getScrollState() 2962f5ebf3f6f7bb6a24856f389e369b247118ba119susnata != HorizontalGridView.SCROLL_STATE_IDLE; 2972f5ebf3f6f7bb6a24856f389e369b247118ba119susnata } 29855c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout} 299