FolderPagedView.java revision 317698bd012c1930b83bb4e2e47ac9e363fa6c6a
1290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal/**
2290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal * Copyright (C) 2015 The Android Open Source Project
3290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal *
4290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal * Licensed under the Apache License, Version 2.0 (the "License");
5290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal * you may not use this file except in compliance with the License.
6290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal * You may obtain a copy of the License at
7290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal *
8290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal *      http://www.apache.org/licenses/LICENSE-2.0
9290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal *
10290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal * Unless required by applicable law or agreed to in writing, software
11290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal * distributed under the License is distributed on an "AS IS" BASIS,
12290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal * See the License for the specific language governing permissions and
14290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal * limitations under the License.
15290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal */
16290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
17290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyalpackage com.android.launcher3;
18290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
19e4766230ff8115c5897ebee74c145bcae822581eSunny Goyalimport android.annotation.SuppressLint;
20290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyalimport android.content.Context;
21290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyalimport android.util.AttributeSet;
22290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyalimport android.util.Log;
23b7e15adc7b67cb1d70ca72014b200dd6cbbf166aSunny Goyalimport android.view.Gravity;
24290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyalimport android.view.LayoutInflater;
25290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyalimport android.view.View;
264846193300245c8c0a1f9bde3175f273df044309Sunny Goyalimport android.view.animation.DecelerateInterpolator;
27a07c2f5c80908e8a612f4681314a7068b92baa9fSunny Goyalimport android.view.animation.Interpolator;
28b7e15adc7b67cb1d70ca72014b200dd6cbbf166aSunny Goyalimport android.view.animation.OvershootInterpolator;
29290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
30290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyalimport com.android.launcher3.FocusHelper.PagedFolderKeyEventListener;
31290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyalimport com.android.launcher3.PageIndicator.PageMarkerResources;
32290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyalimport com.android.launcher3.Workspace.ItemOperator;
33091440a9cb9d4f42406631004aa484cbb79214caAdam Cohenimport com.android.launcher3.util.Thunk;
34290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
35290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyalimport java.util.ArrayList;
36290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyalimport java.util.HashMap;
37290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyalimport java.util.Iterator;
384846193300245c8c0a1f9bde3175f273df044309Sunny Goyalimport java.util.Map;
39290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
40b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyalpublic class FolderPagedView extends PagedView {
41290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
42290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    private static final String TAG = "FolderPagedView";
43290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
44b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal    private static final boolean ALLOW_FOLDER_SCROLL = true;
45b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal
46290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    private static final int REORDER_ANIMATION_DURATION = 230;
474846193300245c8c0a1f9bde3175f273df044309Sunny Goyal    private static final int START_VIEW_REORDER_DELAY = 30;
484846193300245c8c0a1f9bde3175f273df044309Sunny Goyal    private static final float VIEW_REORDER_DELAY_FACTOR = 0.9f;
495d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal
50a07c2f5c80908e8a612f4681314a7068b92baa9fSunny Goyal    private static final int PAGE_INDICATOR_ANIMATION_START_DELAY = 300;
51a07c2f5c80908e8a612f4681314a7068b92baa9fSunny Goyal    private static final int PAGE_INDICATOR_ANIMATION_STAGGERED_DELAY = 150;
52a07c2f5c80908e8a612f4681314a7068b92baa9fSunny Goyal    private static final int PAGE_INDICATOR_ANIMATION_DURATION = 400;
53a07c2f5c80908e8a612f4681314a7068b92baa9fSunny Goyal
54a07c2f5c80908e8a612f4681314a7068b92baa9fSunny Goyal    // This value approximately overshoots to 1.5 times the original size.
55a07c2f5c80908e8a612f4681314a7068b92baa9fSunny Goyal    private static final float PAGE_INDICATOR_OVERSHOOT_TENSION = 4.9f;
56b7e15adc7b67cb1d70ca72014b200dd6cbbf166aSunny Goyal
573b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal    /**
583b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal     * Fraction of the width to scroll when showing the next page hint.
593b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal     */
603b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal    private static final float SCROLL_HINT_FRACTION = 0.07f;
613b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal
62290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    private static final int[] sTempPosArray = new int[2];
63290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
647066003b2032a49ae5e59dab9b706259bdeb7e6eSunny Goyal    public final boolean mIsRtl;
653b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal
66290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    private final LayoutInflater mInflater;
67290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    private final IconCache mIconCache;
68091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen
69091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen    @Thunk final HashMap<View, Runnable> mPendingAnimations = new HashMap<>();
70290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
71e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal    private final int mMaxCountX;
72e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal    private final int mMaxCountY;
73e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal    private final int mMaxItemsPerPage;
74290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
75290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    private int mAllocatedContentSize;
76290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    private int mGridCountX;
77290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    private int mGridCountY;
78290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
79290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    private Folder mFolder;
80290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    private FocusIndicatorView mFocusIndicatorView;
81290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    private PagedFolderKeyEventListener mKeyListener;
82290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
83b7e15adc7b67cb1d70ca72014b200dd6cbbf166aSunny Goyal    private PageIndicator mPageIndicator;
845d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal
85290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    public FolderPagedView(Context context, AttributeSet attrs) {
86290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        super(context, attrs);
87290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        LauncherAppState app = LauncherAppState.getInstance();
88290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
892e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen        InvariantDeviceProfile profile = app.getInvariantDeviceProfile();
902c6e5ccbcd7c3f87e7e85029782440600dc0a3d8Winson Chung        mMaxCountX = profile.numFolderColumns;
912c6e5ccbcd7c3f87e7e85029782440600dc0a3d8Winson Chung        mMaxCountY = profile.numFolderRows;
92b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal
93290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        mMaxItemsPerPage = mMaxCountX * mMaxCountY;
94290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
95290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        mInflater = LayoutInflater.from(context);
96290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        mIconCache = app.getIconCache();
973b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal
987066003b2032a49ae5e59dab9b706259bdeb7e6eSunny Goyal        mIsRtl = Utilities.isRtl(getResources());
99db184fdc7bd652e45216a453541ab4a266457a3aSunny Goyal        setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
1004d113a5ff44ff1a7f19263bde21581fbf9a54212Sunny Goyal
1014d113a5ff44ff1a7f19263bde21581fbf9a54212Sunny Goyal        setEdgeGlowColor(getResources().getColor(R.color.folder_edge_effect_color));
102290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    }
103290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
104290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    public void setFolder(Folder folder) {
105290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        mFolder = folder;
106290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        mFocusIndicatorView = (FocusIndicatorView) folder.findViewById(R.id.focus_indicator);
107290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        mKeyListener = new PagedFolderKeyEventListener(folder);
108b7e15adc7b67cb1d70ca72014b200dd6cbbf166aSunny Goyal        mPageIndicator = (PageIndicator) folder.findViewById(R.id.folder_page_indicator);
109290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    }
110290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
111290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    /**
112290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal     * Sets up the grid size such that {@param count} items can fit in the grid.
113290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal     * The grid size is calculated such that countY <= countX and countX = ceil(sqrt(count)) while
114290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal     * maintaining the restrictions of {@link #mMaxCountX} &amp; {@link #mMaxCountY}.
115290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal     */
116290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    private void setupContentDimensions(int count) {
117290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        mAllocatedContentSize = count;
118290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        boolean done;
119290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        if (count >= mMaxItemsPerPage) {
120290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            mGridCountX = mMaxCountX;
121290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            mGridCountY = mMaxCountY;
122290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            done = true;
123290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        } else {
124290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            done = false;
125290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        }
126290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
127290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        while (!done) {
128290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            int oldCountX = mGridCountX;
129290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            int oldCountY = mGridCountY;
130290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            if (mGridCountX * mGridCountY < count) {
131290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                // Current grid is too small, expand it
132290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                if ((mGridCountX <= mGridCountY || mGridCountY == mMaxCountY) && mGridCountX < mMaxCountX) {
133290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                    mGridCountX++;
134290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                } else if (mGridCountY < mMaxCountY) {
135290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                    mGridCountY++;
136290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                }
137290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                if (mGridCountY == 0) mGridCountY++;
138290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            } else if ((mGridCountY - 1) * mGridCountX >= count && mGridCountY >= mGridCountX) {
139290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                mGridCountY = Math.max(0, mGridCountY - 1);
140290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            } else if ((mGridCountX - 1) * mGridCountY >= count) {
141290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                mGridCountX = Math.max(0, mGridCountX - 1);
142290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            }
143290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            done = mGridCountX == oldCountX && mGridCountY == oldCountY;
144290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        }
145290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
146e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal        // Update grid size
147e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal        for (int i = getPageCount() - 1; i >= 0; i--) {
148290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            getPageAt(i).setGridSize(mGridCountX, mGridCountY);
149290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        }
150290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    }
151290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
152b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal    /**
153b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal     * Binds items to the layout.
154b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal     * @return list of items that could not be bound, probably because we hit the max size limit.
155b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal     */
156290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    public ArrayList<ShortcutInfo> bindItems(ArrayList<ShortcutInfo> items) {
157e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal        ArrayList<View> icons = new ArrayList<View>();
158b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal        ArrayList<ShortcutInfo> extra = new ArrayList<ShortcutInfo>();
159b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal
160290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        for (ShortcutInfo item : items) {
161b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal            if (!ALLOW_FOLDER_SCROLL && icons.size() >= mMaxItemsPerPage) {
162b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal                extra.add(item);
163b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal            } else {
164b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal                icons.add(createNewView(item));
165b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal            }
166290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        }
167e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal        arrangeChildren(icons, icons.size(), false);
168b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal        return extra;
169290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    }
170290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
171290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    /**
172290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal     * Create space for a new item at the end, and returns the rank for that item.
173290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal     * Also sets the current page to the last page.
174290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal     */
1755d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal    public int allocateRankForNewItem(ShortcutInfo info) {
176290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        int rank = getItemCount();
1775d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal        ArrayList<View> views = new ArrayList<View>(mFolder.getItemsInReadingOrder());
1785d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal        views.add(rank, null);
1795d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal        arrangeChildren(views, views.size(), false);
1805d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal        setCurrentPage(rank / mMaxItemsPerPage);
181290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        return rank;
182290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    }
183290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
184290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    public View createAndAddViewForRank(ShortcutInfo item, int rank) {
185e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal        View icon = createNewView(item);
1865d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal        addViewForRank(icon, item, rank);
187e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal        return icon;
188290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    }
189290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
190b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal    /**
191b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal     * Adds the {@param view} to the layout based on {@param rank} and updated the position
192b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal     * related attributes. It assumes that {@param item} is already attached to the view.
193b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal     */
194290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    public void addViewForRank(View view, ShortcutInfo item, int rank) {
195e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal        int pagePos = rank % mMaxItemsPerPage;
196e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal        int pageNo = rank / mMaxItemsPerPage;
197290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
198290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        item.rank = rank;
199290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        item.cellX = pagePos % mGridCountX;
200290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        item.cellY = pagePos / mGridCountX;
201290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
202e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal        CellLayout.LayoutParams lp = (CellLayout.LayoutParams) view.getLayoutParams();
203e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal        lp.cellX = item.cellX;
204e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal        lp.cellY = item.cellY;
205e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal        getPageAt(pageNo).addViewToCellLayout(
206e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal                view, -1, mFolder.mLauncher.getViewIdForItem(item), lp, true);
207290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    }
208290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
209e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal    @SuppressLint("InflateParams")
210b8c663c492d32963b6ee33750fc985f037c58f10Sunny Goyal    public View createNewView(ShortcutInfo item) {
211290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        final BubbleTextView textView = (BubbleTextView) mInflater.inflate(
212e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal                R.layout.folder_application, null, false);
213dfaccf64bd59343de483b12eee6db61c960aedceSunny Goyal        textView.applyFromShortcutInfo(item, mIconCache);
214290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        textView.setOnClickListener(mFolder);
215290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        textView.setOnLongClickListener(mFolder);
216290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        textView.setOnFocusChangeListener(mFocusIndicatorView);
217290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        textView.setOnKeyListener(mKeyListener);
218290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
219e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal        textView.setLayoutParams(new CellLayout.LayoutParams(
220e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal                item.cellX, item.cellY, item.spanX, item.spanY));
221290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        return textView;
222290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    }
223290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
224290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    @Override
225290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    public CellLayout getPageAt(int index) {
226290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        return (CellLayout) getChildAt(index);
227290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    }
228290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
229290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    public void removeCellLayoutView(View view) {
230290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        for (int i = getChildCount() - 1; i >= 0; i --) {
231290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            getPageAt(i).removeView(view);
232290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        }
233290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    }
234290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
235290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    public CellLayout getCurrentCellLayout() {
236290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        return getPageAt(getNextPage());
237290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    }
238290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
239e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal    private CellLayout createAndAddNewPage() {
2402e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen        DeviceProfile grid = ((Launcher) getContext()).getDeviceProfile();
241e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal        CellLayout page = new CellLayout(getContext());
242e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal        page.setCellDimensions(grid.folderCellWidthPx, grid.folderCellHeightPx);
243e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal        page.getShortcutsAndWidgets().setMotionEventSplittingEnabled(false);
244db184fdc7bd652e45216a453541ab4a266457a3aSunny Goyal        page.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO);
245e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal        page.setInvertIfRtl(true);
246e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal        page.setGridSize(mGridCountX, mGridCountY);
247290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
24822fc63ee298335b5f5c603ea1b77dc0e6180b16aSunny Goyal        addView(page, -1, generateDefaultLayoutParams());
249e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal        return page;
250290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    }
251290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
252a1fbd84b791474a9e86b67caeaf27b8429afba73Sunny Goyal    @Override
253a1fbd84b791474a9e86b67caeaf27b8429afba73Sunny Goyal    protected int getChildGap() {
254a1fbd84b791474a9e86b67caeaf27b8429afba73Sunny Goyal        return getPaddingLeft() + getPaddingRight();
255a1fbd84b791474a9e86b67caeaf27b8429afba73Sunny Goyal    }
256a1fbd84b791474a9e86b67caeaf27b8429afba73Sunny Goyal
257290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    public void setFixedSize(int width, int height) {
25822fc63ee298335b5f5c603ea1b77dc0e6180b16aSunny Goyal        width -= (getPaddingLeft() + getPaddingRight());
25922fc63ee298335b5f5c603ea1b77dc0e6180b16aSunny Goyal        height -= (getPaddingTop() + getPaddingBottom());
260290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        for (int i = getChildCount() - 1; i >= 0; i --) {
261290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            ((CellLayout) getChildAt(i)).setFixedSize(width, height);
262290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        }
263290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    }
264290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
265290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    public void removeItem(View v) {
266290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        for (int i = getChildCount() - 1; i >= 0; i --) {
267290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            getPageAt(i).removeView(v);
268290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        }
269290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    }
270290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
271290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    /**
272290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal     * Updates position and rank of all the children in the view.
273290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal     * It essentially removes all views from all the pages and then adds them again in appropriate
274290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal     * page.
275290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal     *
276290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal     * @param list the ordered list of children.
277290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal     * @param itemCount if greater than the total children count, empty spaces are left
278290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal     * at the end, otherwise it is ignored.
279290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal     *
280290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal     */
281290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    public void arrangeChildren(ArrayList<View> list, int itemCount) {
282e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal        arrangeChildren(list, itemCount, true);
283e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal    }
284e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal
285a07c2f5c80908e8a612f4681314a7068b92baa9fSunny Goyal    @SuppressLint("RtlHardcoded")
286e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal    private void arrangeChildren(ArrayList<View> list, int itemCount, boolean saveChanges) {
287290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        ArrayList<CellLayout> pages = new ArrayList<CellLayout>();
288290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        for (int i = 0; i < getChildCount(); i++) {
289290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            CellLayout page = (CellLayout) getChildAt(i);
290290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            page.removeAllViews();
291290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            pages.add(page);
292290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        }
293290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        setupContentDimensions(itemCount);
294290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
295290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        Iterator<CellLayout> pageItr = pages.iterator();
296290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        CellLayout currentPage = null;
297290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
298290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        int position = 0;
299290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        int newX, newY, rank;
300290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
301290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        rank = 0;
3024846193300245c8c0a1f9bde3175f273df044309Sunny Goyal        for (int i = 0; i < itemCount; i++) {
3034846193300245c8c0a1f9bde3175f273df044309Sunny Goyal            View v = list.size() > i ? list.get(i) : null;
304290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            if (currentPage == null || position >= mMaxItemsPerPage) {
305290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                // Next page
306290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                if (pageItr.hasNext()) {
307290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                    currentPage = pageItr.next();
308290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                } else {
309e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal                    currentPage = createAndAddNewPage();
310290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                }
311290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                position = 0;
312290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            }
313290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
3144846193300245c8c0a1f9bde3175f273df044309Sunny Goyal            if (v != null) {
3154846193300245c8c0a1f9bde3175f273df044309Sunny Goyal                CellLayout.LayoutParams lp = (CellLayout.LayoutParams) v.getLayoutParams();
3164846193300245c8c0a1f9bde3175f273df044309Sunny Goyal                newX = position % mGridCountX;
3174846193300245c8c0a1f9bde3175f273df044309Sunny Goyal                newY = position / mGridCountX;
3184846193300245c8c0a1f9bde3175f273df044309Sunny Goyal                ItemInfo info = (ItemInfo) v.getTag();
3194846193300245c8c0a1f9bde3175f273df044309Sunny Goyal                if (info.cellX != newX || info.cellY != newY || info.rank != rank) {
3204846193300245c8c0a1f9bde3175f273df044309Sunny Goyal                    info.cellX = newX;
3214846193300245c8c0a1f9bde3175f273df044309Sunny Goyal                    info.cellY = newY;
3224846193300245c8c0a1f9bde3175f273df044309Sunny Goyal                    info.rank = rank;
3234846193300245c8c0a1f9bde3175f273df044309Sunny Goyal                    if (saveChanges) {
3244846193300245c8c0a1f9bde3175f273df044309Sunny Goyal                        LauncherModel.addOrMoveItemInDatabase(getContext(), info,
3254846193300245c8c0a1f9bde3175f273df044309Sunny Goyal                                mFolder.mInfo.id, 0, info.cellX, info.cellY);
3264846193300245c8c0a1f9bde3175f273df044309Sunny Goyal                    }
327e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal                }
3284846193300245c8c0a1f9bde3175f273df044309Sunny Goyal                lp.cellX = info.cellX;
3294846193300245c8c0a1f9bde3175f273df044309Sunny Goyal                lp.cellY = info.cellY;
3304846193300245c8c0a1f9bde3175f273df044309Sunny Goyal                currentPage.addViewToCellLayout(
3314846193300245c8c0a1f9bde3175f273df044309Sunny Goyal                        v, -1, mFolder.mLauncher.getViewIdForItem(info), lp, true);
332317698bd012c1930b83bb4e2e47ac9e363fa6c6aSunny Goyal
333317698bd012c1930b83bb4e2e47ac9e363fa6c6aSunny Goyal                if (rank < FolderIcon.NUM_ITEMS_IN_PREVIEW && v instanceof BubbleTextView) {
334317698bd012c1930b83bb4e2e47ac9e363fa6c6aSunny Goyal                    ((BubbleTextView) v).verifyHighRes();
335317698bd012c1930b83bb4e2e47ac9e363fa6c6aSunny Goyal                }
336290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            }
3374846193300245c8c0a1f9bde3175f273df044309Sunny Goyal
338290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            rank ++;
339290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            position++;
340290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        }
341290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
342e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal        // Remove extra views.
343290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        boolean removed = false;
344290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        while (pageItr.hasNext()) {
345e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal            removeView(pageItr.next());
346e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal            removed = true;
347290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        }
348290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        if (removed) {
349290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            setCurrentPage(0);
350290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        }
3515d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal
352b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal        setEnableOverscroll(getPageCount() > 1);
3535d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal
3545d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal        // Update footer
3558167dc2dcffbf4f68724bc1db2f5cfc1caf6a848Sunny Goyal        mPageIndicator.setVisibility(getPageCount() > 1 ? View.VISIBLE : View.GONE);
356a07c2f5c80908e8a612f4681314a7068b92baa9fSunny Goyal        // Set the gravity as LEFT or RIGHT instead of START, as START depends on the actual text.
357a07c2f5c80908e8a612f4681314a7068b92baa9fSunny Goyal        mFolder.mFolderName.setGravity(getPageCount() > 1 ?
358a07c2f5c80908e8a612f4681314a7068b92baa9fSunny Goyal                (mIsRtl ? Gravity.RIGHT : Gravity.LEFT) : Gravity.CENTER_HORIZONTAL);
359290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    }
360290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
361290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    public int getDesiredWidth() {
36222fc63ee298335b5f5c603ea1b77dc0e6180b16aSunny Goyal        return getPageCount() > 0 ?
36322fc63ee298335b5f5c603ea1b77dc0e6180b16aSunny Goyal                (getPageAt(0).getDesiredWidth() + getPaddingLeft() + getPaddingRight()) : 0;
364290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    }
365290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
366290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    public int getDesiredHeight()  {
36722fc63ee298335b5f5c603ea1b77dc0e6180b16aSunny Goyal        return  getPageCount() > 0 ?
36822fc63ee298335b5f5c603ea1b77dc0e6180b16aSunny Goyal                (getPageAt(0).getDesiredHeight() + getPaddingTop() + getPaddingBottom()) : 0;
369290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    }
370290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
371290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    public int getItemCount() {
372e85d7145222ba1311cd9280726d8419b84f2f94bSunny Goyal        int lastPageIndex = getChildCount() - 1;
373e85d7145222ba1311cd9280726d8419b84f2f94bSunny Goyal        if (lastPageIndex < 0) {
374e85d7145222ba1311cd9280726d8419b84f2f94bSunny Goyal            // If there are no pages, nothing has yet been added to the folder.
375e85d7145222ba1311cd9280726d8419b84f2f94bSunny Goyal            return 0;
3764846193300245c8c0a1f9bde3175f273df044309Sunny Goyal        }
377e85d7145222ba1311cd9280726d8419b84f2f94bSunny Goyal        return getPageAt(lastPageIndex).getShortcutsAndWidgets().getChildCount()
378e85d7145222ba1311cd9280726d8419b84f2f94bSunny Goyal                + lastPageIndex * mMaxItemsPerPage;
379290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    }
380290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
381b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal    /**
382b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal     * @return the rank of the cell nearest to the provided pixel position.
383b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal     */
384290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    public int findNearestArea(int pixelX, int pixelY) {
385290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        int pageIndex = getNextPage();
386290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        CellLayout page = getPageAt(pageIndex);
387f7a29e83f06909b378dba39c83a522375682710aSunny Goyal        page.findNearestArea(pixelX, pixelY, 1, 1, sTempPosArray);
388290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        if (mFolder.isLayoutRtl()) {
389290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            sTempPosArray[0] = page.getCountX() - sTempPosArray[0] - 1;
390290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        }
391290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        return Math.min(mAllocatedContentSize - 1,
392290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                pageIndex * mMaxItemsPerPage + sTempPosArray[1] * mGridCountX + sTempPosArray[0]);
393290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    }
394290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
395290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    @Override
396290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    protected PageMarkerResources getPageIndicatorMarker(int pageIndex) {
397d3d37090c485359e2cf62eb6aa8e70350d161689Sunny Goyal        return new PageMarkerResources(R.drawable.ic_pageindicator_current_folder,
398d3d37090c485359e2cf62eb6aa8e70350d161689Sunny Goyal                R.drawable.ic_pageindicator_default_folder);
399290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    }
400290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
401290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    public boolean isFull() {
402b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal        return !ALLOW_FOLDER_SCROLL && getItemCount() >= mMaxItemsPerPage;
403290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    }
404290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
405290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    public View getLastItem() {
406290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        if (getChildCount() < 1) {
407290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            return null;
408290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        }
409290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        ShortcutAndWidgetContainer lastContainer = getCurrentCellLayout().getShortcutsAndWidgets();
410290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        int lastRank = lastContainer.getChildCount() - 1;
411290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        if (mGridCountX > 0) {
412290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            return lastContainer.getChildAt(lastRank % mGridCountX, lastRank / mGridCountX);
413290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        } else {
414290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            return lastContainer.getChildAt(lastRank);
415290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        }
416290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    }
417290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
418b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal    /**
419b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal     * Iterates over all its items in a reading order.
420b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal     * @return the view for which the operator returned true.
421b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal     */
422290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    public View iterateOverItems(ItemOperator op) {
423290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        for (int k = 0 ; k < getChildCount(); k++) {
424290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            CellLayout page = getPageAt(k);
425290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            for (int j = 0; j < page.getCountY(); j++) {
426290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                for (int i = 0; i < page.getCountX(); i++) {
427290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                    View v = page.getChildAt(i, j);
428290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                    if ((v != null) && op.evaluate((ItemInfo) v.getTag(), v, this)) {
429290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                        return v;
430290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                    }
431290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                }
432290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            }
433290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        }
434290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        return null;
435290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    }
436290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
437290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    public String getAccessibilityDescription() {
438290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        return String.format(getContext().getString(R.string.folder_opened),
439290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                mGridCountX, mGridCountY);
440290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    }
441290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
442b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal    /**
443b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal     * Sets the focus on the first visible child.
444b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal     */
445290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    public void setFocusOnFirstChild() {
446290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        View firstChild = getCurrentCellLayout().getChildAt(0, 0);
447290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        if (firstChild != null) {
448290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            firstChild.requestFocus();
449290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        }
450290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    }
451290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
452290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    @Override
453290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    protected void notifyPageSwitchListener() {
454290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        super.notifyPageSwitchListener();
455290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        if (mFolder != null) {
456290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            mFolder.updateTextViewFocus();
457290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        }
458290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    }
459290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
4604846193300245c8c0a1f9bde3175f273df044309Sunny Goyal    /**
4614846193300245c8c0a1f9bde3175f273df044309Sunny Goyal     * Scrolls the current view by a fraction
4624846193300245c8c0a1f9bde3175f273df044309Sunny Goyal     */
4633b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal    public void showScrollHint(int direction) {
4647066003b2032a49ae5e59dab9b706259bdeb7e6eSunny Goyal        float fraction = (direction == DragController.SCROLL_LEFT) ^ mIsRtl
4653b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal                ? -SCROLL_HINT_FRACTION : SCROLL_HINT_FRACTION;
4664846193300245c8c0a1f9bde3175f273df044309Sunny Goyal        int hint = (int) (fraction * getWidth());
4674846193300245c8c0a1f9bde3175f273df044309Sunny Goyal        int scroll = getScrollForPage(getNextPage()) + hint;
4684d113a5ff44ff1a7f19263bde21581fbf9a54212Sunny Goyal        int delta = scroll - getScrollX();
4694846193300245c8c0a1f9bde3175f273df044309Sunny Goyal        if (delta != 0) {
4704846193300245c8c0a1f9bde3175f273df044309Sunny Goyal            mScroller.setInterpolator(new DecelerateInterpolator());
4714d113a5ff44ff1a7f19263bde21581fbf9a54212Sunny Goyal            mScroller.startScroll(getScrollX(), 0, delta, 0, Folder.SCROLL_HINT_DURATION);
4724846193300245c8c0a1f9bde3175f273df044309Sunny Goyal            invalidate();
4734846193300245c8c0a1f9bde3175f273df044309Sunny Goyal        }
4744846193300245c8c0a1f9bde3175f273df044309Sunny Goyal    }
4754846193300245c8c0a1f9bde3175f273df044309Sunny Goyal
4764846193300245c8c0a1f9bde3175f273df044309Sunny Goyal    public void clearScrollHint() {
4774d113a5ff44ff1a7f19263bde21581fbf9a54212Sunny Goyal        if (getScrollX() != getScrollForPage(getNextPage())) {
4784846193300245c8c0a1f9bde3175f273df044309Sunny Goyal            snapToPage(getNextPage());
4794846193300245c8c0a1f9bde3175f273df044309Sunny Goyal        }
4804846193300245c8c0a1f9bde3175f273df044309Sunny Goyal    }
4814846193300245c8c0a1f9bde3175f273df044309Sunny Goyal
4824846193300245c8c0a1f9bde3175f273df044309Sunny Goyal    /**
4834846193300245c8c0a1f9bde3175f273df044309Sunny Goyal     * Finish animation all the views which are animating across pages
4844846193300245c8c0a1f9bde3175f273df044309Sunny Goyal     */
4854846193300245c8c0a1f9bde3175f273df044309Sunny Goyal    public void completePendingPageChanges() {
4865d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal        if (!mPendingAnimations.isEmpty()) {
4875d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal            HashMap<View, Runnable> pendingViews = new HashMap<>(mPendingAnimations);
4884846193300245c8c0a1f9bde3175f273df044309Sunny Goyal            for (Map.Entry<View, Runnable> e : pendingViews.entrySet()) {
4894846193300245c8c0a1f9bde3175f273df044309Sunny Goyal                e.getKey().animate().cancel();
4904846193300245c8c0a1f9bde3175f273df044309Sunny Goyal                e.getValue().run();
4914846193300245c8c0a1f9bde3175f273df044309Sunny Goyal            }
4924846193300245c8c0a1f9bde3175f273df044309Sunny Goyal        }
4934846193300245c8c0a1f9bde3175f273df044309Sunny Goyal    }
4944846193300245c8c0a1f9bde3175f273df044309Sunny Goyal
4954846193300245c8c0a1f9bde3175f273df044309Sunny Goyal    public boolean rankOnCurrentPage(int rank) {
4964846193300245c8c0a1f9bde3175f273df044309Sunny Goyal        int p = rank / mMaxItemsPerPage;
4974846193300245c8c0a1f9bde3175f273df044309Sunny Goyal        return p == getNextPage();
4984846193300245c8c0a1f9bde3175f273df044309Sunny Goyal    }
4994846193300245c8c0a1f9bde3175f273df044309Sunny Goyal
500290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    @Override
50134b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal    protected void onPageBeginMoving() {
50234b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal        super.onPageBeginMoving();
50334b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal        getVisiblePages(sTempPosArray);
50434b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal        for (int i = sTempPosArray[0]; i <= sTempPosArray[1]; i++) {
50534b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal            verifyVisibleHighResIcons(i);
50634b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal        }
50734b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal    }
50834b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal
50934b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal    /**
51034b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal     * Ensures that all the icons on the given page are of high-res
51134b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal     */
51234b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal    public void verifyVisibleHighResIcons(int pageNo) {
51334b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal        CellLayout page = getPageAt(pageNo);
51434b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal        if (page != null) {
51534b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal            ShortcutAndWidgetContainer parent = page.getShortcutsAndWidgets();
51634b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal            for (int i = parent.getChildCount() - 1; i >= 0; i--) {
51734b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal                ((BubbleTextView) parent.getChildAt(i)).verifyHighRes();
51834b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal            }
51934b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal        }
52034b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal    }
52134b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal
522ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal    public int getAllocatedContentSize() {
523ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal        return mAllocatedContentSize;
524ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal    }
525ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal
526b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal    /**
527b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal     * Reorders the items such that the {@param empty} spot moves to {@param target}
528b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal     */
529290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    public void realTimeReorder(int empty, int target) {
5304846193300245c8c0a1f9bde3175f273df044309Sunny Goyal        completePendingPageChanges();
531290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        int delay = 0;
5324846193300245c8c0a1f9bde3175f273df044309Sunny Goyal        float delayAmount = START_VIEW_REORDER_DELAY;
533290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
534290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        // Animation only happens on the current page.
535290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        int pageToAnimate = getNextPage();
536290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
537290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        int pageT = target / mMaxItemsPerPage;
538290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        int pagePosT = target % mMaxItemsPerPage;
539290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
540290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        if (pageT != pageToAnimate) {
541290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            Log.e(TAG, "Cannot animate when the target cell is invisible");
542290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        }
543290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        int pagePosE = empty % mMaxItemsPerPage;
544290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        int pageE = empty / mMaxItemsPerPage;
545290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
546290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        int startPos, endPos;
547290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        int moveStart, moveEnd;
548290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        int direction;
549290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
550290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        if (target == empty) {
551290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            // No animation
552290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            return;
553290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        } else if (target > empty) {
554290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            // Items will move backwards to make room for the empty cell.
555290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            direction = 1;
556290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
557290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            // If empty cell is in a different page, move them instantly.
558290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            if (pageE < pageToAnimate) {
559290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                moveStart = empty;
560290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                // Instantly move the first item in the current page.
561290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                moveEnd = pageToAnimate * mMaxItemsPerPage;
562290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                // Animate the 2nd item in the current page, as the first item was already moved to
563290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                // the last page.
564290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                startPos = 0;
565290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            } else {
566290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                moveStart = moveEnd = -1;
567290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                startPos = pagePosE;
568290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            }
569290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
570290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            endPos = pagePosT;
571290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        } else {
572290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            // The items will move forward.
573290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            direction = -1;
574290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
575290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            if (pageE > pageToAnimate) {
576290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                // Move the items immediately.
577290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                moveStart = empty;
578290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                // Instantly move the last item in the current page.
579290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                moveEnd = (pageToAnimate + 1) * mMaxItemsPerPage - 1;
580290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
581290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                // Animations start with the second last item in the page
582290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                startPos = mMaxItemsPerPage - 1;
583290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            } else {
584290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                moveStart = moveEnd = -1;
585290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                startPos = pagePosE;
586290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            }
587290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
588290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            endPos = pagePosT;
589290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        }
590290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
591290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        // Instant moving views.
592290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        while (moveStart != moveEnd) {
593290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            int rankToMove = moveStart + direction;
594290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            int p = rankToMove / mMaxItemsPerPage;
595290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            int pagePos = rankToMove % mMaxItemsPerPage;
596290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            int x = pagePos % mGridCountX;
597290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            int y = pagePos / mGridCountX;
598290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
599290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            final CellLayout page = getPageAt(p);
600290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            final View v = page.getChildAt(x, y);
601290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            if (v != null) {
602290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                if (pageToAnimate != p) {
603290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                    page.removeView(v);
604290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                    addViewForRank(v, (ShortcutInfo) v.getTag(), moveStart);
605290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                } else {
606290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                    // Do a fake animation before removing it.
607290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                    final int newRank = moveStart;
608290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                    final float oldTranslateX = v.getTranslationX();
609290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
610290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                    Runnable endAction = new Runnable() {
611290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
612290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                        @Override
613290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                        public void run() {
6145d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal                            mPendingAnimations.remove(v);
615290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                            v.setTranslationX(oldTranslateX);
616290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                            ((CellLayout) v.getParent().getParent()).removeView(v);
617290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                            addViewForRank(v, (ShortcutInfo) v.getTag(), newRank);
618290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                        }
619290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                    };
620290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                    v.animate()
6217066003b2032a49ae5e59dab9b706259bdeb7e6eSunny Goyal                        .translationXBy((direction > 0 ^ mIsRtl) ? -v.getWidth() : v.getWidth())
622290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                        .setDuration(REORDER_ANIMATION_DURATION)
623290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                        .setStartDelay(0)
624290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                        .withEndAction(endAction);
6255d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal                    mPendingAnimations.put(v, endAction);
626290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                }
627290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            }
628290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            moveStart = rankToMove;
629290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        }
630290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
631290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        if ((endPos - startPos) * direction <= 0) {
632290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            // No animation
633290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            return;
634290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        }
635290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal
636290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        CellLayout page = getPageAt(pageToAnimate);
637290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        for (int i = startPos; i != endPos; i += direction) {
638290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            int nextPos = i + direction;
639290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            View v = page.getChildAt(nextPos % mGridCountX, nextPos / mGridCountX);
640290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            if (v != null) {
641290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                ((ItemInfo) v.getTag()).rank -= direction;
642290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            }
643290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            if (page.animateChildToPosition(v, i % mGridCountX, i / mGridCountX,
644290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                    REORDER_ANIMATION_DURATION, delay, true, true)) {
645290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal                delay += delayAmount;
6464846193300245c8c0a1f9bde3175f273df044309Sunny Goyal                delayAmount *= VIEW_REORDER_DELAY_FACTOR;
647290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal            }
648290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal        }
649290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal    }
650b7e15adc7b67cb1d70ca72014b200dd6cbbf166aSunny Goyal
651b7e15adc7b67cb1d70ca72014b200dd6cbbf166aSunny Goyal    public void setMarkerScale(float scale) {
652b7e15adc7b67cb1d70ca72014b200dd6cbbf166aSunny Goyal        int count  = mPageIndicator.getChildCount();
653b7e15adc7b67cb1d70ca72014b200dd6cbbf166aSunny Goyal        for (int i = 0; i < count; i++) {
654b7e15adc7b67cb1d70ca72014b200dd6cbbf166aSunny Goyal            View marker = mPageIndicator.getChildAt(i);
655b7e15adc7b67cb1d70ca72014b200dd6cbbf166aSunny Goyal            marker.animate().cancel();
656b7e15adc7b67cb1d70ca72014b200dd6cbbf166aSunny Goyal            marker.setScaleX(scale);
657b7e15adc7b67cb1d70ca72014b200dd6cbbf166aSunny Goyal            marker.setScaleY(scale);
658b7e15adc7b67cb1d70ca72014b200dd6cbbf166aSunny Goyal        }
659b7e15adc7b67cb1d70ca72014b200dd6cbbf166aSunny Goyal    }
660b7e15adc7b67cb1d70ca72014b200dd6cbbf166aSunny Goyal
661b7e15adc7b67cb1d70ca72014b200dd6cbbf166aSunny Goyal    public void animateMarkers() {
662b7e15adc7b67cb1d70ca72014b200dd6cbbf166aSunny Goyal        int count  = mPageIndicator.getChildCount();
663a07c2f5c80908e8a612f4681314a7068b92baa9fSunny Goyal        Interpolator interpolator = new OvershootInterpolator(PAGE_INDICATOR_OVERSHOOT_TENSION);
664b7e15adc7b67cb1d70ca72014b200dd6cbbf166aSunny Goyal        for (int i = 0; i < count; i++) {
665b7e15adc7b67cb1d70ca72014b200dd6cbbf166aSunny Goyal            mPageIndicator.getChildAt(i).animate().scaleX(1).scaleY(1)
666b7e15adc7b67cb1d70ca72014b200dd6cbbf166aSunny Goyal                .setInterpolator(interpolator)
667a07c2f5c80908e8a612f4681314a7068b92baa9fSunny Goyal                .setDuration(PAGE_INDICATOR_ANIMATION_DURATION)
668a07c2f5c80908e8a612f4681314a7068b92baa9fSunny Goyal                .setStartDelay(PAGE_INDICATOR_ANIMATION_STAGGERED_DELAY * i
669a07c2f5c80908e8a612f4681314a7068b92baa9fSunny Goyal                        + PAGE_INDICATOR_ANIMATION_START_DELAY);
670b7e15adc7b67cb1d70ca72014b200dd6cbbf166aSunny Goyal        }
671b7e15adc7b67cb1d70ca72014b200dd6cbbf166aSunny Goyal    }
672b7e15adc7b67cb1d70ca72014b200dd6cbbf166aSunny Goyal
673b7e15adc7b67cb1d70ca72014b200dd6cbbf166aSunny Goyal    public int itemsPerPage() {
674b7e15adc7b67cb1d70ca72014b200dd6cbbf166aSunny Goyal        return mMaxItemsPerPage;
675b7e15adc7b67cb1d70ca72014b200dd6cbbf166aSunny Goyal    }
6764d113a5ff44ff1a7f19263bde21581fbf9a54212Sunny Goyal
6774d113a5ff44ff1a7f19263bde21581fbf9a54212Sunny Goyal    @Override
6784d113a5ff44ff1a7f19263bde21581fbf9a54212Sunny Goyal    protected void getEdgeVerticalPostion(int[] pos) {
6794d113a5ff44ff1a7f19263bde21581fbf9a54212Sunny Goyal        pos[0] = 0;
6804d113a5ff44ff1a7f19263bde21581fbf9a54212Sunny Goyal        pos[1] = getViewportHeight();
6814d113a5ff44ff1a7f19263bde21581fbf9a54212Sunny Goyal    }
682290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal}
683