1062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu/*
2062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu * Copyright (C) 2015 The Android Open Source Project
3062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu *
4062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu * Licensed under the Apache License, Version 2.0 (the "License");
5062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu * you may not use this file except in compliance with the License.
6062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu * You may obtain a copy of the License at
7062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu *
8062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu *      http://www.apache.org/licenses/LICENSE-2.0
9062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu *
10062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu * Unless required by applicable law or agreed to in writing, software
11062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu * distributed under the License is distributed on an "AS IS" BASIS,
12062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu * See the License for the specific language governing permissions and
14062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu * limitations under the License.
15062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu */
16062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
17062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gupackage android.support.v17.leanback.widget;
18062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
19062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Guimport android.support.v17.leanback.tests.R;
20062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Guimport android.support.v7.widget.RecyclerView;
21062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Guimport android.support.v17.leanback.widget.BaseGridView;
22062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Guimport android.support.v17.leanback.widget.OnChildSelectedListener;
23062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Guimport android.app.Activity;
24062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Guimport android.content.Intent;
25062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Guimport android.graphics.Color;
26062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Guimport android.os.Bundle;
27062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Guimport android.util.Log;
28062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Guimport android.util.SparseArray;
29062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Guimport android.view.View;
30062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Guimport android.view.View.OnClickListener;
31062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Guimport android.view.View.OnFocusChangeListener;
32062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Guimport android.view.ViewGroup;
33062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Guimport android.widget.ImageView;
34062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Guimport android.widget.TextView;
35062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
36c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Guimport java.util.ArrayList;
37c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu
38062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu/**
39062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu * @hide from javadoc
40062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu */
41062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gupublic class GridActivity extends Activity {
423a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu
43062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    private static final String TAG = "GridActivity";
44062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
45362fda0323b85ec2379967901a0bd33a2ad4b8b5Dake Gu    interface AdapterListener {
46362fda0323b85ec2379967901a0bd33a2ad4b8b5Dake Gu        void onBind(RecyclerView.ViewHolder vh, int position);
47362fda0323b85ec2379967901a0bd33a2ad4b8b5Dake Gu    }
48362fda0323b85ec2379967901a0bd33a2ad4b8b5Dake Gu
49247741d74797105ba4f6d2834ec56dab32c14644Dake Gu    public static final String EXTRA_LAYOUT_RESOURCE_ID = "layoutResourceId";
5085df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu    public static final String EXTRA_NUM_ITEMS = "numItems";
5185df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu    public static final String EXTRA_ITEMS = "items";
5277b17ebed6d1f8488b150b25e2b6754971480caeDake Gu    public static final String EXTRA_ITEMS_FOCUSABLE = "itemsFocusable";
53062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    public static final String EXTRA_STAGGERED = "staggered";
54fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu    public static final String EXTRA_REQUEST_LAYOUT_ONFOCUS = "requestLayoutOnFocus";
553a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu    public static final String EXTRA_REQUEST_FOCUS_ONLAYOUT = "requstFocusOnLayout";
56c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu    public static final String EXTRA_CHILD_LAYOUT_ID = "childLayoutId";
571a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu    public static final String EXTRA_SECONDARY_SIZE_ZERO = "secondarySizeZero";
58362fda0323b85ec2379967901a0bd33a2ad4b8b5Dake Gu    public static final String EXTRA_UPDATE_SIZE = "updateSize";
595509e275a04396bfb16b3a217c5392a864398174Dake Gu    public static final String EXTRA_LAYOUT_MARGINS = "layoutMargins";
60e2443a93fcb82151f5290b89617b34b69442fdd3Dake Gu    public static final String EXTRA_NINEPATCH_SHADOW = "NINEPATCH_SHADOW";
61362fda0323b85ec2379967901a0bd33a2ad4b8b5Dake Gu
6208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    /**
6308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu     * Class that implements GridWidgetTest.ViewTypeProvider for creating different
6408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu     * view types for each position.
6508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu     */
6608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    public static final String EXTRA_VIEWTYPEPROVIDER_CLASS = "viewtype_class";
6708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    /**
6808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu     * Class that implements GridWidgetTest.ItemAlignmentFacetProvider for creating different
6908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu     * ItemAlignmentFacet for each ViewHolder.
7008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu     */
7108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    public static final String EXTRA_ITEMALIGNMENTPROVIDER_CLASS = "itemalignment_class";
7208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    /**
7308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu     * Class that implements GridWidgetTest.ItemAlignmentFacetProvider for creating different
7408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu     * ItemAlignmentFacet for a given viewType.
7508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu     */
7608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    public static final String EXTRA_ITEMALIGNMENTPROVIDER_VIEWTYPE_CLASS =
7708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            "itemalignment_viewtype_class";
78062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    public static final String SELECT_ACTION = "android.test.leanback.widget.SELECT";
79062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
80062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    static final int DEFAULT_NUM_ITEMS = 100;
81062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    static final boolean DEFAULT_STAGGERED = true;
82fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu    static final boolean DEFAULT_REQUEST_LAYOUT_ONFOCUS = false;
833a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu    static final boolean DEFAULT_REQUEST_FOCUS_ONLAYOUT = false;
84062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
85062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    private static final boolean DEBUG = false;
86062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
87247741d74797105ba4f6d2834ec56dab32c14644Dake Gu    int mLayoutId;
88062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    int mOrientation;
89062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    int mNumItems;
90c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu    int mChildLayout;
91062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    boolean mStaggered;
92fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu    boolean mRequestLayoutOnFocus;
933a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu    boolean mRequestFocusOnLayout;
941a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu    boolean mSecondarySizeZero;
9508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    GridWidgetTest.ViewTypeProvider mViewTypeProvider;
9608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    GridWidgetTest.ItemAlignmentFacetProvider mAlignmentProvider;
9708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    GridWidgetTest.ItemAlignmentFacetProvider mAlignmentViewTypeProvider;
98362fda0323b85ec2379967901a0bd33a2ad4b8b5Dake Gu    AdapterListener mAdapterListener;
99362fda0323b85ec2379967901a0bd33a2ad4b8b5Dake Gu    boolean mUpdateSize = true;
100062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
10185df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu    int[] mGridViewLayoutSize;
102062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    BaseGridView mGridView;
103062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    int[] mItemLengths;
10477b17ebed6d1f8488b150b25e2b6754971480caeDake Gu    boolean[] mItemFocusables;
1055509e275a04396bfb16b3a217c5392a864398174Dake Gu    int[] mLayoutMargins;
106e2443a93fcb82151f5290b89617b34b69442fdd3Dake Gu    int mNinePatchShadow;
107062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
108e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu    private int mBoundCount;
109e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu
110062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    private View createView() {
111062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
112247741d74797105ba4f6d2834ec56dab32c14644Dake Gu        View view = getLayoutInflater().inflate(mLayoutId, null, false);
113062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        mGridView = (BaseGridView) view.findViewById(R.id.gridview);
114247741d74797105ba4f6d2834ec56dab32c14644Dake Gu        mOrientation = mGridView instanceof HorizontalGridView ? BaseGridView.HORIZONTAL :
115247741d74797105ba4f6d2834ec56dab32c14644Dake Gu                BaseGridView.VERTICAL;
116062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        mGridView.setWindowAlignment(BaseGridView.WINDOW_ALIGN_BOTH_EDGE);
117062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        mGridView.setWindowAlignmentOffsetPercent(35);
118062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        mGridView.setOnChildSelectedListener(new OnChildSelectedListener() {
119062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu            @Override
120062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu            public void onChildSelected(ViewGroup parent, View view, int position, long id) {
121062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu                if (DEBUG) Log.d(TAG, "onChildSelected position=" + position +  " id="+id);
122062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu            }
123062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        });
124e2443a93fcb82151f5290b89617b34b69442fdd3Dake Gu        if (mNinePatchShadow != 0) {
125e2443a93fcb82151f5290b89617b34b69442fdd3Dake Gu            mGridView.setLayoutMode(ViewGroup.LAYOUT_MODE_OPTICAL_BOUNDS);
126e2443a93fcb82151f5290b89617b34b69442fdd3Dake Gu        }
127062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        return view;
128062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    }
129062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
130062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    @Override
131062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    protected void onCreate(Bundle savedInstanceState) {
132062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        Intent intent = getIntent();
133062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
1344576ab79ede1a6c515316c63124202f54ecc031fDake Gu        mLayoutId = intent.getIntExtra(EXTRA_LAYOUT_RESOURCE_ID, R.layout.horizontal_grid);
135c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        mChildLayout = intent.getIntExtra(EXTRA_CHILD_LAYOUT_ID, -1);
13685df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        mStaggered = intent.getBooleanExtra(EXTRA_STAGGERED, DEFAULT_STAGGERED);
137fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        mRequestLayoutOnFocus = intent.getBooleanExtra(EXTRA_REQUEST_LAYOUT_ONFOCUS,
138fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu                DEFAULT_REQUEST_LAYOUT_ONFOCUS);
1393a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        mRequestFocusOnLayout = intent.getBooleanExtra(EXTRA_REQUEST_FOCUS_ONLAYOUT,
1403a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu                DEFAULT_REQUEST_FOCUS_ONLAYOUT);
141362fda0323b85ec2379967901a0bd33a2ad4b8b5Dake Gu        mUpdateSize = intent.getBooleanExtra(EXTRA_UPDATE_SIZE, true);
1421a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu        mSecondarySizeZero = intent.getBooleanExtra(EXTRA_SECONDARY_SIZE_ZERO, false);
14385df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        mItemLengths = intent.getIntArrayExtra(EXTRA_ITEMS);
14477b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        mItemFocusables = intent.getBooleanArrayExtra(EXTRA_ITEMS_FOCUSABLE);
1455509e275a04396bfb16b3a217c5392a864398174Dake Gu        mLayoutMargins = intent.getIntArrayExtra(EXTRA_LAYOUT_MARGINS);
14608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        String alignmentClass = intent.getStringExtra(EXTRA_ITEMALIGNMENTPROVIDER_CLASS);
14708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        String alignmentViewTypeClass =
14808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                intent.getStringExtra(EXTRA_ITEMALIGNMENTPROVIDER_VIEWTYPE_CLASS);
14908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        String viewTypeClass = intent.getStringExtra(EXTRA_VIEWTYPEPROVIDER_CLASS);
150e2443a93fcb82151f5290b89617b34b69442fdd3Dake Gu        mNinePatchShadow = intent.getIntExtra(EXTRA_NINEPATCH_SHADOW, 0);
15108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        try {
15208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            if (alignmentClass != null) {
15308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                mAlignmentProvider = (GridWidgetTest.ItemAlignmentFacetProvider)
15408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                        Class.forName(alignmentClass).newInstance();
15508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            }
15608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            if (alignmentViewTypeClass != null) {
15708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                mAlignmentViewTypeProvider = (GridWidgetTest.ItemAlignmentFacetProvider)
15808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                        Class.forName(alignmentViewTypeClass).newInstance();
15908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            }
16008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            if (viewTypeClass != null) {
16108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                mViewTypeProvider = (GridWidgetTest.ViewTypeProvider)
16208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                        Class.forName(viewTypeClass).newInstance();
16308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            }
16408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        } catch (ClassNotFoundException ex) {
16508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            throw new RuntimeException(ex);
16608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        } catch (InstantiationException ex) {
16708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            throw new RuntimeException(ex);
16808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        } catch (IllegalAccessException ex) {
16908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            throw new RuntimeException(ex);
17008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        }
171fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu
172fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        super.onCreate(savedInstanceState);
173fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu
174fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        if (DEBUG) Log.v(TAG, "onCreate " + this);
175fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu
176fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        RecyclerView.Adapter adapter = new MyAdapter();
177fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu
178fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        View view = createView();
17985df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        if (mItemLengths == null) {
18085df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu            mNumItems = intent.getIntExtra(EXTRA_NUM_ITEMS, DEFAULT_NUM_ITEMS);
18185df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu            mItemLengths = new int[mNumItems];
18285df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu            for (int i = 0; i < mItemLengths.length; i++) {
18385df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                if (mOrientation == BaseGridView.HORIZONTAL) {
18485df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                    mItemLengths[i] = mStaggered ? (int)(Math.random() * 180) + 180 : 240;
18585df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                } else {
18685df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                    mItemLengths[i] = mStaggered ? (int)(Math.random() * 120) + 120 : 160;
18785df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                }
188e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            }
18985df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        } else {
19085df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu            mNumItems = mItemLengths.length;
191062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        }
192062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
193f7726a8422c64f43180291a0f660d3ed065e0f9eDake Gu        mGridView.setAdapter(adapter);
194062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        setContentView(view);
195062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    }
196062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
19789b4aed6fcd80f940531e265936ab908a8037f87Dake Gu    void rebindToNewAdapter() {
19889b4aed6fcd80f940531e265936ab908a8037f87Dake Gu        mGridView.setAdapter(new MyAdapter());
19989b4aed6fcd80f940531e265936ab908a8037f87Dake Gu    }
20089b4aed6fcd80f940531e265936ab908a8037f87Dake Gu
201062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    @Override
202062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    protected void onNewIntent(Intent intent) {
203062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        if (DEBUG) Log.v(TAG, "onNewIntent " + intent+ " "+this);
204062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        if (intent.getAction().equals(SELECT_ACTION)) {
205062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu            int position = intent.getIntExtra("SELECT_POSITION", -1);
206062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu            if (position >= 0) {
207062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu                mGridView.setSelectedPosition(position);
208062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu            }
209062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        }
210062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        super.onNewIntent(intent);
211062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    }
212062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
213062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    private OnFocusChangeListener mItemFocusChangeListener = new OnFocusChangeListener() {
214062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
215062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        @Override
216062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        public void onFocusChange(View v, boolean hasFocus) {
217062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu            if (hasFocus) {
218062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu                v.setBackgroundColor(Color.YELLOW);
219062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu            } else {
220062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu                v.setBackgroundColor(Color.LTGRAY);
221062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu            }
222fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu            if (mRequestLayoutOnFocus) {
223fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu                RecyclerView.ViewHolder vh = mGridView.getChildViewHolder(v);
224fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu                int position = vh.getAdapterPosition();
225fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu                updateSize(v, position);
226fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu            }
227062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        }
228062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    };
229062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
230c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu    private OnFocusChangeListener mSubItemFocusChangeListener = new OnFocusChangeListener() {
231c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu
232c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        @Override
233c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        public void onFocusChange(View v, boolean hasFocus) {
234c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu            if (hasFocus) {
235c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu                v.setBackgroundColor(Color.YELLOW);
236c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu            } else {
237c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu                v.setBackgroundColor(Color.LTGRAY);
238c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu            }
239c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        }
240c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu    };
241c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu
242e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu    void resetBoundCount() {
243e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        mBoundCount = 0;
244e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu    }
245e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu
246e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu    int getBoundCount() {
247e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu       return mBoundCount;
248e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu    }
249e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu
25085df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu    void swap(int index1, int index2) {
25185df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        if (index1 == index2) {
25285df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu            return;
25385df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        } else if (index1 > index2) {
25485df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu            int index = index1;
25585df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu            index1 = index2;
25685df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu            index2 = index;
25785df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        }
25885df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        int value = mItemLengths[index1];
25985df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        mItemLengths[index1] = mItemLengths[index2];
26085df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        mItemLengths[index2] = value;
26185df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        mGridView.getAdapter().notifyItemMoved(index1, index2);
26285df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        mGridView.getAdapter().notifyItemMoved(index2 - 1, index1);
26385df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu    }
26485df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
26585df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu    void changeArraySize(int length) {
26685df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        mNumItems = length;
26785df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        mGridView.getAdapter().notifyDataSetChanged();
26885df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu    }
26985df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
270ede7fd3c91008fb042c736240534d0d87234f112Dake Gu    int[] removeItems(int index, int length) {
271ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        int[] removed = new int[length];
272ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        System.arraycopy(mItemLengths, index, removed, 0, length);
273ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        System.arraycopy(mItemLengths, index + length, mItemLengths, index,
274ede7fd3c91008fb042c736240534d0d87234f112Dake Gu                mNumItems - index - length);
275ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        mNumItems -= length;
276936fd406f49a6fae8768084e84fa7d1beccf40a9Dake Gu        if (mGridView.getAdapter() != null) {
277936fd406f49a6fae8768084e84fa7d1beccf40a9Dake Gu            mGridView.getAdapter().notifyItemRangeRemoved(index, length);
278936fd406f49a6fae8768084e84fa7d1beccf40a9Dake Gu        }
279ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        return removed;
280ede7fd3c91008fb042c736240534d0d87234f112Dake Gu    }
281ede7fd3c91008fb042c736240534d0d87234f112Dake Gu
282e2f2ff730ed20153aa006d655888190763c16d5cDake Gu    void attachToNewAdapter(int[] items) {
283e2f2ff730ed20153aa006d655888190763c16d5cDake Gu        mItemLengths = items;
284e2f2ff730ed20153aa006d655888190763c16d5cDake Gu        mNumItems = items.length;
285e2f2ff730ed20153aa006d655888190763c16d5cDake Gu        mGridView.setAdapter(new MyAdapter());
286e2f2ff730ed20153aa006d655888190763c16d5cDake Gu    }
287e2f2ff730ed20153aa006d655888190763c16d5cDake Gu
288e2f2ff730ed20153aa006d655888190763c16d5cDake Gu
289ede7fd3c91008fb042c736240534d0d87234f112Dake Gu    void addItems(int index, int[] items) {
290ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        int length = items.length;
29157f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        if (mItemLengths.length < mNumItems + length) {
29257f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu            int[] array = new int[mNumItems + length];
29357f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu            System.arraycopy(mItemLengths, 0, array, 0, mNumItems);
29457f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu            mItemLengths = array;
29557f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        }
296ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        System.arraycopy(mItemLengths, index, mItemLengths, index + length, mNumItems - index);
297ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        System.arraycopy(items, 0, mItemLengths, index, length);
298ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        mNumItems += length;
299936fd406f49a6fae8768084e84fa7d1beccf40a9Dake Gu        if (mGridView.getAdapter() != null) {
300936fd406f49a6fae8768084e84fa7d1beccf40a9Dake Gu            mGridView.getAdapter().notifyItemRangeInserted(index, length);
301936fd406f49a6fae8768084e84fa7d1beccf40a9Dake Gu        }
302ede7fd3c91008fb042c736240534d0d87234f112Dake Gu    }
303ede7fd3c91008fb042c736240534d0d87234f112Dake Gu
30408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    class MyAdapter extends RecyclerView.Adapter implements FacetProviderAdapter {
30508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
30608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        @Override
30708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        public int getItemViewType(int position) {
30808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            if (mViewTypeProvider != null) {
30908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                return mViewTypeProvider.getViewType(position);
31008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            }
31108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            return 0;
31208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        }
31308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
31408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        @Override
31508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        public FacetProvider getFacetProvider(int viewType) {
31608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            final Object alignmentFacet = mAlignmentViewTypeProvider != null?
31708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                mAlignmentViewTypeProvider.getItemAlignmentFacet(viewType) : null;
31808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            if (alignmentFacet != null) {
31908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                return new FacetProvider() {
32008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                    @Override
32108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                    public Object getFacet(Class facetClass) {
32208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                        if (facetClass.equals(ItemAlignmentFacet.class)) {
32308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                            return alignmentFacet;
32408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                        }
32508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                        return null;
32608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                    }
32708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                };
32808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            }
32908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            return null;
33008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        }
331062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
332062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        @Override
333062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
334062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu            if (DEBUG) Log.v(TAG, "createViewHolder " + viewType);
3355509e275a04396bfb16b3a217c5392a864398174Dake Gu            View itemView;
336c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu            if (mChildLayout != -1) {
337362fda0323b85ec2379967901a0bd33a2ad4b8b5Dake Gu                final View view = getLayoutInflater().inflate(mChildLayout, parent, false);
338c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu                ArrayList<View> focusables = new ArrayList<View>();
339c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu                view.addFocusables(focusables, View.FOCUS_UP);
340c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu                for (int i = 0; i < focusables.size(); i++) {
341c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu                    View f = focusables.get(i);
3423bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu                    f.setBackgroundColor(Color.LTGRAY);
343c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu                    f.setOnFocusChangeListener(new OnFocusChangeListener() {
344c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu                        @Override
345c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu                        public void onFocusChange(View v, boolean hasFocus) {
346c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu                            if (hasFocus) {
347c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu                                v.setBackgroundColor(Color.YELLOW);
348c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu                            } else {
349c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu                                v.setBackgroundColor(Color.LTGRAY);
350c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu                            }
351c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu                            if (mRequestLayoutOnFocus) {
3523bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu                                if (v == view) {
3533bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu                                    RecyclerView.ViewHolder vh = mGridView.getChildViewHolder(v);
3543bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu                                    int position = vh.getAdapterPosition();
3553bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu                                    updateSize(v, position);
3563bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu                                }
357c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu                                view.requestLayout();
358c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu                            }
359c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu                        }
360c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu                    });
361c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu                }
3625509e275a04396bfb16b3a217c5392a864398174Dake Gu                itemView = view;
3635509e275a04396bfb16b3a217c5392a864398174Dake Gu            } else {
3645509e275a04396bfb16b3a217c5392a864398174Dake Gu                TextView textView = new TextView(parent.getContext()) {
3655509e275a04396bfb16b3a217c5392a864398174Dake Gu                    @Override
3665509e275a04396bfb16b3a217c5392a864398174Dake Gu                    protected void onLayout(boolean change, int left, int top, int right,
3675509e275a04396bfb16b3a217c5392a864398174Dake Gu                            int bottom) {
3685509e275a04396bfb16b3a217c5392a864398174Dake Gu                        super.onLayout(change, left, top, right, bottom);
3695509e275a04396bfb16b3a217c5392a864398174Dake Gu                        if (mRequestFocusOnLayout) {
3705509e275a04396bfb16b3a217c5392a864398174Dake Gu                            if (hasFocus()) {
3715509e275a04396bfb16b3a217c5392a864398174Dake Gu                                clearFocus();
3725509e275a04396bfb16b3a217c5392a864398174Dake Gu                                requestFocus();
3735509e275a04396bfb16b3a217c5392a864398174Dake Gu                            }
3743a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu                        }
3753a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu                    }
3765509e275a04396bfb16b3a217c5392a864398174Dake Gu                };
3775509e275a04396bfb16b3a217c5392a864398174Dake Gu                textView.setTextColor(Color.BLACK);
3785509e275a04396bfb16b3a217c5392a864398174Dake Gu                textView.setOnFocusChangeListener(mItemFocusChangeListener);
3795509e275a04396bfb16b3a217c5392a864398174Dake Gu                itemView = textView;
3805509e275a04396bfb16b3a217c5392a864398174Dake Gu            }
3815509e275a04396bfb16b3a217c5392a864398174Dake Gu            if (mLayoutMargins != null) {
3825509e275a04396bfb16b3a217c5392a864398174Dake Gu                ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams)
3835509e275a04396bfb16b3a217c5392a864398174Dake Gu                        itemView.getLayoutParams();
3845509e275a04396bfb16b3a217c5392a864398174Dake Gu                if (lp == null) {
3855509e275a04396bfb16b3a217c5392a864398174Dake Gu                    lp = new ViewGroup.MarginLayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
3865509e275a04396bfb16b3a217c5392a864398174Dake Gu                            ViewGroup.LayoutParams.WRAP_CONTENT);
3873a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu                }
3885509e275a04396bfb16b3a217c5392a864398174Dake Gu                lp.leftMargin = mLayoutMargins[0];
3895509e275a04396bfb16b3a217c5392a864398174Dake Gu                lp.topMargin = mLayoutMargins[1];
3905509e275a04396bfb16b3a217c5392a864398174Dake Gu                lp.rightMargin = mLayoutMargins[2];
3915509e275a04396bfb16b3a217c5392a864398174Dake Gu                lp.bottomMargin = mLayoutMargins[3];
3925509e275a04396bfb16b3a217c5392a864398174Dake Gu                itemView.setLayoutParams(lp);
3935509e275a04396bfb16b3a217c5392a864398174Dake Gu            }
394e2443a93fcb82151f5290b89617b34b69442fdd3Dake Gu            if (mNinePatchShadow != 0) {
395e2443a93fcb82151f5290b89617b34b69442fdd3Dake Gu                ViewGroup viewGroup = (ViewGroup) itemView;
396e2443a93fcb82151f5290b89617b34b69442fdd3Dake Gu                View shadow = new View(viewGroup.getContext());
397e2443a93fcb82151f5290b89617b34b69442fdd3Dake Gu                shadow.setBackgroundResource(mNinePatchShadow);
398e2443a93fcb82151f5290b89617b34b69442fdd3Dake Gu                viewGroup.addView(shadow);
399e2443a93fcb82151f5290b89617b34b69442fdd3Dake Gu                viewGroup.setLayoutMode(ViewGroup.LAYOUT_MODE_OPTICAL_BOUNDS);
400e2443a93fcb82151f5290b89617b34b69442fdd3Dake Gu            }
4015509e275a04396bfb16b3a217c5392a864398174Dake Gu            return new ViewHolder(itemView);
402062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        }
403062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
404062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        @Override
405062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        public void onBindViewHolder(RecyclerView.ViewHolder baseHolder, int position) {
406062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu            if (DEBUG) Log.v(TAG, "bindViewHolder " + position + " " + baseHolder);
407e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            mBoundCount++;
408062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu            ViewHolder holder = (ViewHolder) baseHolder;
40908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            if (mAlignmentProvider != null) {
41008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                holder.mItemAlignment = mAlignmentProvider.getItemAlignmentFacet(position);
41108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            } else {
41208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                holder.mItemAlignment = null;
41308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            }
414c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu            if (mChildLayout == -1) {
41500e05297683e1cc2a5fb25a00632a778b7b5d0e4Dake Gu                ((TextView) holder.itemView).setText("Item "+mItemLengths[position]
41600e05297683e1cc2a5fb25a00632a778b7b5d0e4Dake Gu                        + " type=" + getItemViewType(position));
417c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu                boolean focusable = true;
418c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu                if (mItemFocusables != null) {
419c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu                    focusable = mItemFocusables[position];
420c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu                }
421c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu                ((TextView) holder.itemView).setFocusable(focusable);
422c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu                ((TextView) holder.itemView).setFocusableInTouchMode(focusable);
423c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu                holder.itemView.setBackgroundColor(Color.LTGRAY);
4243bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu            } else {
4253bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu                if (holder.itemView instanceof TextView) {
42600e05297683e1cc2a5fb25a00632a778b7b5d0e4Dake Gu                    ((TextView) holder.itemView).setText("Item "+mItemLengths[position]
42700e05297683e1cc2a5fb25a00632a778b7b5d0e4Dake Gu                            + " type=" + getItemViewType(position));
4283bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu                }
42977b17ebed6d1f8488b150b25e2b6754971480caeDake Gu            }
430fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu            updateSize(holder.itemView, position);
431362fda0323b85ec2379967901a0bd33a2ad4b8b5Dake Gu            if (mAdapterListener != null) {
432362fda0323b85ec2379967901a0bd33a2ad4b8b5Dake Gu                mAdapterListener.onBind(baseHolder, position);
433362fda0323b85ec2379967901a0bd33a2ad4b8b5Dake Gu            }
434062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        }
435062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
436062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        @Override
437062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        public int getItemCount() {
43885df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu            return mNumItems;
439062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        }
44000e05297683e1cc2a5fb25a00632a778b7b5d0e4Dake Gu
441062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    }
442062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
443fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu    void updateSize(View view, int position) {
444362fda0323b85ec2379967901a0bd33a2ad4b8b5Dake Gu        if (!mUpdateSize) {
445362fda0323b85ec2379967901a0bd33a2ad4b8b5Dake Gu            return;
446362fda0323b85ec2379967901a0bd33a2ad4b8b5Dake Gu        }
447fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        ViewGroup.LayoutParams p = view.getLayoutParams();
448fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        if (p == null) {
449fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu            p = new ViewGroup.LayoutParams(0, 0);
450fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        }
451fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        if (mOrientation == BaseGridView.HORIZONTAL) {
452fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu            p.width = mItemLengths[position] + (mRequestLayoutOnFocus && view.hasFocus() ? 1 : 0);
4531a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu            p.height = mSecondarySizeZero ? 0 : 80;
454fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        } else {
4551a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu            p.width = mSecondarySizeZero ? 0 : 240;
456fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu            p.height = mItemLengths[position] + (mRequestLayoutOnFocus && view.hasFocus() ? 1 : 0);
457fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        }
458fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        view.setLayoutParams(p);
459fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu    }
460fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu
46108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    static class ViewHolder extends RecyclerView.ViewHolder implements FacetProvider {
462062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
46308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        ItemAlignmentFacet mItemAlignment;
464062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        public ViewHolder(View v) {
465062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu            super(v);
466062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        }
46708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
46808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        @Override
46908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        public Object getFacet(Class facetClass) {
47008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            if (facetClass.equals(ItemAlignmentFacet.class)) {
47108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                return mItemAlignment;
47208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            }
47308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            return null;
47408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        }
475062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    }
476062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu}
477