FolderPagedView.java revision a1fbd84b791474a9e86b67caeaf27b8429afba73
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; 27b7e15adc7b67cb1d70ca72014b200dd6cbbf166aSunny Goyalimport android.view.animation.OvershootInterpolator; 28290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 29290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyalimport com.android.launcher3.FocusHelper.PagedFolderKeyEventListener; 30290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyalimport com.android.launcher3.PageIndicator.PageMarkerResources; 31290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyalimport com.android.launcher3.Workspace.ItemOperator; 32091440a9cb9d4f42406631004aa484cbb79214caAdam Cohenimport com.android.launcher3.util.Thunk; 33290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 34290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyalimport java.util.ArrayList; 35290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyalimport java.util.HashMap; 36290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyalimport java.util.Iterator; 374846193300245c8c0a1f9bde3175f273df044309Sunny Goyalimport java.util.Map; 38290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 39b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyalpublic class FolderPagedView extends PagedView { 40290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 41290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal private static final String TAG = "FolderPagedView"; 42290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 43b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal private static final boolean ALLOW_FOLDER_SCROLL = true; 44b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal 45290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal private static final int REORDER_ANIMATION_DURATION = 230; 464846193300245c8c0a1f9bde3175f273df044309Sunny Goyal private static final int START_VIEW_REORDER_DELAY = 30; 474846193300245c8c0a1f9bde3175f273df044309Sunny Goyal private static final float VIEW_REORDER_DELAY_FACTOR = 0.9f; 485d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal 49b7e15adc7b67cb1d70ca72014b200dd6cbbf166aSunny Goyal private static final int PAGE_INDICATOR_ANIMATION_DELAY = 150; 50b7e15adc7b67cb1d70ca72014b200dd6cbbf166aSunny Goyal 513b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal /** 523b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal * Fraction of the width to scroll when showing the next page hint. 533b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal */ 543b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal private static final float SCROLL_HINT_FRACTION = 0.07f; 553b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal 56290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal private static final int[] sTempPosArray = new int[2]; 57290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 587066003b2032a49ae5e59dab9b706259bdeb7e6eSunny Goyal public final boolean mIsRtl; 593b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal 60290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal private final LayoutInflater mInflater; 61290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal private final IconCache mIconCache; 62091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen 63091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk final HashMap<View, Runnable> mPendingAnimations = new HashMap<>(); 64290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 65e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal private final int mMaxCountX; 66e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal private final int mMaxCountY; 67e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal private final int mMaxItemsPerPage; 68290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 69290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal private int mAllocatedContentSize; 70290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal private int mGridCountX; 71290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal private int mGridCountY; 72290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 73290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal private Folder mFolder; 74290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal private FocusIndicatorView mFocusIndicatorView; 75290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal private PagedFolderKeyEventListener mKeyListener; 76290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 77b7e15adc7b67cb1d70ca72014b200dd6cbbf166aSunny Goyal private PageIndicator mPageIndicator; 785d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal 79290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal public FolderPagedView(Context context, AttributeSet attrs) { 80290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal super(context, attrs); 81290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal LauncherAppState app = LauncherAppState.getInstance(); 82290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 83290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal DeviceProfile grid = app.getDynamicGrid().getDeviceProfile(); 84fee35bbfac29a55382880f846fff86003e615ccbSunny Goyal mMaxCountX = (int) grid.numFolderColumns; 85fee35bbfac29a55382880f846fff86003e615ccbSunny Goyal mMaxCountY = (int) grid.numFolderRows; 86b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal 87290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal mMaxItemsPerPage = mMaxCountX * mMaxCountY; 88290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 89290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal mInflater = LayoutInflater.from(context); 90290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal mIconCache = app.getIconCache(); 913b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal 927066003b2032a49ae5e59dab9b706259bdeb7e6eSunny Goyal mIsRtl = Utilities.isRtl(getResources()); 93db184fdc7bd652e45216a453541ab4a266457a3aSunny Goyal setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES); 94290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 95290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 96290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal public void setFolder(Folder folder) { 97290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal mFolder = folder; 98290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal mFocusIndicatorView = (FocusIndicatorView) folder.findViewById(R.id.focus_indicator); 99290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal mKeyListener = new PagedFolderKeyEventListener(folder); 100b7e15adc7b67cb1d70ca72014b200dd6cbbf166aSunny Goyal mPageIndicator = (PageIndicator) folder.findViewById(R.id.folder_page_indicator); 101290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 102290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 103290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal /** 104290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal * Sets up the grid size such that {@param count} items can fit in the grid. 105290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal * The grid size is calculated such that countY <= countX and countX = ceil(sqrt(count)) while 106290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal * maintaining the restrictions of {@link #mMaxCountX} & {@link #mMaxCountY}. 107290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal */ 108290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal private void setupContentDimensions(int count) { 109290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal mAllocatedContentSize = count; 110290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal boolean done; 111290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal if (count >= mMaxItemsPerPage) { 112290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal mGridCountX = mMaxCountX; 113290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal mGridCountY = mMaxCountY; 114290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal done = true; 115290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } else { 116290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal done = false; 117290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 118290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 119290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal while (!done) { 120290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal int oldCountX = mGridCountX; 121290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal int oldCountY = mGridCountY; 122290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal if (mGridCountX * mGridCountY < count) { 123290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal // Current grid is too small, expand it 124290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal if ((mGridCountX <= mGridCountY || mGridCountY == mMaxCountY) && mGridCountX < mMaxCountX) { 125290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal mGridCountX++; 126290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } else if (mGridCountY < mMaxCountY) { 127290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal mGridCountY++; 128290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 129290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal if (mGridCountY == 0) mGridCountY++; 130290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } else if ((mGridCountY - 1) * mGridCountX >= count && mGridCountY >= mGridCountX) { 131290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal mGridCountY = Math.max(0, mGridCountY - 1); 132290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } else if ((mGridCountX - 1) * mGridCountY >= count) { 133290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal mGridCountX = Math.max(0, mGridCountX - 1); 134290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 135290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal done = mGridCountX == oldCountX && mGridCountY == oldCountY; 136290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 137290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 138e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal // Update grid size 139e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal for (int i = getPageCount() - 1; i >= 0; i--) { 140290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal getPageAt(i).setGridSize(mGridCountX, mGridCountY); 141290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 142290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 143290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 144b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal /** 145b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal * Binds items to the layout. 146b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal * @return list of items that could not be bound, probably because we hit the max size limit. 147b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal */ 148290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal public ArrayList<ShortcutInfo> bindItems(ArrayList<ShortcutInfo> items) { 149e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal ArrayList<View> icons = new ArrayList<View>(); 150b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal ArrayList<ShortcutInfo> extra = new ArrayList<ShortcutInfo>(); 151b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal 152290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal for (ShortcutInfo item : items) { 153b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal if (!ALLOW_FOLDER_SCROLL && icons.size() >= mMaxItemsPerPage) { 154b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal extra.add(item); 155b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal } else { 156b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal icons.add(createNewView(item)); 157b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal } 158290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 159e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal arrangeChildren(icons, icons.size(), false); 160b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal return extra; 161290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 162290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 163290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal /** 164290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal * Create space for a new item at the end, and returns the rank for that item. 165290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal * Also sets the current page to the last page. 166290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal */ 1675d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal public int allocateRankForNewItem(ShortcutInfo info) { 168290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal int rank = getItemCount(); 1695d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal ArrayList<View> views = new ArrayList<View>(mFolder.getItemsInReadingOrder()); 1705d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal views.add(rank, null); 1715d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal arrangeChildren(views, views.size(), false); 1725d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal setCurrentPage(rank / mMaxItemsPerPage); 173290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal return rank; 174290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 175290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 176290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal public View createAndAddViewForRank(ShortcutInfo item, int rank) { 177e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal View icon = createNewView(item); 1785d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal addViewForRank(icon, item, rank); 179e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal return icon; 180290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 181290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 182b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal /** 183b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal * Adds the {@param view} to the layout based on {@param rank} and updated the position 184b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal * related attributes. It assumes that {@param item} is already attached to the view. 185b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal */ 186290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal public void addViewForRank(View view, ShortcutInfo item, int rank) { 187e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal int pagePos = rank % mMaxItemsPerPage; 188e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal int pageNo = rank / mMaxItemsPerPage; 189290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 190290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal item.rank = rank; 191290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal item.cellX = pagePos % mGridCountX; 192290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal item.cellY = pagePos / mGridCountX; 193290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 194e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal CellLayout.LayoutParams lp = (CellLayout.LayoutParams) view.getLayoutParams(); 195e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal lp.cellX = item.cellX; 196e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal lp.cellY = item.cellY; 197e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal getPageAt(pageNo).addViewToCellLayout( 198e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal view, -1, mFolder.mLauncher.getViewIdForItem(item), lp, true); 199290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 200290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 201e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal @SuppressLint("InflateParams") 202b8c663c492d32963b6ee33750fc985f037c58f10Sunny Goyal public View createNewView(ShortcutInfo item) { 203290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal final BubbleTextView textView = (BubbleTextView) mInflater.inflate( 204e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal R.layout.folder_application, null, false); 205dfaccf64bd59343de483b12eee6db61c960aedceSunny Goyal textView.applyFromShortcutInfo(item, mIconCache); 206290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal textView.setOnClickListener(mFolder); 207290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal textView.setOnLongClickListener(mFolder); 208290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal textView.setOnFocusChangeListener(mFocusIndicatorView); 209290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal textView.setOnKeyListener(mKeyListener); 210290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 211e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal textView.setLayoutParams(new CellLayout.LayoutParams( 212e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal item.cellX, item.cellY, item.spanX, item.spanY)); 213290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal return textView; 214290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 215290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 216290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal @Override 217290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal public CellLayout getPageAt(int index) { 218290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal return (CellLayout) getChildAt(index); 219290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 220290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 221290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal public void removeCellLayoutView(View view) { 222290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal for (int i = getChildCount() - 1; i >= 0; i --) { 223290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal getPageAt(i).removeView(view); 224290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 225290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 226290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 227290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal public CellLayout getCurrentCellLayout() { 228290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal return getPageAt(getNextPage()); 229290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 230290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 231e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal private CellLayout createAndAddNewPage() { 232290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal DeviceProfile grid = LauncherAppState.getInstance().getDynamicGrid().getDeviceProfile(); 233e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal CellLayout page = new CellLayout(getContext()); 234e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal page.setCellDimensions(grid.folderCellWidthPx, grid.folderCellHeightPx); 235e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal page.getShortcutsAndWidgets().setMotionEventSplittingEnabled(false); 236db184fdc7bd652e45216a453541ab4a266457a3aSunny Goyal page.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO); 237e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal page.setInvertIfRtl(true); 238e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal page.setGridSize(mGridCountX, mGridCountY); 239290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 24022fc63ee298335b5f5c603ea1b77dc0e6180b16aSunny Goyal addView(page, -1, generateDefaultLayoutParams()); 241e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal return page; 242290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 243290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 244a1fbd84b791474a9e86b67caeaf27b8429afba73Sunny Goyal @Override 245a1fbd84b791474a9e86b67caeaf27b8429afba73Sunny Goyal protected int getChildGap() { 246a1fbd84b791474a9e86b67caeaf27b8429afba73Sunny Goyal return getPaddingLeft() + getPaddingRight(); 247a1fbd84b791474a9e86b67caeaf27b8429afba73Sunny Goyal } 248a1fbd84b791474a9e86b67caeaf27b8429afba73Sunny Goyal 249290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal public void setFixedSize(int width, int height) { 25022fc63ee298335b5f5c603ea1b77dc0e6180b16aSunny Goyal width -= (getPaddingLeft() + getPaddingRight()); 25122fc63ee298335b5f5c603ea1b77dc0e6180b16aSunny Goyal height -= (getPaddingTop() + getPaddingBottom()); 252290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal for (int i = getChildCount() - 1; i >= 0; i --) { 253290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal ((CellLayout) getChildAt(i)).setFixedSize(width, height); 254290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 255290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 256290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 257290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal public void removeItem(View v) { 258290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal for (int i = getChildCount() - 1; i >= 0; i --) { 259290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal getPageAt(i).removeView(v); 260290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 261290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 262290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 263290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal /** 264290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal * Updates position and rank of all the children in the view. 265290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal * It essentially removes all views from all the pages and then adds them again in appropriate 266290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal * page. 267290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal * 268290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal * @param list the ordered list of children. 269290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal * @param itemCount if greater than the total children count, empty spaces are left 270290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal * at the end, otherwise it is ignored. 271290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal * 272290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal */ 273290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal public void arrangeChildren(ArrayList<View> list, int itemCount) { 274e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal arrangeChildren(list, itemCount, true); 275e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal } 276e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal 277e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal private void arrangeChildren(ArrayList<View> list, int itemCount, boolean saveChanges) { 278290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal ArrayList<CellLayout> pages = new ArrayList<CellLayout>(); 279290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal for (int i = 0; i < getChildCount(); i++) { 280290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal CellLayout page = (CellLayout) getChildAt(i); 281290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal page.removeAllViews(); 282290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal pages.add(page); 283290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 284290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal setupContentDimensions(itemCount); 285290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 286290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal Iterator<CellLayout> pageItr = pages.iterator(); 287290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal CellLayout currentPage = null; 288290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 289290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal int position = 0; 290290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal int newX, newY, rank; 291290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 292290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal rank = 0; 2934846193300245c8c0a1f9bde3175f273df044309Sunny Goyal for (int i = 0; i < itemCount; i++) { 2944846193300245c8c0a1f9bde3175f273df044309Sunny Goyal View v = list.size() > i ? list.get(i) : null; 295290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal if (currentPage == null || position >= mMaxItemsPerPage) { 296290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal // Next page 297290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal if (pageItr.hasNext()) { 298290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal currentPage = pageItr.next(); 299290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } else { 300e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal currentPage = createAndAddNewPage(); 301290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 302290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal position = 0; 303290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 304290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 3054846193300245c8c0a1f9bde3175f273df044309Sunny Goyal if (v != null) { 3064846193300245c8c0a1f9bde3175f273df044309Sunny Goyal CellLayout.LayoutParams lp = (CellLayout.LayoutParams) v.getLayoutParams(); 3074846193300245c8c0a1f9bde3175f273df044309Sunny Goyal newX = position % mGridCountX; 3084846193300245c8c0a1f9bde3175f273df044309Sunny Goyal newY = position / mGridCountX; 3094846193300245c8c0a1f9bde3175f273df044309Sunny Goyal ItemInfo info = (ItemInfo) v.getTag(); 3104846193300245c8c0a1f9bde3175f273df044309Sunny Goyal if (info.cellX != newX || info.cellY != newY || info.rank != rank) { 3114846193300245c8c0a1f9bde3175f273df044309Sunny Goyal info.cellX = newX; 3124846193300245c8c0a1f9bde3175f273df044309Sunny Goyal info.cellY = newY; 3134846193300245c8c0a1f9bde3175f273df044309Sunny Goyal info.rank = rank; 3144846193300245c8c0a1f9bde3175f273df044309Sunny Goyal if (saveChanges) { 3154846193300245c8c0a1f9bde3175f273df044309Sunny Goyal LauncherModel.addOrMoveItemInDatabase(getContext(), info, 3164846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mFolder.mInfo.id, 0, info.cellX, info.cellY); 3174846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 318e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal } 3194846193300245c8c0a1f9bde3175f273df044309Sunny Goyal lp.cellX = info.cellX; 3204846193300245c8c0a1f9bde3175f273df044309Sunny Goyal lp.cellY = info.cellY; 3214846193300245c8c0a1f9bde3175f273df044309Sunny Goyal currentPage.addViewToCellLayout( 3224846193300245c8c0a1f9bde3175f273df044309Sunny Goyal v, -1, mFolder.mLauncher.getViewIdForItem(info), lp, true); 323290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 3244846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 325290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal rank ++; 326290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal position++; 327290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 328290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 329e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal // Remove extra views. 330290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal boolean removed = false; 331290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal while (pageItr.hasNext()) { 332e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal removeView(pageItr.next()); 333e4766230ff8115c5897ebee74c145bcae822581eSunny Goyal removed = true; 334290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 335290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal if (removed) { 336290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal setCurrentPage(0); 337290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 3385d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal 339b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal setEnableOverscroll(getPageCount() > 1); 3405d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal 3415d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal // Update footer 3428167dc2dcffbf4f68724bc1db2f5cfc1caf6a848Sunny Goyal mPageIndicator.setVisibility(getPageCount() > 1 ? View.VISIBLE : View.GONE); 343b7e15adc7b67cb1d70ca72014b200dd6cbbf166aSunny Goyal mFolder.mFolderName.setGravity(getPageCount() > 1 ? Gravity.START : Gravity.CENTER_HORIZONTAL); 344290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 345290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 346290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal public int getDesiredWidth() { 34722fc63ee298335b5f5c603ea1b77dc0e6180b16aSunny Goyal return getPageCount() > 0 ? 34822fc63ee298335b5f5c603ea1b77dc0e6180b16aSunny Goyal (getPageAt(0).getDesiredWidth() + getPaddingLeft() + getPaddingRight()) : 0; 349290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 350290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 351290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal public int getDesiredHeight() { 35222fc63ee298335b5f5c603ea1b77dc0e6180b16aSunny Goyal return getPageCount() > 0 ? 35322fc63ee298335b5f5c603ea1b77dc0e6180b16aSunny Goyal (getPageAt(0).getDesiredHeight() + getPaddingTop() + getPaddingBottom()) : 0; 354290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 355290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 356290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal public int getItemCount() { 357e85d7145222ba1311cd9280726d8419b84f2f94bSunny Goyal int lastPageIndex = getChildCount() - 1; 358e85d7145222ba1311cd9280726d8419b84f2f94bSunny Goyal if (lastPageIndex < 0) { 359e85d7145222ba1311cd9280726d8419b84f2f94bSunny Goyal // If there are no pages, nothing has yet been added to the folder. 360e85d7145222ba1311cd9280726d8419b84f2f94bSunny Goyal return 0; 3614846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 362e85d7145222ba1311cd9280726d8419b84f2f94bSunny Goyal return getPageAt(lastPageIndex).getShortcutsAndWidgets().getChildCount() 363e85d7145222ba1311cd9280726d8419b84f2f94bSunny Goyal + lastPageIndex * mMaxItemsPerPage; 364290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 365290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 366b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal /** 367b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal * @return the rank of the cell nearest to the provided pixel position. 368b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal */ 369290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal public int findNearestArea(int pixelX, int pixelY) { 370290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal int pageIndex = getNextPage(); 371290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal CellLayout page = getPageAt(pageIndex); 372f7a29e83f06909b378dba39c83a522375682710aSunny Goyal page.findNearestArea(pixelX, pixelY, 1, 1, sTempPosArray); 373290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal if (mFolder.isLayoutRtl()) { 374290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal sTempPosArray[0] = page.getCountX() - sTempPosArray[0] - 1; 375290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 376290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal return Math.min(mAllocatedContentSize - 1, 377290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal pageIndex * mMaxItemsPerPage + sTempPosArray[1] * mGridCountX + sTempPosArray[0]); 378290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 379290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 380290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal @Override 381290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal protected PageMarkerResources getPageIndicatorMarker(int pageIndex) { 382d3d37090c485359e2cf62eb6aa8e70350d161689Sunny Goyal return new PageMarkerResources(R.drawable.ic_pageindicator_current_folder, 383d3d37090c485359e2cf62eb6aa8e70350d161689Sunny Goyal R.drawable.ic_pageindicator_default_folder); 384290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 385290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 386290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal public boolean isFull() { 387b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal return !ALLOW_FOLDER_SCROLL && getItemCount() >= mMaxItemsPerPage; 388290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 389290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 390290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal public View getLastItem() { 391290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal if (getChildCount() < 1) { 392290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal return null; 393290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 394290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal ShortcutAndWidgetContainer lastContainer = getCurrentCellLayout().getShortcutsAndWidgets(); 395290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal int lastRank = lastContainer.getChildCount() - 1; 396290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal if (mGridCountX > 0) { 397290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal return lastContainer.getChildAt(lastRank % mGridCountX, lastRank / mGridCountX); 398290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } else { 399290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal return lastContainer.getChildAt(lastRank); 400290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 401290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 402290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 403b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal /** 404b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal * Iterates over all its items in a reading order. 405b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal * @return the view for which the operator returned true. 406b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal */ 407290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal public View iterateOverItems(ItemOperator op) { 408290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal for (int k = 0 ; k < getChildCount(); k++) { 409290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal CellLayout page = getPageAt(k); 410290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal for (int j = 0; j < page.getCountY(); j++) { 411290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal for (int i = 0; i < page.getCountX(); i++) { 412290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal View v = page.getChildAt(i, j); 413290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal if ((v != null) && op.evaluate((ItemInfo) v.getTag(), v, this)) { 414290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal return v; 415290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 416290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 417290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 418290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 419290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal return null; 420290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 421290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 422290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal public String getAccessibilityDescription() { 423290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal return String.format(getContext().getString(R.string.folder_opened), 424290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal mGridCountX, mGridCountY); 425290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 426290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 427b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal /** 428b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal * Sets the focus on the first visible child. 429b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal */ 430290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal public void setFocusOnFirstChild() { 431290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal View firstChild = getCurrentCellLayout().getChildAt(0, 0); 432290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal if (firstChild != null) { 433290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal firstChild.requestFocus(); 434290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 435290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 436290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 437290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal @Override 438290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal protected void notifyPageSwitchListener() { 439290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal super.notifyPageSwitchListener(); 440290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal if (mFolder != null) { 441290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal mFolder.updateTextViewFocus(); 442290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 443290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 444290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 4454846193300245c8c0a1f9bde3175f273df044309Sunny Goyal /** 4464846193300245c8c0a1f9bde3175f273df044309Sunny Goyal * Scrolls the current view by a fraction 4474846193300245c8c0a1f9bde3175f273df044309Sunny Goyal */ 4483b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal public void showScrollHint(int direction) { 4497066003b2032a49ae5e59dab9b706259bdeb7e6eSunny Goyal float fraction = (direction == DragController.SCROLL_LEFT) ^ mIsRtl 4503b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal ? -SCROLL_HINT_FRACTION : SCROLL_HINT_FRACTION; 4514846193300245c8c0a1f9bde3175f273df044309Sunny Goyal int hint = (int) (fraction * getWidth()); 4524846193300245c8c0a1f9bde3175f273df044309Sunny Goyal int scroll = getScrollForPage(getNextPage()) + hint; 4534846193300245c8c0a1f9bde3175f273df044309Sunny Goyal int delta = scroll - mUnboundedScrollX; 4544846193300245c8c0a1f9bde3175f273df044309Sunny Goyal if (delta != 0) { 4554846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mScroller.setInterpolator(new DecelerateInterpolator()); 4564846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mScroller.startScroll(mUnboundedScrollX, 0, delta, 0, Folder.SCROLL_HINT_DURATION); 4574846193300245c8c0a1f9bde3175f273df044309Sunny Goyal invalidate(); 4584846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 4594846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 4604846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 4614846193300245c8c0a1f9bde3175f273df044309Sunny Goyal public void clearScrollHint() { 4624846193300245c8c0a1f9bde3175f273df044309Sunny Goyal if (mUnboundedScrollX != getScrollForPage(getNextPage())) { 4634846193300245c8c0a1f9bde3175f273df044309Sunny Goyal snapToPage(getNextPage()); 4644846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 4654846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 4664846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 4674846193300245c8c0a1f9bde3175f273df044309Sunny Goyal /** 4684846193300245c8c0a1f9bde3175f273df044309Sunny Goyal * Finish animation all the views which are animating across pages 4694846193300245c8c0a1f9bde3175f273df044309Sunny Goyal */ 4704846193300245c8c0a1f9bde3175f273df044309Sunny Goyal public void completePendingPageChanges() { 4715d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal if (!mPendingAnimations.isEmpty()) { 4725d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal HashMap<View, Runnable> pendingViews = new HashMap<>(mPendingAnimations); 4734846193300245c8c0a1f9bde3175f273df044309Sunny Goyal for (Map.Entry<View, Runnable> e : pendingViews.entrySet()) { 4744846193300245c8c0a1f9bde3175f273df044309Sunny Goyal e.getKey().animate().cancel(); 4754846193300245c8c0a1f9bde3175f273df044309Sunny Goyal e.getValue().run(); 4764846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 4774846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 4784846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 4794846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 4804846193300245c8c0a1f9bde3175f273df044309Sunny Goyal public boolean rankOnCurrentPage(int rank) { 4814846193300245c8c0a1f9bde3175f273df044309Sunny Goyal int p = rank / mMaxItemsPerPage; 4824846193300245c8c0a1f9bde3175f273df044309Sunny Goyal return p == getNextPage(); 4834846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 4844846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 485290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal @Override 48634b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal protected void onPageBeginMoving() { 48734b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal super.onPageBeginMoving(); 48834b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal getVisiblePages(sTempPosArray); 48934b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal for (int i = sTempPosArray[0]; i <= sTempPosArray[1]; i++) { 49034b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal verifyVisibleHighResIcons(i); 49134b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal } 49234b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal } 49334b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal 49434b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal /** 49534b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal * Ensures that all the icons on the given page are of high-res 49634b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal */ 49734b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal public void verifyVisibleHighResIcons(int pageNo) { 49834b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal CellLayout page = getPageAt(pageNo); 49934b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal if (page != null) { 50034b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal ShortcutAndWidgetContainer parent = page.getShortcutsAndWidgets(); 50134b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal for (int i = parent.getChildCount() - 1; i >= 0; i--) { 50234b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal ((BubbleTextView) parent.getChildAt(i)).verifyHighRes(); 50334b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal } 50434b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal } 50534b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal } 50634b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal 507ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal public int getAllocatedContentSize() { 508ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal return mAllocatedContentSize; 509ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal } 510ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal 511b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal /** 512b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal * Reorders the items such that the {@param empty} spot moves to {@param target} 513b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal */ 514290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal public void realTimeReorder(int empty, int target) { 5154846193300245c8c0a1f9bde3175f273df044309Sunny Goyal completePendingPageChanges(); 516290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal int delay = 0; 5174846193300245c8c0a1f9bde3175f273df044309Sunny Goyal float delayAmount = START_VIEW_REORDER_DELAY; 518290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 519290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal // Animation only happens on the current page. 520290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal int pageToAnimate = getNextPage(); 521290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 522290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal int pageT = target / mMaxItemsPerPage; 523290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal int pagePosT = target % mMaxItemsPerPage; 524290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 525290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal if (pageT != pageToAnimate) { 526290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal Log.e(TAG, "Cannot animate when the target cell is invisible"); 527290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 528290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal int pagePosE = empty % mMaxItemsPerPage; 529290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal int pageE = empty / mMaxItemsPerPage; 530290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 531290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal int startPos, endPos; 532290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal int moveStart, moveEnd; 533290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal int direction; 534290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 535290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal if (target == empty) { 536290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal // No animation 537290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal return; 538290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } else if (target > empty) { 539290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal // Items will move backwards to make room for the empty cell. 540290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal direction = 1; 541290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 542290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal // If empty cell is in a different page, move them instantly. 543290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal if (pageE < pageToAnimate) { 544290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal moveStart = empty; 545290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal // Instantly move the first item in the current page. 546290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal moveEnd = pageToAnimate * mMaxItemsPerPage; 547290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal // Animate the 2nd item in the current page, as the first item was already moved to 548290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal // the last page. 549290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal startPos = 0; 550290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } else { 551290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal moveStart = moveEnd = -1; 552290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal startPos = pagePosE; 553290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 554290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 555290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal endPos = pagePosT; 556290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } else { 557290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal // The items will move forward. 558290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal direction = -1; 559290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 560290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal if (pageE > pageToAnimate) { 561290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal // Move the items immediately. 562290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal moveStart = empty; 563290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal // Instantly move the last item in the current page. 564290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal moveEnd = (pageToAnimate + 1) * mMaxItemsPerPage - 1; 565290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 566290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal // Animations start with the second last item in the page 567290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal startPos = mMaxItemsPerPage - 1; 568290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } else { 569290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal moveStart = moveEnd = -1; 570290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal startPos = pagePosE; 571290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 572290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 573290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal endPos = pagePosT; 574290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 575290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 576290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal // Instant moving views. 577290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal while (moveStart != moveEnd) { 578290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal int rankToMove = moveStart + direction; 579290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal int p = rankToMove / mMaxItemsPerPage; 580290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal int pagePos = rankToMove % mMaxItemsPerPage; 581290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal int x = pagePos % mGridCountX; 582290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal int y = pagePos / mGridCountX; 583290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 584290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal final CellLayout page = getPageAt(p); 585290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal final View v = page.getChildAt(x, y); 586290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal if (v != null) { 587290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal if (pageToAnimate != p) { 588290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal page.removeView(v); 589290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal addViewForRank(v, (ShortcutInfo) v.getTag(), moveStart); 590290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } else { 591290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal // Do a fake animation before removing it. 592290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal final int newRank = moveStart; 593290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal final float oldTranslateX = v.getTranslationX(); 594290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 595290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal Runnable endAction = new Runnable() { 596290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 597290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal @Override 598290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal public void run() { 5995d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal mPendingAnimations.remove(v); 600290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal v.setTranslationX(oldTranslateX); 601290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal ((CellLayout) v.getParent().getParent()).removeView(v); 602290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal addViewForRank(v, (ShortcutInfo) v.getTag(), newRank); 603290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 604290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal }; 605290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal v.animate() 6067066003b2032a49ae5e59dab9b706259bdeb7e6eSunny Goyal .translationXBy((direction > 0 ^ mIsRtl) ? -v.getWidth() : v.getWidth()) 607290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal .setDuration(REORDER_ANIMATION_DURATION) 608290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal .setStartDelay(0) 609290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal .withEndAction(endAction); 6105d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal mPendingAnimations.put(v, endAction); 611290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 612290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 613290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal moveStart = rankToMove; 614290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 615290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 616290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal if ((endPos - startPos) * direction <= 0) { 617290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal // No animation 618290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal return; 619290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 620290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal 621290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal CellLayout page = getPageAt(pageToAnimate); 622290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal for (int i = startPos; i != endPos; i += direction) { 623290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal int nextPos = i + direction; 624290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal View v = page.getChildAt(nextPos % mGridCountX, nextPos / mGridCountX); 625290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal if (v != null) { 626290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal ((ItemInfo) v.getTag()).rank -= direction; 627290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 628290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal if (page.animateChildToPosition(v, i % mGridCountX, i / mGridCountX, 629290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal REORDER_ANIMATION_DURATION, delay, true, true)) { 630290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal delay += delayAmount; 6314846193300245c8c0a1f9bde3175f273df044309Sunny Goyal delayAmount *= VIEW_REORDER_DELAY_FACTOR; 632290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 633290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 634290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal } 635b7e15adc7b67cb1d70ca72014b200dd6cbbf166aSunny Goyal 636b7e15adc7b67cb1d70ca72014b200dd6cbbf166aSunny Goyal public void setMarkerScale(float scale) { 637b7e15adc7b67cb1d70ca72014b200dd6cbbf166aSunny Goyal int count = mPageIndicator.getChildCount(); 638b7e15adc7b67cb1d70ca72014b200dd6cbbf166aSunny Goyal for (int i = 0; i < count; i++) { 639b7e15adc7b67cb1d70ca72014b200dd6cbbf166aSunny Goyal View marker = mPageIndicator.getChildAt(i); 640b7e15adc7b67cb1d70ca72014b200dd6cbbf166aSunny Goyal marker.animate().cancel(); 641b7e15adc7b67cb1d70ca72014b200dd6cbbf166aSunny Goyal marker.setScaleX(scale); 642b7e15adc7b67cb1d70ca72014b200dd6cbbf166aSunny Goyal marker.setScaleY(scale); 643b7e15adc7b67cb1d70ca72014b200dd6cbbf166aSunny Goyal } 644b7e15adc7b67cb1d70ca72014b200dd6cbbf166aSunny Goyal } 645b7e15adc7b67cb1d70ca72014b200dd6cbbf166aSunny Goyal 646b7e15adc7b67cb1d70ca72014b200dd6cbbf166aSunny Goyal public void animateMarkers() { 647b7e15adc7b67cb1d70ca72014b200dd6cbbf166aSunny Goyal int count = mPageIndicator.getChildCount(); 648b7e15adc7b67cb1d70ca72014b200dd6cbbf166aSunny Goyal OvershootInterpolator interpolator = new OvershootInterpolator(4); 649b7e15adc7b67cb1d70ca72014b200dd6cbbf166aSunny Goyal for (int i = 0; i < count; i++) { 650b7e15adc7b67cb1d70ca72014b200dd6cbbf166aSunny Goyal mPageIndicator.getChildAt(i).animate().scaleX(1).scaleY(1) 651b7e15adc7b67cb1d70ca72014b200dd6cbbf166aSunny Goyal .setInterpolator(interpolator) 652b7e15adc7b67cb1d70ca72014b200dd6cbbf166aSunny Goyal .setDuration(Folder.FOOTER_ANIMATION_DURATION) 653b7e15adc7b67cb1d70ca72014b200dd6cbbf166aSunny Goyal .setStartDelay(PAGE_INDICATOR_ANIMATION_DELAY * i); 654b7e15adc7b67cb1d70ca72014b200dd6cbbf166aSunny Goyal } 655b7e15adc7b67cb1d70ca72014b200dd6cbbf166aSunny Goyal } 656b7e15adc7b67cb1d70ca72014b200dd6cbbf166aSunny Goyal 657b7e15adc7b67cb1d70ca72014b200dd6cbbf166aSunny Goyal public int itemsPerPage() { 658b7e15adc7b67cb1d70ca72014b200dd6cbbf166aSunny Goyal return mMaxItemsPerPage; 659b7e15adc7b67cb1d70ca72014b200dd6cbbf166aSunny Goyal } 660290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal} 661