summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSunny Goyal <sunnygoyal@google.com>2015-04-09 23:35:01 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2015-04-09 23:35:02 +0000
commit557280c116db54ed2100eb0815e6d539d2b58252 (patch)
treee04c2e50836df29b7db5a9fe2657a39bec7049a1
parent326192156687e0f42d4e37a41232b04a32b41e95 (diff)
parentb863415c17aaaf6012647df5ed14803f89f94bcb (diff)
downloadandroid_packages_apps_Trebuchet-557280c116db54ed2100eb0815e6d539d2b58252.tar.gz
android_packages_apps_Trebuchet-557280c116db54ed2100eb0815e6d539d2b58252.tar.bz2
android_packages_apps_Trebuchet-557280c116db54ed2100eb0815e6d539d2b58252.zip
Merge "Updating folder UI" into ub-launcher3-burnaby
-rw-r--r--res/layout/page_indicator_marker.xml4
-rw-r--r--res/layout/user_folder.xml52
-rw-r--r--res/layout/user_folder_scroll.xml106
-rw-r--r--src/com/android/launcher3/Folder.java180
-rw-r--r--src/com/android/launcher3/FolderCellLayout.java330
-rw-r--r--src/com/android/launcher3/FolderPagedView.java129
6 files changed, 161 insertions, 640 deletions
diff --git a/res/layout/page_indicator_marker.xml b/res/layout/page_indicator_marker.xml
index 686d27569..564a95811 100644
--- a/res/layout/page_indicator_marker.xml
+++ b/res/layout/page_indicator_marker.xml
@@ -16,8 +16,8 @@
<com.android.launcher3.PageIndicatorMarker
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:launcher="http://schemas.android.com/apk/res-auto"
- android:layout_width="16dp"
- android:layout_height="16dp"
+ android:layout_width="12dp"
+ android:layout_height="12dp"
android:layout_gravity="center_vertical">
<ImageView
android:id="@+id/inactive"
diff --git a/res/layout/user_folder.xml b/res/layout/user_folder.xml
index 7a4d5e881..cd3a051ad 100644
--- a/res/layout/user_folder.xml
+++ b/res/layout/user_folder.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright (C) 2008 The Android Open Source Project
+ Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -34,30 +34,44 @@
android:layout_width="20dp"
android:layout_height="20dp" />
- <com.android.launcher3.FolderCellLayout
+ <com.android.launcher3.FolderPagedView
android:id="@+id/folder_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:cacheColorHint="#ff333333"
- android:hapticFeedbackEnabled="false" />
+ launcher:pageIndicator="@+id/folder_page_indicator" />
</FrameLayout>
- <com.android.launcher3.FolderEditText
- android:id="@+id/folder_name"
+ <LinearLayout
+ android:id="@+id/folder_footer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:background="#00000000"
- android:fontFamily="sans-serif-condensed"
- android:gravity="center_horizontal"
- android:hint="@string/folder_hint_text"
- android:imeOptions="flagNoExtractUi"
- android:paddingBottom="@dimen/folder_name_padding"
- android:paddingTop="@dimen/folder_name_padding"
- android:singleLine="true"
- android:textColor="#ff777777"
- android:textColorHighlight="#ffCCCCCC"
- android:textColorHint="#ff808080"
- android:textCursorDrawable="@null"
- android:textSize="14sp" />
+ android:orientation="vertical" >
+
+ <include
+ android:id="@+id/folder_page_indicator"
+ android:layout_width="wrap_content"
+ android:layout_height="12dp"
+ android:layout_gravity="center_horizontal"
+ layout="@layout/page_indicator" />
+
+ <com.android.launcher3.FolderEditText
+ android:id="@+id/folder_name"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:background="#00000000"
+ android:fontFamily="sans-serif-condensed"
+ android:gravity="center_horizontal"
+ android:hint="@string/folder_hint_text"
+ android:imeOptions="flagNoExtractUi"
+ android:paddingBottom="@dimen/folder_name_padding"
+ android:paddingTop="@dimen/folder_name_padding"
+ android:singleLine="true"
+ android:textColor="#ff777777"
+ android:textColorHighlight="#ffCCCCCC"
+ android:textColorHint="#ff808080"
+ android:textCursorDrawable="@null"
+ android:textSize="14sp" />
+ </LinearLayout>
</com.android.launcher3.Folder> \ No newline at end of file
diff --git a/res/layout/user_folder_scroll.xml b/res/layout/user_folder_scroll.xml
deleted file mode 100644
index 12e5097f3..000000000
--- a/res/layout/user_folder_scroll.xml
+++ /dev/null
@@ -1,106 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<com.android.launcher3.Folder xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:launcher="http://schemas.android.com/apk/res-auto"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:background="@drawable/quantum_panel"
- android:orientation="vertical" >
-
- <FrameLayout
- android:id="@+id/folder_content_wrapper"
- android:layout_width="match_parent"
- android:layout_height="match_parent" >
-
- <!-- Actual size of the indicator doesn't matter as it is scaled to match the view size -->
-
- <com.android.launcher3.FocusIndicatorView
- android:id="@+id/focus_indicator"
- android:layout_width="20dp"
- android:layout_height="20dp" />
-
- <com.android.launcher3.FolderPagedView
- android:id="@+id/folder_content"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- launcher:pageIndicator="@+id/folder_page_indicator" />
- </FrameLayout>
-
- <LinearLayout
- android:id="@+id/folder_footer"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- android:paddingStart="12dp"
- android:paddingEnd="8dp" >
-
- <com.android.launcher3.FolderEditText
- android:id="@+id/folder_name"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"
- android:layout_weight="1"
- android:background="#00000000"
- android:fontFamily="sans-serif-condensed"
- android:gravity="start"
- android:hint="@string/folder_hint_text"
- android:imeOptions="flagNoExtractUi"
- android:paddingBottom="@dimen/folder_name_padding"
- android:paddingTop="@dimen/folder_name_padding"
- android:singleLine="true"
- android:textColor="#ff777777"
- android:textColorHighlight="#ffCCCCCC"
- android:textColorHint="#ff808080"
- android:textCursorDrawable="@null"
- android:textSize="14sp" />
-
- <include
- android:id="@+id/folder_page_indicator"
- android:layout_width="wrap_content"
- android:layout_height="12dp"
- android:layout_gravity="top"
- android:layout_marginTop="5dp"
- layout="@layout/page_indicator" />
-
- <LinearLayout
- android:id="@+id/folder_sort"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:layout_gravity="center_vertical"
- android:gravity="end|center_vertical" >
-
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginEnd="8dp"
- android:text="@string/sort_alphabetical"
- android:textColor="#ff777777"
- android:textSize="14sp" />
-
- <Switch
- android:id="@+id/folder_sort_switch"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:clickable="false"
- android:duplicateParentState="true"
- android:focusable="false" />
- </LinearLayout>
- </LinearLayout>
-
-</com.android.launcher3.Folder> \ No newline at end of file
diff --git a/src/com/android/launcher3/Folder.java b/src/com/android/launcher3/Folder.java
index 1e1d1eeb4..0eb1fd8bb 100644
--- a/src/com/android/launcher3/Folder.java
+++ b/src/com/android/launcher3/Folder.java
@@ -69,7 +69,6 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
* results in CellLayout being measured as UNSPECIFIED, which it does not support.
*/
private static final int MIN_CONTENT_DIMEN = 5;
- private static final boolean ALLOW_FOLDER_SCROLL = true;
static final int STATE_NONE = -1;
static final int STATE_SMALL = 0;
@@ -101,6 +100,8 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
private final Alarm mReorderAlarm = new Alarm();
private final Alarm mOnExitAlarm = new Alarm();
+ private final Alarm mOnScrollHintAlarm = new Alarm();
+ @Thunk final Alarm mScrollPauseAlarm = new Alarm();
@Thunk final ArrayList<View> mItemsInReadingOrder = new ArrayList<View>();
@@ -116,7 +117,7 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
@Thunk FolderIcon mFolderIcon;
- @Thunk FolderContent mContent;
+ @Thunk FolderPagedView mContent;
@Thunk View mContentWrapper;
FolderEditText mFolderName;
@@ -149,11 +150,6 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
// Folder scrolling
private int mScrollAreaOffset;
- private Alarm mOnScrollHintAlarm;
- @Thunk Alarm mScrollPauseAlarm;
-
- // TODO: Use {@link #mContent} once {@link #ALLOW_FOLDER_SCROLL} is removed.
- @Thunk FolderPagedView mPagedView;
@Thunk int mScrollHintDir = DragController.SCROLL_NONE;
@Thunk int mCurrentScrollDir = DragController.SCROLL_NONE;
@@ -186,18 +182,13 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
// name is complete, we have something to focus on, thus hiding the cursor and giving
// reliable behavior when clicking the text field (since it will always gain focus on click).
setFocusableInTouchMode(true);
-
- if (ALLOW_FOLDER_SCROLL) {
- mOnScrollHintAlarm = new Alarm();
- mScrollPauseAlarm = new Alarm();
- }
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
mContentWrapper = findViewById(R.id.folder_content_wrapper);
- mContent = (FolderContent) findViewById(R.id.folder_content);
+ mContent = (FolderPagedView) findViewById(R.id.folder_content);
mContent.setFolder(this);
mFolderName = (FolderEditText) findViewById(R.id.folder_name);
@@ -211,16 +202,16 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
mFolderName.setInputType(mFolderName.getInputType() |
InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS | InputType.TYPE_TEXT_FLAG_CAP_WORDS);
- mFooter = ALLOW_FOLDER_SCROLL ? findViewById(R.id.folder_footer) : mFolderName;
+ mFooter = findViewById(R.id.folder_footer);
+ updateFooterHeight();
+ }
+
+ public void updateFooterHeight() {
// We find out how tall footer wants to be (it is set to wrap_content), so that
// we can allocate the appropriate amount of space for it.
int measureSpec = MeasureSpec.UNSPECIFIED;
mFooter.measure(measureSpec, measureSpec);
mFooterHeight = mFooter.getMeasuredHeight();
-
- if (ALLOW_FOLDER_SCROLL) {
- mPagedView = (FolderPagedView) mContent;
- }
}
private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {
@@ -398,8 +389,7 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
* @return A new UserFolder.
*/
static Folder fromXml(Context context) {
- return (Folder) LayoutInflater.from(context).inflate(
- ALLOW_FOLDER_SCROLL ? R.layout.user_folder_scroll : R.layout.user_folder, null);
+ return (Folder) LayoutInflater.from(context).inflate(R.layout.user_folder, null);
}
/**
@@ -424,12 +414,10 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
public void animateOpen() {
if (!(getParent() instanceof DragLayer)) return;
- if (ALLOW_FOLDER_SCROLL) {
- mPagedView.completePendingPageChanges();
- if (!(mDragInProgress && mPagedView.mIsSorted)) {
- // Open on the first page.
- mPagedView.snapToPageImmediately(0);
- }
+ mContent.completePendingPageChanges();
+ if (!(mDragInProgress && mContent.mIsSorted)) {
+ // Open on the first page.
+ mContent.snapToPageImmediately(0);
}
Animator openFolderAnim = null;
@@ -533,10 +521,8 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
mDragController.forceTouchMove();
}
- if (ALLOW_FOLDER_SCROLL) {
- FolderPagedView pages = (FolderPagedView) mContent;
- pages.verifyVisibleHighResIcons(pages.getNextPage());
- }
+ FolderPagedView pages = (FolderPagedView) mContent;
+ pages.verifyVisibleHighResIcons(pages.getNextPage());
}
public void beginExternalDrag(ShortcutInfo item) {
@@ -544,7 +530,8 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
mEmptyCellRank = mContent.allocateRankForNewItem(item);
mIsExternalDrag = true;
mDragInProgress = true;
- if (ALLOW_FOLDER_SCROLL && mPagedView.mIsSorted) {
+
+ if (mContent.mIsSorted) {
mScrollPauseAlarm.setOnAlarmListener(null);
mScrollPauseAlarm.cancelAlarm();
mScrollPauseAlarm.setAlarm(SORTED_STICKY_REORDER_DELAY);
@@ -601,11 +588,9 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
public void onDragEnter(DragObject d) {
mPrevTargetRank = -1;
mOnExitAlarm.cancelAlarm();
- if (ALLOW_FOLDER_SCROLL) {
- // Get the area offset such that the folder only closes if half the drag icon width
- // is outside the folder area
- mScrollAreaOffset = d.dragView.getDragRegionWidth() / 2 - d.xOffset;
- }
+ // Get the area offset such that the folder only closes if half the drag icon width
+ // is outside the folder area
+ mScrollAreaOffset = d.dragView.getDragRegionWidth() / 2 - d.xOffset;
}
OnAlarmListener mReorderAlarmListener = new OnAlarmListener() {
@@ -632,7 +617,7 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
}
@Thunk void onDragOver(DragObject d, int reorderDelay) {
- if (ALLOW_FOLDER_SCROLL && mScrollPauseAlarm.alarmPending()) {
+ if (mScrollPauseAlarm.alarmPending()) {
return;
}
final float[] r = new float[2];
@@ -645,27 +630,23 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
mPrevTargetRank = mTargetRank;
}
- if (!ALLOW_FOLDER_SCROLL) {
- return;
- }
-
float x = r[0];
- int currentPage = mPagedView.getNextPage();
+ int currentPage = mContent.getNextPage();
- float cellOverlap = mPagedView.getCurrentCellLayout().getCellWidth()
+ float cellOverlap = mContent.getCurrentCellLayout().getCellWidth()
* ICON_OVERSCROLL_WIDTH_FACTOR;
boolean isOutsideLeftEdge = x < cellOverlap;
boolean isOutsideRightEdge = x > (getWidth() - cellOverlap);
- if (currentPage > 0 && (mPagedView.rtlLayout ? isOutsideRightEdge : isOutsideLeftEdge)) {
+ if (currentPage > 0 && (mContent.rtlLayout ? isOutsideRightEdge : isOutsideLeftEdge)) {
showScrollHint(DragController.SCROLL_LEFT, d);
- } else if (currentPage < (mPagedView.getPageCount() - 1)
- && (mPagedView.rtlLayout ? isOutsideLeftEdge : isOutsideRightEdge)) {
+ } else if (currentPage < (mContent.getPageCount() - 1)
+ && (mContent.rtlLayout ? isOutsideLeftEdge : isOutsideRightEdge)) {
showScrollHint(DragController.SCROLL_RIGHT, d);
} else {
mOnScrollHintAlarm.cancelAlarm();
if (mScrollHintDir != DragController.SCROLL_NONE) {
- mPagedView.clearScrollHint();
+ mContent.clearScrollHint();
mScrollHintDir = DragController.SCROLL_NONE;
}
}
@@ -674,7 +655,7 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
private void showScrollHint(int direction, DragObject d) {
// Show scroll hint on the right
if (mScrollHintDir != direction) {
- mPagedView.showScrollHint(direction);
+ mContent.showScrollHint(direction);
mScrollHintDir = direction;
}
@@ -714,13 +695,11 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
}
mReorderAlarm.cancelAlarm();
- if (ALLOW_FOLDER_SCROLL) {
- mOnScrollHintAlarm.cancelAlarm();
- mScrollPauseAlarm.cancelAlarm();
- if (mScrollHintDir != DragController.SCROLL_NONE) {
- mPagedView.clearScrollHint();
- mScrollHintDir = DragController.SCROLL_NONE;
- }
+ mOnScrollHintAlarm.cancelAlarm();
+ mScrollPauseAlarm.cancelAlarm();
+ if (mScrollHintDir != DragController.SCROLL_NONE) {
+ mContent.clearScrollHint();
+ mScrollHintDir = DragController.SCROLL_NONE;
}
}
@@ -1088,21 +1067,19 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
};
}
- if (ALLOW_FOLDER_SCROLL) {
- // If the icon was dropped while the page was being scrolled, we need to compute
- // the target location again such that the icon is placed of the final page.
- if (!mPagedView.rankOnCurrentPage(mEmptyCellRank)) {
- // Reorder again.
- mTargetRank = getTargetRank(d, null);
+ // If the icon was dropped while the page was being scrolled, we need to compute
+ // the target location again such that the icon is placed of the final page.
+ if (!mContent.rankOnCurrentPage(mEmptyCellRank)) {
+ // Reorder again.
+ mTargetRank = getTargetRank(d, null);
- // Rearrange items immediately.
- mReorderAlarmListener.onAlarm(mReorderAlarm);
+ // Rearrange items immediately.
+ mReorderAlarmListener.onAlarm(mReorderAlarm);
- mOnScrollHintAlarm.cancelAlarm();
- mScrollPauseAlarm.cancelAlarm();
- }
- mPagedView.completePendingPageChanges();
+ mOnScrollHintAlarm.cancelAlarm();
+ mScrollPauseAlarm.cancelAlarm();
}
+ mContent.completePendingPageChanges();
View currentDragView;
ShortcutInfo si = mCurrentDragInfo;
@@ -1252,10 +1229,10 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
@Override
public void onAlarm(Alarm alarm) {
if (mCurrentScrollDir == DragController.SCROLL_LEFT) {
- mPagedView.scrollLeft();
+ mContent.scrollLeft();
mScrollHintDir = DragController.SCROLL_NONE;
} else if (mCurrentScrollDir == DragController.SCROLL_RIGHT) {
- mPagedView.scrollRight();
+ mContent.scrollRight();
mScrollHintDir = DragController.SCROLL_NONE;
} else {
// This should not happen
@@ -1286,69 +1263,4 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
onDragOver(mDragObject, 1);
}
}
-
- public static interface FolderContent {
- void setFolder(Folder f);
-
- void removeItem(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<ShortcutInfo> bindItems(ArrayList<ShortcutInfo> children);
-
- /**
- * Create space for a new item, and returns the rank for that item.
- * Resizes the content if necessary.
- */
- int allocateRankForNewItem(ShortcutInfo info);
-
- 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<View> 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
deleted file mode 100644
index 8585addd5..000000000
--- a/src/com/android/launcher3/FolderCellLayout.java
+++ /dev/null
@@ -1,330 +0,0 @@
-/**
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3;
-
-import android.content.Context;
-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 implements Folder.FolderContent {
-
- private static final int REORDER_ANIMATION_DURATION = 230;
- private static final int START_VIEW_REORDER_DELAY = 30;
- private static final float VIEW_REORDER_DELAY_FACTOR = 0.9f;
-
- private static final int[] sTempPosArray = new int[2];
-
- private final FolderKeyEventListener mKeyListener = new FolderKeyEventListener();
- private final LayoutInflater mInflater;
- private final IconCache mIconCache;
-
- private final int mMaxCountX;
- private final int mMaxCountY;
- private final int mMaxNumItems;
-
- // Indicates the last number of items used to set up the grid size
- private int mAllocatedContentSize;
-
- private Folder mFolder;
- private FocusIndicatorView mFocusIndicatorView;
-
- public FolderCellLayout(Context context) {
- this(context, null);
- }
-
- public FolderCellLayout(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public FolderCellLayout(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
-
- LauncherAppState app = LauncherAppState.getInstance();
- DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
- mMaxCountX = (int) grid.numColumns;
- mMaxCountY = (int) grid.numRows;
- mMaxNumItems = mMaxCountX * mMaxCountY;
-
- 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);
- }
-
- /**
- * Sets up the grid size such that {@param count} items can fit in the grid.
- * The grid size is calculated such that countY <= countX and countX = ceil(sqrt(count)) while
- * maintaining the restrictions of {@link #mMaxCountX} &amp; {@link #mMaxCountY}.
- */
- private void setupContentDimensions(int count) {
- mAllocatedContentSize = count;
- int countX = getCountX();
- int countY = getCountY();
- boolean done = false;
-
- while (!done) {
- int oldCountX = countX;
- int oldCountY = countY;
- if (countX * countY < count) {
- // Current grid is too small, expand it
- if ((countX <= countY || countY == mMaxCountY) && countX < mMaxCountX) {
- countX++;
- } else if (countY < mMaxCountY) {
- countY++;
- }
- if (countY == 0) countY++;
- } else if ((countY - 1) * countX >= count && countY >= countX) {
- countY = Math.max(0, countY - 1);
- } else if ((countX - 1) * countY >= count) {
- countX = Math.max(0, countX - 1);
- }
- done = countX == oldCountX && countY == oldCountY;
- }
- setGridSize(countX, countY);
- }
-
- @Override
- public ArrayList<ShortcutInfo> bindItems(ArrayList<ShortcutInfo> items) {
- ArrayList<ShortcutInfo> extra = new ArrayList<ShortcutInfo>();
- setupContentDimensions(Math.min(items.size(), mMaxNumItems));
-
- int countX = getCountX();
- int rank = 0;
- for (ShortcutInfo item : items) {
- if (rank >= mMaxNumItems) {
- extra.add(item);
- continue;
- }
-
- item.rank = rank;
- item.cellX = rank % countX;
- item.cellY = rank / countX;
- addNewView(item);
- rank++;
- }
- return extra;
- }
-
- @Override
- public int allocateRankForNewItem(ShortcutInfo info) {
- int rank = getItemCount();
- mFolder.rearrangeChildren(rank + 1);
- return rank;
- }
-
- @Override
- public View createAndAddViewForRank(ShortcutInfo item, int rank) {
- updateItemXY(item, rank);
- return addNewView(item);
- }
-
- @Override
- public void addViewForRank(View view, ShortcutInfo item, int rank) {
- updateItemXY(item, rank);
- CellLayout.LayoutParams lp = (CellLayout.LayoutParams) view.getLayoutParams();
- lp.cellX = item.cellX;
- lp.cellY = item.cellY;
- addViewToCellLayout(view, -1, mFolder.mLauncher.getViewIdForItem(item), lp, true);
- }
-
- @Override
- public void removeItem(View v) {
- removeView(v);
- }
-
- /**
- * Updates the item cellX and cellY position
- */
- private void updateItemXY(ShortcutInfo item, int rank) {
- item.rank = rank;
- int countX = getCountX();
- item.cellX = rank % countX;
- item.cellY = rank / countX;
- }
-
- private View addNewView(ShortcutInfo item) {
- final BubbleTextView textView = (BubbleTextView) mInflater.inflate(
- R.layout.folder_application, getShortcutsAndWidgets(), false);
- textView.applyFromShortcutInfo(item, mIconCache, false);
- textView.setOnClickListener(mFolder);
- textView.setOnLongClickListener(mFolder);
- textView.setOnFocusChangeListener(mFocusIndicatorView);
- textView.setOnKeyListener(mKeyListener);
-
- CellLayout.LayoutParams lp = new CellLayout.LayoutParams(
- item.cellX, item.cellY, item.spanX, item.spanY);
- addViewToCellLayout(textView, -1, mFolder.mLauncher.getViewIdForItem(item), lp, true);
- return textView;
- }
-
- /**
- * Refer {@link #findNearestArea(int, int, int, int, View, boolean, int[])}
- */
- @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;
- }
-
- // Convert this position to rank.
- return Math.min(mAllocatedContentSize - 1,
- sTempPosArray[1] * getCountX() + sTempPosArray[0]);
- }
-
- @Override
- public boolean isFull() {
- return getItemCount() >= mMaxNumItems;
- }
-
- @Override
- public int getItemCount() {
- return getShortcutsAndWidgets().getChildCount();
- }
-
- @Override
- public void arrangeChildren(ArrayList<View> list, int itemCount) {
- setupContentDimensions(itemCount);
- removeAllViews();
-
- int newX, newY;
- int rank = 0;
- int countX = getCountX();
- for (View v : list) {
- CellLayout.LayoutParams lp = (CellLayout.LayoutParams) v.getLayoutParams();
- newX = rank % countX;
- newY = rank / countX;
- ItemInfo info = (ItemInfo) v.getTag();
- if (info.cellX != newX || info.cellY != newY || info.rank != rank) {
- info.cellX = newX;
- info.cellY = newY;
- info.rank = rank;
- LauncherModel.addOrMoveItemInDatabase(getContext(), info,
- mFolder.mInfo.id, 0, info.cellX, info.cellY);
- }
- lp.cellX = info.cellX;
- lp.cellY = info.cellY;
- rank ++;
- addViewToCellLayout(v, -1, mFolder.mLauncher.getViewIdForItem(info), lp, true);
- }
- }
-
- @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 lastRank = getShortcutsAndWidgets().getChildCount() - 1;
- // count can be zero if the folder is not yet laid out.
- int count = getCountX();
- if (count > 0) {
- return getShortcutsAndWidgets().getChildAt(lastRank % count, lastRank / count);
- } else {
- return getShortcutsAndWidgets().getChildAt(lastRank);
- }
- }
-
- @Override
- public void realTimeReorder(int empty, int target) {
- boolean wrap;
- int startX;
- int endX;
- int startY;
- int delay = 0;
- float delayAmount = START_VIEW_REORDER_DELAY;
-
- int countX = getCountX();
- int emptyX = empty % getCountX();
- int emptyY = empty / countX;
-
- int targetX = target % countX;
- int targetY = target / countX;
-
- if (target > empty) {
- wrap = emptyX == countX - 1;
- startY = wrap ? emptyY + 1 : emptyY;
- for (int y = startY; y <= targetY; y++) {
- startX = y == emptyY ? emptyX + 1 : 0;
- endX = y < targetY ? countX - 1 : targetX;
- for (int x = startX; x <= endX; x++) {
- View v = getChildAt(x,y);
- if (animateChildToPosition(v, emptyX, emptyY,
- REORDER_ANIMATION_DURATION, delay, true, true)) {
- emptyX = x;
- emptyY = y;
- delay += delayAmount;
- delayAmount *= VIEW_REORDER_DELAY_FACTOR;
- }
- }
- }
- } else {
- wrap = emptyX == 0;
- startY = wrap ? emptyY - 1 : emptyY;
- for (int y = startY; y >= targetY; y--) {
- startX = y == emptyY ? emptyX - 1 : countX - 1;
- endX = y > targetY ? 0 : targetX;
- for (int x = startX; x >= endX; x--) {
- View v = getChildAt(x,y);
- if (animateChildToPosition(v, emptyX, emptyY,
- REORDER_ANIMATION_DURATION, delay, true, true)) {
- emptyX = x;
- emptyY = y;
- delay += delayAmount;
- delayAmount *= VIEW_REORDER_DELAY_FACTOR;
- }
- }
- }
- }
- }
-}
diff --git a/src/com/android/launcher3/FolderPagedView.java b/src/com/android/launcher3/FolderPagedView.java
index 1c42d2592..247c55246 100644
--- a/src/com/android/launcher3/FolderPagedView.java
+++ b/src/com/android/launcher3/FolderPagedView.java
@@ -19,7 +19,6 @@ package com.android.launcher3;
import android.annotation.SuppressLint;
import android.content.Context;
import android.util.AttributeSet;
-import android.util.LayoutDirection;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
@@ -42,10 +41,15 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
-public class FolderPagedView extends PagedView implements Folder.FolderContent {
+public class FolderPagedView extends PagedView {
private static final String TAG = "FolderPagedView";
+ private static final boolean ALLOW_FOLDER_SCROLL = true;
+
+ // To enable this flag, user_folder.xml needs to be modified to add sort button.
+ private static final boolean ALLOW_ITEM_SORTING = false;
+
private static final int REORDER_ANIMATION_DURATION = 230;
private static final int START_VIEW_REORDER_DELAY = 30;
private static final float VIEW_REORDER_DELAY_FACTOR = 0.9f;
@@ -96,32 +100,38 @@ public class FolderPagedView extends PagedView implements Folder.FolderContent {
setDataIsReady();
DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
- mMaxCountX = Math.min((int) grid.numColumns, MAX_ITEMS_PER_PAGE);
- mMaxCountY = Math.min((int) grid.numRows, MAX_ITEMS_PER_PAGE);
+ if (ALLOW_FOLDER_SCROLL) {
+ mMaxCountX = Math.min((int) grid.numColumns, MAX_ITEMS_PER_PAGE);
+ mMaxCountY = Math.min((int) grid.numRows, MAX_ITEMS_PER_PAGE);
+ } else {
+ mMaxCountX = (int) grid.numColumns;
+ mMaxCountY = (int) grid.numRows;
+ }
+
mMaxItemsPerPage = mMaxCountX * mMaxCountY;
mInflater = LayoutInflater.from(context);
mIconCache = app.getIconCache();
- rtlLayout = getResources().getConfiguration().getLayoutDirection() == LayoutDirection.RTL;
+ rtlLayout = getResources().getConfiguration().getLayoutDirection() == LAYOUT_DIRECTION_RTL;
}
- @Override
public void setFolder(Folder folder) {
mFolder = folder;
mFocusIndicatorView = (FocusIndicatorView) folder.findViewById(R.id.focus_indicator);
mKeyListener = new PagedFolderKeyEventListener(folder);
+ mPageIndicator = folder.findViewById(R.id.folder_page_indicator);
- mSortButton = folder.findViewById(R.id.folder_sort);
- mSortButton.setOnClickListener(new OnClickListener() {
+ if (ALLOW_ITEM_SORTING) {
+ // Initialize {@link #mSortSwitch} and {@link #mSortButton}.
+ mSortButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- onSortClicked();
- }
- });
- mPageIndicator = folder.findViewById(R.id.folder_page_indicator);
- mSortSwitch = (Switch) folder.findViewById(R.id.folder_sort_switch);
+ @Override
+ public void onClick(View v) {
+ onSortClicked();
+ }
+ });
+ }
}
private void onSortClicked() {
@@ -138,9 +148,11 @@ public class FolderPagedView extends PagedView implements Folder.FolderContent {
private void setIsSorted(boolean isSorted, boolean saveChanges) {
mIsSorted = isSorted;
- mSortSwitch.setChecked(isSorted);
- mFolder.mInfo.setOption(FolderInfo.FLAG_ITEMS_SORTED, isSorted,
- saveChanges ? mFolder.mLauncher : null);
+ if (ALLOW_ITEM_SORTING) {
+ mSortSwitch.setChecked(isSorted);
+ mFolder.mInfo.setOption(FolderInfo.FLAG_ITEMS_SORTED, isSorted,
+ saveChanges ? mFolder.mLauncher : null);
+ }
}
/**
@@ -282,26 +294,34 @@ public class FolderPagedView extends PagedView implements Folder.FolderContent {
}
}
- @Override
+ /**
+ * Binds items to the layout.
+ * @return list of items that could not be bound, probably because we hit the max size limit.
+ */
public ArrayList<ShortcutInfo> bindItems(ArrayList<ShortcutInfo> items) {
- mIsSorted = mFolder.mInfo.hasOption(FolderInfo.FLAG_ITEMS_SORTED);
+ mIsSorted = ALLOW_ITEM_SORTING && mFolder.mInfo.hasOption(FolderInfo.FLAG_ITEMS_SORTED);
ArrayList<View> icons = new ArrayList<View>();
+ ArrayList<ShortcutInfo> extra = new ArrayList<ShortcutInfo>();
+
for (ShortcutInfo item : items) {
- icons.add(createNewView(item));
+ if (!ALLOW_FOLDER_SCROLL && icons.size() >= mMaxItemsPerPage) {
+ extra.add(item);
+ } else {
+ icons.add(createNewView(item));
+ }
}
arrangeChildren(icons, icons.size(), false);
- return new ArrayList<ShortcutInfo>();
+ return extra;
}
/**
* Create space for a new item at the end, and returns the rank for that item.
* Also sets the current page to the last page.
*/
- @Override
public int allocateRankForNewItem(ShortcutInfo info) {
int rank = getItemCount();
ArrayList<View> views = new ArrayList<View>(mFolder.getItemsInReadingOrder());
- if (mIsSorted) {
+ if (ALLOW_ITEM_SORTING && mIsSorted) {
View tmp = new View(getContext());
tmp.setTag(info);
int index = Collections.binarySearch(views, tmp, new ViewComparator());
@@ -321,14 +341,16 @@ public class FolderPagedView extends PagedView implements Folder.FolderContent {
return rank;
}
- @Override
public View createAndAddViewForRank(ShortcutInfo item, int rank) {
View icon = createNewView(item);
addViewForRank(icon, item, rank);
return icon;
}
- @Override
+ /**
+ * 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.
+ */
public void addViewForRank(View view, ShortcutInfo item, int rank) {
int pagePos = rank % mMaxItemsPerPage;
int pageNo = rank / mMaxItemsPerPage;
@@ -388,14 +410,12 @@ public class FolderPagedView extends PagedView implements Folder.FolderContent {
return page;
}
- @Override
public void setFixedSize(int width, int height) {
for (int i = getChildCount() - 1; i >= 0; i --) {
((CellLayout) getChildAt(i)).setFixedSize(width, height);
}
}
- @Override
public void removeItem(View v) {
for (int i = getChildCount() - 1; i >= 0; i --) {
getPageAt(i).removeView(v);
@@ -412,7 +432,6 @@ public class FolderPagedView extends PagedView implements Folder.FolderContent {
* at the end, otherwise it is ignored.
*
*/
- @Override
public void arrangeChildren(ArrayList<View> list, int itemCount) {
arrangeChildren(list, itemCount, true);
}
@@ -488,19 +507,26 @@ public class FolderPagedView extends PagedView implements Folder.FolderContent {
setCurrentPage(0);
}
- setIsSorted(isSorted, saveChanges);
+ setEnableOverscroll(getPageCount() > 1);
// Update footer
- if (getPageCount() > 1) {
- mPageIndicator.setVisibility(View.VISIBLE);
- mSortButton.setVisibility(View.VISIBLE);
- mFolder.mFolderName.setGravity(rtlLayout ? Gravity.RIGHT : Gravity.LEFT);
- setEnableOverscroll(true);
+ if (ALLOW_ITEM_SORTING) {
+ setIsSorted(isSorted, saveChanges);
+ if (getPageCount() > 1) {
+ mPageIndicator.setVisibility(View.VISIBLE);
+ mSortButton.setVisibility(View.VISIBLE);
+ mFolder.mFolderName.setGravity(rtlLayout ? Gravity.RIGHT : Gravity.LEFT);
+ } else {
+ mPageIndicator.setVisibility(View.GONE);
+ mSortButton.setVisibility(View.GONE);
+ mFolder.mFolderName.setGravity(Gravity.CENTER_HORIZONTAL);
+ }
} else {
- mPageIndicator.setVisibility(View.GONE);
- mSortButton.setVisibility(View.GONE);
- mFolder.mFolderName.setGravity(Gravity.CENTER_HORIZONTAL);
- setEnableOverscroll(false);
+ int indicatorVisibility = mPageIndicator.getVisibility();
+ mPageIndicator.setVisibility(getPageCount() > 1 ? View.VISIBLE : View.GONE);
+ if (indicatorVisibility != mPageIndicator.getVisibility()) {
+ mFolder.updateFooterHeight();
+ }
}
}
@@ -521,7 +547,6 @@ public class FolderPagedView extends PagedView implements Folder.FolderContent {
return getPageCount() > 0 ? getPageAt(0).getDesiredHeight() : 0;
}
- @Override
public int getItemCount() {
int lastPageIndex = getChildCount() - 1;
if (lastPageIndex < 0) {
@@ -532,7 +557,9 @@ public class FolderPagedView extends PagedView implements Folder.FolderContent {
+ lastPageIndex * mMaxItemsPerPage;
}
- @Override
+ /**
+ * @return the rank of the cell nearest to the provided pixel position.
+ */
public int findNearestArea(int pixelX, int pixelY) {
int pageIndex = getNextPage();
CellLayout page = getPageAt(pageIndex);
@@ -550,12 +577,10 @@ public class FolderPagedView extends PagedView implements Folder.FolderContent {
R.drawable.ic_pageindicator_default_folder);
}
- @Override
public boolean isFull() {
- return false;
+ return !ALLOW_FOLDER_SCROLL && getItemCount() >= mMaxItemsPerPage;
}
- @Override
public View getLastItem() {
if (getChildCount() < 1) {
return null;
@@ -569,7 +594,10 @@ public class FolderPagedView extends PagedView implements Folder.FolderContent {
}
}
- @Override
+ /**
+ * Iterates over all its items in a reading order.
+ * @return the view for which the operator returned true.
+ */
public View iterateOverItems(ItemOperator op) {
for (int k = 0 ; k < getChildCount(); k++) {
CellLayout page = getPageAt(k);
@@ -585,13 +613,14 @@ public class FolderPagedView extends PagedView implements Folder.FolderContent {
return null;
}
- @Override
public String getAccessibilityDescription() {
return String.format(getContext().getString(R.string.folder_opened),
mGridCountX, mGridCountY);
}
- @Override
+ /**
+ * Sets the focus on the first visible child.
+ */
public void setFocusOnFirstChild() {
View firstChild = getCurrentCellLayout().getChildAt(0, 0);
if (firstChild != null) {
@@ -605,7 +634,7 @@ public class FolderPagedView extends PagedView implements Folder.FolderContent {
if (mFolder != null) {
mFolder.updateTextViewFocus();
}
- if (mSortOperationPending && getNextPage() == 0) {
+ if (ALLOW_ITEM_SORTING && mSortOperationPending && getNextPage() == 0) {
post(new Runnable() {
@Override
@@ -680,7 +709,9 @@ public class FolderPagedView extends PagedView implements Folder.FolderContent {
}
}
- @Override
+ /**
+ * Reorders the items such that the {@param empty} spot moves to {@param target}
+ */
public void realTimeReorder(int empty, int target) {
completePendingPageChanges();
int delay = 0;