From bc753359f8b08e0813016eebc8392b83a4d2bd6e Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Thu, 5 Mar 2015 09:40:44 -0800 Subject: Extracting a common interface out of FolderCellLayout Change-Id: Ia94a75ac232b8b425c8befdf2e4f064678531505 --- src/com/android/launcher3/Folder.java | 141 ++++++++++++++++-------- src/com/android/launcher3/FolderCellLayout.java | 86 +++++++++------ 2 files changed, 144 insertions(+), 83 deletions(-) (limited to 'src/com/android/launcher3') diff --git a/src/com/android/launcher3/Folder.java b/src/com/android/launcher3/Folder.java index 80fc32880..4414672cc 100644 --- a/src/com/android/launcher3/Folder.java +++ b/src/com/android/launcher3/Folder.java @@ -48,6 +48,7 @@ import android.widget.LinearLayout; import android.widget.TextView; import com.android.launcher3.FolderInfo.FolderListener; +import com.android.launcher3.Workspace.ItemOperator; import java.util.ArrayList; import java.util.Collections; @@ -95,7 +96,7 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList private FolderIcon mFolderIcon; - private FolderCellLayout mContent; + private FolderContent mContent; private View mContentWrapper; FolderEditText mFolderName; @@ -160,17 +161,9 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList protected void onFinishInflate() { super.onFinishInflate(); mContentWrapper = findViewById(R.id.folder_content_wrapper); - mContent = (FolderCellLayout) findViewById(R.id.folder_content); + mContent = (FolderContent) findViewById(R.id.folder_content); mContent.setFolder(this); - LauncherAppState app = LauncherAppState.getInstance(); - DeviceProfile grid = app.getDynamicGrid().getDeviceProfile(); - - mContent.setCellDimensions(grid.folderCellWidthPx, grid.folderCellHeightPx); - mContent.setGridSize(0, 0); - mContent.getShortcutsAndWidgets().setMotionEventSplittingEnabled(false); - mContent.setInvertIfRtl(true); - mFolderName = (FolderEditText) findViewById(R.id.folder_name); mFolderName.setFolder(this); mFolderName.setOnFocusChangeListener(this); @@ -435,8 +428,8 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList reveal.setDuration(mMaterialExpandDuration); reveal.setInterpolator(new LogDecelerateInterpolator(100, 0)); - mContent.setAlpha(0f); - Animator iconsAlpha = LauncherAnimUtils.ofFloat(mContent, "alpha", 0f, 1f); + mContentWrapper.setAlpha(0f); + Animator iconsAlpha = LauncherAnimUtils.ofFloat(mContentWrapper, "alpha", 0f, 1f); iconsAlpha.setDuration(mMaterialExpandDuration); iconsAlpha.setStartDelay(mMaterialExpandStagger); iconsAlpha.setInterpolator(new AccelerateInterpolator(1.5f)); @@ -459,11 +452,11 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList openFolderAnim = anim; - mContent.setLayerType(LAYER_TYPE_HARDWARE, null); + mContentWrapper.setLayerType(LAYER_TYPE_HARDWARE, null); onCompleteRunnable = new Runnable() { @Override public void run() { - mContent.setLayerType(LAYER_TYPE_NONE, null); + mContentWrapper.setLayerType(LAYER_TYPE_NONE, null); } }; } @@ -471,8 +464,7 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList @Override public void onAnimationStart(Animator animation) { sendCustomAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED, - String.format(getContext().getString(R.string.folder_opened), - mContent.getCountX(), mContent.getCountY())); + mContent.getAccessibilityDescription()); mState = STATE_ANIMATING; } @Override @@ -483,7 +475,7 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList onCompleteRunnable.run(); } - setFocusOnFirstChild(); + mContent.setFocusOnFirstChild(); } }); openFolderAnim.start(); @@ -512,13 +504,6 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList } } - private void setFocusOnFirstChild() { - View firstChild = mContent.getChildAt(0, 0); - if (firstChild != null) { - firstChild.requestFocus(); - } - } - public void animateClosed() { if (!(getParent() instanceof DragLayer)) return; PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 0); @@ -576,7 +561,7 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList r[0] -= getPaddingLeft(); r[1] -= getPaddingTop(); - mTargetRank = mContent.findNearestArea((int) r[0], (int) r[1], 1, 1); + mTargetRank = mContent.findNearestArea((int) r[0], (int) r[1]); if (mTargetRank != mPrevTargetRank) { mReorderAlarm.cancelAlarm(); mReorderAlarm.setOnAlarmListener(mReorderAlarmListener); @@ -869,10 +854,6 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList return mContent.getItemCount(); } - public View getItemAt(int index) { - return mContent.getShortcutsAndWidgets().getChildAt(index); - } - private void onCloseComplete() { DragLayer parent = (DragLayer) getParent(); if (parent != null) { @@ -933,7 +914,7 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList } } }; - View finalChild = getItemAt(0); + View finalChild = mContent.getLastItem(); if (finalChild != null) { mFolderIcon.performDestroyAnimation(finalChild, onCompleteRunnable); } else { @@ -949,8 +930,7 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList // This method keeps track of the last item in the folder for the purposes // of keyboard focus private void updateTextViewFocus() { - View lastChild = getItemAt(getItemCount() - 1); - getItemAt(getItemCount() - 1); + View lastChild = mContent.getLastItem(); if (lastChild != null) { mFolderName.setNextFocusDownId(lastChild.getId()); mFolderName.setNextFocusRightId(lastChild.getId()); @@ -1037,7 +1017,7 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList // If the item was dropped onto this open folder, we have done the work associated // with adding the item to the folder, as indicated by mSuppressOnAdd being set if (mSuppressOnAdd) return; - mContent.createAndAddShortcutToEnd(item); + mContent.createAndAddViewForRank(item, mContent.allocateNewLastItemRank()); LauncherModel.addOrMoveItemInDatabase( mLauncher, item, mInfo.id, 0, item.cellX, item.cellY); } @@ -1059,16 +1039,14 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList } } - private View getViewForInfo(ShortcutInfo item) { - for (int j = 0; j < mContent.getCountY(); j++) { - for (int i = 0; i < mContent.getCountX(); i++) { - View v = mContent.getChildAt(i, j); - if (v.getTag() == item) { - return v; - } + private View getViewForInfo(final ShortcutInfo item) { + return mContent.iterateOverItems(new ItemOperator() { + + @Override + public boolean evaluate(ItemInfo info, View view, View parent) { + return info == item; } - } - return null; + }); } public void onItemsChanged() { @@ -1081,14 +1059,14 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList public ArrayList getItemsInReadingOrder() { if (mItemsInvalidated) { mItemsInReadingOrder.clear(); - for (int j = 0; j < mContent.getCountY(); j++) { - for (int i = 0; i < mContent.getCountX(); i++) { - View v = mContent.getChildAt(i, j); - if (v != null) { - mItemsInReadingOrder.add(v); - } + mContent.iterateOverItems(new ItemOperator() { + + @Override + public boolean evaluate(ItemInfo info, View view, View parent) { + mItemsInReadingOrder.add(view); + return false; } - } + }); mItemsInvalidated = false; } return mItemsInReadingOrder; @@ -1108,4 +1086,69 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList public void getHitRectRelativeToDragLayer(Rect outRect) { getHitRect(outRect); } + + public static interface FolderContent { + void setFolder(Folder f); + + void removeView(View v); + + boolean isFull(); + int getItemCount(); + + int getDesiredWidth(); + int getDesiredHeight(); + void setFixedSize(int width, int height); + + /** + * Iterates over all its items in a reading order. + * @return the view for which the operator returned true. + */ + View iterateOverItems(ItemOperator op); + View getLastItem(); + + String getAccessibilityDescription(); + + /** + * Binds items to the layout. + * @return list of items that could not be bound, probably because we hit the max size limit. + */ + ArrayList bindItems(ArrayList children); + + /** + * Create space for a new item at the end, and returns the rank for that item. + * Resizes the content if necessary. + */ + int allocateNewLastItemRank(); + + View createAndAddViewForRank(ShortcutInfo item, int rank); + + /** + * Adds the {@param view} to the layout based on {@param rank} and updated the position + * related attributes. It assumes that {@param item} is already attached to the view. + */ + void addViewForRank(View view, ShortcutInfo item, int rank); + + /** + * Reorders the items such that the {@param empty} spot moves to {@param target} + */ + void realTimeReorder(int empty, int target); + + /** + * @return the rank of the cell nearest to the provided pixel position. + */ + int findNearestArea(int pixelX, int pixelY); + + /** + * Updates position and rank of all the children in the view based. + * @param list the ordered list of children. + * @param itemCount if greater than the total children count, empty spaces are left + * at the end. + */ + void arrangeChildren(ArrayList list, int itemCount); + + /** + * Sets the focus on the first visible child. + */ + void setFocusOnFirstChild(); + } } diff --git a/src/com/android/launcher3/FolderCellLayout.java b/src/com/android/launcher3/FolderCellLayout.java index 66f5224bb..21f2a1112 100644 --- a/src/com/android/launcher3/FolderCellLayout.java +++ b/src/com/android/launcher3/FolderCellLayout.java @@ -5,9 +5,11 @@ import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; +import com.android.launcher3.Workspace.ItemOperator; + import java.util.ArrayList; -public class FolderCellLayout extends CellLayout { +public class FolderCellLayout extends CellLayout implements Folder.FolderContent { private static final int REORDER_ANIMATION_DURATION = 230; private static final int START_VIEW_REORDER_DELAY = 30; @@ -48,8 +50,13 @@ public class FolderCellLayout extends CellLayout { mInflater = LayoutInflater.from(context); mIconCache = app.getIconCache(); + + setCellDimensions(grid.folderCellWidthPx, grid.folderCellHeightPx); + getShortcutsAndWidgets().setMotionEventSplittingEnabled(false); + setInvertIfRtl(true); } + @Override public void setFolder(Folder folder) { mFolder = folder; mFocusIndicatorView = (FocusIndicatorView) folder.findViewById(R.id.focus_indicator); @@ -87,10 +94,7 @@ public class FolderCellLayout extends CellLayout { setGridSize(countX, countY); } - /** - * Binds items to the layout. - * @return list of items that could not be bound, probably because we hit the max size limit. - */ + @Override public ArrayList bindItems(ArrayList items) { ArrayList extra = new ArrayList(); setupContentDimensions(Math.min(items.size(), mMaxNumItems)); @@ -112,33 +116,20 @@ public class FolderCellLayout extends CellLayout { return extra; } - /** - * Create space for a new item at the end, and returns the rank for that item. - * Resizes the content if necessary. - */ + @Override public int allocateNewLastItemRank() { int rank = getItemCount(); mFolder.rearrangeChildren(rank + 1); return rank; } - /** - * Adds the new item to the end of the grid. Resizes the content if necessary. - */ - public View createAndAddShortcutToEnd(ShortcutInfo item) { - int rank = allocateNewLastItemRank(); - return createAndAddViewForRank(item, rank); - } - + @Override public View createAndAddViewForRank(ShortcutInfo item, int rank) { updateItemXY(item, rank); return addNewView(item); } - /** - * Adds the {@param view} to the layout based on {@param rank} and updated the position - * related attributes. It assumes that {@param item} is already attached to the view. - */ + @Override public void addViewForRank(View view, ShortcutInfo item, int rank) { updateItemXY(item, rank); CellLayout.LayoutParams lp = (CellLayout.LayoutParams) view.getLayoutParams(); @@ -174,12 +165,10 @@ public class FolderCellLayout extends CellLayout { /** * Refer {@link #findNearestArea(int, int, int, int, View, boolean, int[])} - * - * @return The rank of a vacant area that can contain this object, - * nearest the requested location. */ - public int findNearestArea(int pixelX, int pixelY, int spanX, int spanY) { - findNearestArea(pixelX, pixelY, spanX, spanY, null, false, sTempPosArray); + @Override + public int findNearestArea(int pixelX, int pixelY) { + findNearestArea(pixelX, pixelY, 1, 1, null, false, sTempPosArray); if (mFolder.isLayoutRtl()) { sTempPosArray[0] = getCountX() - sTempPosArray[0] - 1; } @@ -189,19 +178,17 @@ public class FolderCellLayout extends CellLayout { sTempPosArray[1] * getCountX() + sTempPosArray[0]); } + @Override public boolean isFull() { return getItemCount() >= mMaxNumItems; } + @Override public int getItemCount() { return getShortcutsAndWidgets().getChildCount(); } - /** - * Updates position and rank of all the children in the view based. - * @param list the ordered list of children. - * @param itemCount if greater than the total children count, empty spaces are left at the end. - */ + @Override public void arrangeChildren(ArrayList list, int itemCount) { setupContentDimensions(itemCount); removeAllViews(); @@ -228,9 +215,40 @@ public class FolderCellLayout extends CellLayout { } } - /** - * Reorders the items such that the {@param empty} spot moves to {@param target} - */ + @Override + public View iterateOverItems(ItemOperator op) { + for (int j = 0; j < getCountY(); j++) { + for (int i = 0; i < getCountX(); i++) { + View v = getChildAt(i, j); + if ((v != null) && op.evaluate((ItemInfo) v.getTag(), v, this)) { + return v; + } + } + } + return null; + } + + @Override + public String getAccessibilityDescription() { + return String.format(getContext().getString(R.string.folder_opened), + getCountX(), getCountY()); + } + + @Override + public void setFocusOnFirstChild() { + View firstChild = getChildAt(0, 0); + if (firstChild != null) { + firstChild.requestFocus(); + } + } + + @Override + public View getLastItem() { + int total = getShortcutsAndWidgets().getChildCount(); + return getShortcutsAndWidgets().getChildAt(total % getCountX(), total / getCountX()); + } + + @Override public void realTimeReorder(int empty, int target) { boolean wrap; int startX; -- cgit v1.2.3