Goodbye folder sorting
> Removing all traces of folder sorting Change-Id: Id77a7745564c869f5c5c1b3a560bf606fe08b107
This commit is contained in:
@@ -77,7 +77,7 @@
|
|||||||
<!-- Search bar text in the apps view. [CHAR_LIMIT=50] -->
|
<!-- Search bar text in the apps view. [CHAR_LIMIT=50] -->
|
||||||
<string name="apps_view_search_bar_hint">Search Apps</string>
|
<string name="apps_view_search_bar_hint">Search Apps</string>
|
||||||
<!-- Loading apps text. [CHAR_LIMIT=50] -->
|
<!-- Loading apps text. [CHAR_LIMIT=50] -->
|
||||||
<string name="loading_apps_message">Loading Apps...</string>
|
<string name="loading_apps_message">Loading Apps…</string>
|
||||||
<!-- No-search-results text. [CHAR_LIMIT=50] -->
|
<!-- No-search-results text. [CHAR_LIMIT=50] -->
|
||||||
<string name="apps_view_no_search_results">No Apps found matching \"<xliff:g id="query" example="Android">%1$s</xliff:g>\"</string>
|
<string name="apps_view_no_search_results">No Apps found matching \"<xliff:g id="query" example="Android">%1$s</xliff:g>\"</string>
|
||||||
|
|
||||||
@@ -91,8 +91,6 @@
|
|||||||
<string name="rename_action">OK</string>
|
<string name="rename_action">OK</string>
|
||||||
<!-- Buttons in Rename folder dialog box -->
|
<!-- Buttons in Rename folder dialog box -->
|
||||||
<string name="cancel_action">Cancel</string>
|
<string name="cancel_action">Cancel</string>
|
||||||
<!-- Label for button to sort folder contents. [CHAR_LIMIT=10] -->
|
|
||||||
<string name="sort_alphabetical">A-Z</string>
|
|
||||||
|
|
||||||
<!-- Shortcuts -->
|
<!-- Shortcuts -->
|
||||||
<skip />
|
<skip />
|
||||||
|
|||||||
@@ -82,12 +82,6 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
|
|||||||
*/
|
*/
|
||||||
public static final int SCROLL_HINT_DURATION = DragController.SCROLL_DELAY;
|
public static final int SCROLL_HINT_DURATION = DragController.SCROLL_DELAY;
|
||||||
|
|
||||||
/**
|
|
||||||
* Time in milliseconds for which an icon sticks to the target position
|
|
||||||
* in case of a sorted folder.
|
|
||||||
*/
|
|
||||||
private static final int SORTED_STICKY_REORDER_DELAY = 1500;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fraction of icon width which behave as scroll region.
|
* Fraction of icon width which behave as scroll region.
|
||||||
*/
|
*/
|
||||||
@@ -417,7 +411,7 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
|
|||||||
if (!(getParent() instanceof DragLayer)) return;
|
if (!(getParent() instanceof DragLayer)) return;
|
||||||
|
|
||||||
mContent.completePendingPageChanges();
|
mContent.completePendingPageChanges();
|
||||||
if (!(mDragInProgress && mContent.mIsSorted)) {
|
if (!mDragInProgress) {
|
||||||
// Open on the first page.
|
// Open on the first page.
|
||||||
mContent.snapToPageImmediately(0);
|
mContent.snapToPageImmediately(0);
|
||||||
}
|
}
|
||||||
@@ -533,12 +527,6 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
|
|||||||
mIsExternalDrag = true;
|
mIsExternalDrag = true;
|
||||||
mDragInProgress = true;
|
mDragInProgress = true;
|
||||||
|
|
||||||
if (mContent.mIsSorted) {
|
|
||||||
mScrollPauseAlarm.setOnAlarmListener(null);
|
|
||||||
mScrollPauseAlarm.cancelAlarm();
|
|
||||||
mScrollPauseAlarm.setAlarm(SORTED_STICKY_REORDER_DELAY);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Since this folder opened by another controller, it might not get onDrop or
|
// Since this folder opened by another controller, it might not get onDrop or
|
||||||
// onDropComplete. Perform cleanup once drag-n-drop ends.
|
// onDropComplete. Perform cleanup once drag-n-drop ends.
|
||||||
mDragController.addDragListener(this);
|
mDragController.addDragListener(this);
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ public class FolderInfo extends ItemInfo {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The folder is locked in sorted mode
|
* The folder is locked in sorted mode
|
||||||
|
* @deprecated
|
||||||
*/
|
*/
|
||||||
public static final int FLAG_ITEMS_SORTED = 0x00000001;
|
public static final int FLAG_ITEMS_SORTED = 0x00000001;
|
||||||
|
|
||||||
|
|||||||
@@ -20,23 +20,16 @@ import android.annotation.SuppressLint;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.Gravity;
|
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.animation.DecelerateInterpolator;
|
import android.view.animation.DecelerateInterpolator;
|
||||||
import android.view.animation.Interpolator;
|
|
||||||
import android.view.animation.OvershootInterpolator;
|
|
||||||
import android.widget.Switch;
|
|
||||||
|
|
||||||
import com.android.launcher3.FocusHelper.PagedFolderKeyEventListener;
|
import com.android.launcher3.FocusHelper.PagedFolderKeyEventListener;
|
||||||
import com.android.launcher3.PageIndicator.PageMarkerResources;
|
import com.android.launcher3.PageIndicator.PageMarkerResources;
|
||||||
import com.android.launcher3.Workspace.ItemOperator;
|
import com.android.launcher3.Workspace.ItemOperator;
|
||||||
import com.android.launcher3.util.Thunk;
|
import com.android.launcher3.util.Thunk;
|
||||||
|
|
||||||
import java.text.Collator;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -47,17 +40,10 @@ public class FolderPagedView extends PagedView {
|
|||||||
|
|
||||||
private static final boolean ALLOW_FOLDER_SCROLL = true;
|
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 REORDER_ANIMATION_DURATION = 230;
|
||||||
private static final int START_VIEW_REORDER_DELAY = 30;
|
private static final int START_VIEW_REORDER_DELAY = 30;
|
||||||
private static final float VIEW_REORDER_DELAY_FACTOR = 0.9f;
|
private static final float VIEW_REORDER_DELAY_FACTOR = 0.9f;
|
||||||
|
|
||||||
private static final int SPAN_TO_PAGE_DURATION = 350;
|
|
||||||
private static final int SORT_ANIM_HIDE_DURATION = 130;
|
|
||||||
private static final int SORT_ANIM_SHOW_DURATION = 160;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fraction of the width to scroll when showing the next page hint.
|
* Fraction of the width to scroll when showing the next page hint.
|
||||||
*/
|
*/
|
||||||
@@ -87,13 +73,8 @@ public class FolderPagedView extends PagedView {
|
|||||||
private FocusIndicatorView mFocusIndicatorView;
|
private FocusIndicatorView mFocusIndicatorView;
|
||||||
private PagedFolderKeyEventListener mKeyListener;
|
private PagedFolderKeyEventListener mKeyListener;
|
||||||
|
|
||||||
private View mSortButton;
|
|
||||||
private Switch mSortSwitch;
|
|
||||||
private View mPageIndicator;
|
private View mPageIndicator;
|
||||||
|
|
||||||
private boolean mSortOperationPending;
|
|
||||||
boolean mIsSorted;
|
|
||||||
|
|
||||||
public FolderPagedView(Context context, AttributeSet attrs) {
|
public FolderPagedView(Context context, AttributeSet attrs) {
|
||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
LauncherAppState app = LauncherAppState.getInstance();
|
LauncherAppState app = LauncherAppState.getInstance();
|
||||||
@@ -121,132 +102,6 @@ public class FolderPagedView extends PagedView {
|
|||||||
mFocusIndicatorView = (FocusIndicatorView) folder.findViewById(R.id.focus_indicator);
|
mFocusIndicatorView = (FocusIndicatorView) folder.findViewById(R.id.focus_indicator);
|
||||||
mKeyListener = new PagedFolderKeyEventListener(folder);
|
mKeyListener = new PagedFolderKeyEventListener(folder);
|
||||||
mPageIndicator = folder.findViewById(R.id.folder_page_indicator);
|
mPageIndicator = folder.findViewById(R.id.folder_page_indicator);
|
||||||
|
|
||||||
if (ALLOW_ITEM_SORTING) {
|
|
||||||
// Initialize {@link #mSortSwitch} and {@link #mSortButton}.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when sort button is clicked.
|
|
||||||
*/
|
|
||||||
private void onSortClicked() {
|
|
||||||
if (mSortOperationPending) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (mIsSorted) {
|
|
||||||
setIsSorted(false, true);
|
|
||||||
} else {
|
|
||||||
mSortOperationPending = true;
|
|
||||||
doSort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setIsSorted(boolean isSorted, boolean saveChanges) {
|
|
||||||
mIsSorted = isSorted;
|
|
||||||
if (ALLOW_ITEM_SORTING) {
|
|
||||||
mSortSwitch.setChecked(isSorted);
|
|
||||||
mFolder.mInfo.setOption(FolderInfo.FLAG_ITEMS_SORTED, isSorted,
|
|
||||||
saveChanges ? mFolder.mLauncher : null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sorts the contents of the folder and animates the icons on the first page to reflect
|
|
||||||
* the changes.
|
|
||||||
* Steps:
|
|
||||||
* 1. Scroll to first page
|
|
||||||
* 2. Sort all icons in one go
|
|
||||||
* 3. Re-apply the old IconInfos on the first page (so that there is no instant change)
|
|
||||||
* 4. Animate each view individually to reflect the new icon.
|
|
||||||
*/
|
|
||||||
private void doSort() {
|
|
||||||
if (!mSortOperationPending) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (getNextPage() != 0) {
|
|
||||||
snapToPage(0, SPAN_TO_PAGE_DURATION, new DecelerateInterpolator());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mSortOperationPending = false;
|
|
||||||
ShortcutInfo[][] oldItems = new ShortcutInfo[mGridCountX][mGridCountY];
|
|
||||||
CellLayout currentPage = getCurrentCellLayout();
|
|
||||||
for (int x = 0; x < mGridCountX; x++) {
|
|
||||||
for (int y = 0; y < mGridCountY; y++) {
|
|
||||||
View v = currentPage.getChildAt(x, y);
|
|
||||||
if (v != null) {
|
|
||||||
oldItems[x][y] = (ShortcutInfo) v.getTag();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ArrayList<View> views = new ArrayList<View>(mFolder.getItemsInReadingOrder());
|
|
||||||
Collections.sort(views, new ViewComparator());
|
|
||||||
arrangeChildren(views, views.size());
|
|
||||||
|
|
||||||
int delay = 0;
|
|
||||||
float delayAmount = START_VIEW_REORDER_DELAY;
|
|
||||||
final Interpolator hideInterpolator = new DecelerateInterpolator(2);
|
|
||||||
final Interpolator showInterpolator = new OvershootInterpolator(0.8f);
|
|
||||||
|
|
||||||
currentPage = getCurrentCellLayout();
|
|
||||||
for (int x = 0; x < mGridCountX; x++) {
|
|
||||||
for (int y = 0; y < mGridCountY; y++) {
|
|
||||||
final BubbleTextView v = (BubbleTextView) currentPage.getChildAt(x, y);
|
|
||||||
if (v != null) {
|
|
||||||
final ShortcutInfo info = (ShortcutInfo) v.getTag();
|
|
||||||
final Runnable clearPending = new Runnable() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
mPendingAnimations.remove(v);
|
|
||||||
v.setScaleX(1);
|
|
||||||
v.setScaleY(1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if (oldItems[x][y] == null) {
|
|
||||||
v.setScaleX(0);
|
|
||||||
v.setScaleY(0);
|
|
||||||
v.animate().setDuration(SORT_ANIM_SHOW_DURATION)
|
|
||||||
.setStartDelay(SORT_ANIM_HIDE_DURATION + delay)
|
|
||||||
.scaleX(1).scaleY(1).setInterpolator(showInterpolator)
|
|
||||||
.withEndAction(clearPending);
|
|
||||||
mPendingAnimations.put(v, clearPending);
|
|
||||||
} else {
|
|
||||||
// Apply the old iconInfo so that there is no sudden change.
|
|
||||||
v.applyFromShortcutInfo(oldItems[x][y], mIconCache, false);
|
|
||||||
v.animate().setStartDelay(delay).setDuration(SORT_ANIM_HIDE_DURATION)
|
|
||||||
.scaleX(0).scaleY(0)
|
|
||||||
.setInterpolator(hideInterpolator)
|
|
||||||
.withEndAction(new Runnable() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
// Apply the new iconInfo as part of the animation.
|
|
||||||
v.applyFromShortcutInfo(info, mIconCache, false);
|
|
||||||
v.animate().scaleX(1).scaleY(1)
|
|
||||||
.setDuration(SORT_ANIM_SHOW_DURATION).setStartDelay(0)
|
|
||||||
.setInterpolator(showInterpolator)
|
|
||||||
.withEndAction(clearPending);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
mPendingAnimations.put(v, new Runnable() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
clearPending.run();
|
|
||||||
v.applyFromShortcutInfo(info, mIconCache, false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
delay += delayAmount;
|
|
||||||
delayAmount *= VIEW_REORDER_DELAY_FACTOR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setIsSorted(true, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -295,7 +150,6 @@ public class FolderPagedView extends PagedView {
|
|||||||
* @return list of items that could not be bound, probably because we hit the max size limit.
|
* @return list of items that could not be bound, probably because we hit the max size limit.
|
||||||
*/
|
*/
|
||||||
public ArrayList<ShortcutInfo> bindItems(ArrayList<ShortcutInfo> items) {
|
public ArrayList<ShortcutInfo> bindItems(ArrayList<ShortcutInfo> items) {
|
||||||
mIsSorted = ALLOW_ITEM_SORTING && mFolder.mInfo.hasOption(FolderInfo.FLAG_ITEMS_SORTED);
|
|
||||||
ArrayList<View> icons = new ArrayList<View>();
|
ArrayList<View> icons = new ArrayList<View>();
|
||||||
ArrayList<ShortcutInfo> extra = new ArrayList<ShortcutInfo>();
|
ArrayList<ShortcutInfo> extra = new ArrayList<ShortcutInfo>();
|
||||||
|
|
||||||
@@ -317,20 +171,6 @@ public class FolderPagedView extends PagedView {
|
|||||||
public int allocateRankForNewItem(ShortcutInfo info) {
|
public int allocateRankForNewItem(ShortcutInfo info) {
|
||||||
int rank = getItemCount();
|
int rank = getItemCount();
|
||||||
ArrayList<View> views = new ArrayList<View>(mFolder.getItemsInReadingOrder());
|
ArrayList<View> views = new ArrayList<View>(mFolder.getItemsInReadingOrder());
|
||||||
if (ALLOW_ITEM_SORTING && mIsSorted) {
|
|
||||||
View tmp = new View(getContext());
|
|
||||||
tmp.setTag(info);
|
|
||||||
int index = Collections.binarySearch(views, tmp, new ViewComparator());
|
|
||||||
if (index < 0) {
|
|
||||||
rank = -index - 1;
|
|
||||||
} else {
|
|
||||||
// Item with same name already exists.
|
|
||||||
// We will just insert it before that item.
|
|
||||||
rank = index;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
views.add(rank, null);
|
views.add(rank, null);
|
||||||
arrangeChildren(views, views.size(), false);
|
arrangeChildren(views, views.size(), false);
|
||||||
setCurrentPage(rank / mMaxItemsPerPage);
|
setCurrentPage(rank / mMaxItemsPerPage);
|
||||||
@@ -447,10 +287,6 @@ public class FolderPagedView extends PagedView {
|
|||||||
int position = 0;
|
int position = 0;
|
||||||
int newX, newY, rank;
|
int newX, newY, rank;
|
||||||
|
|
||||||
boolean isSorted = mIsSorted;
|
|
||||||
|
|
||||||
ViewComparator comparator = new ViewComparator();
|
|
||||||
View lastView = null;
|
|
||||||
rank = 0;
|
rank = 0;
|
||||||
for (int i = 0; i < itemCount; i++) {
|
for (int i = 0; i < itemCount; i++) {
|
||||||
View v = list.size() > i ? list.get(i) : null;
|
View v = list.size() > i ? list.get(i) : null;
|
||||||
@@ -465,10 +301,6 @@ public class FolderPagedView extends PagedView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (v != null) {
|
if (v != null) {
|
||||||
if (lastView != null) {
|
|
||||||
isSorted &= comparator.compare(lastView, v) <= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) v.getLayoutParams();
|
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) v.getLayoutParams();
|
||||||
newX = position % mGridCountX;
|
newX = position % mGridCountX;
|
||||||
newY = position / mGridCountX;
|
newY = position / mGridCountX;
|
||||||
@@ -488,7 +320,6 @@ public class FolderPagedView extends PagedView {
|
|||||||
v, -1, mFolder.mLauncher.getViewIdForItem(info), lp, true);
|
v, -1, mFolder.mLauncher.getViewIdForItem(info), lp, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
lastView = v;
|
|
||||||
rank ++;
|
rank ++;
|
||||||
position++;
|
position++;
|
||||||
}
|
}
|
||||||
@@ -506,23 +337,10 @@ public class FolderPagedView extends PagedView {
|
|||||||
setEnableOverscroll(getPageCount() > 1);
|
setEnableOverscroll(getPageCount() > 1);
|
||||||
|
|
||||||
// Update footer
|
// Update footer
|
||||||
if (ALLOW_ITEM_SORTING) {
|
int indicatorVisibility = mPageIndicator.getVisibility();
|
||||||
setIsSorted(isSorted, saveChanges);
|
mPageIndicator.setVisibility(getPageCount() > 1 ? View.VISIBLE : View.GONE);
|
||||||
if (getPageCount() > 1) {
|
if (indicatorVisibility != mPageIndicator.getVisibility()) {
|
||||||
mPageIndicator.setVisibility(View.VISIBLE);
|
mFolder.updateFooterHeight();
|
||||||
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 {
|
|
||||||
int indicatorVisibility = mPageIndicator.getVisibility();
|
|
||||||
mPageIndicator.setVisibility(getPageCount() > 1 ? View.VISIBLE : View.GONE);
|
|
||||||
if (indicatorVisibility != mPageIndicator.getVisibility()) {
|
|
||||||
mFolder.updateFooterHeight();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -630,17 +448,6 @@ public class FolderPagedView extends PagedView {
|
|||||||
if (mFolder != null) {
|
if (mFolder != null) {
|
||||||
mFolder.updateTextViewFocus();
|
mFolder.updateTextViewFocus();
|
||||||
}
|
}
|
||||||
if (ALLOW_ITEM_SORTING && mSortOperationPending && getNextPage() == 0) {
|
|
||||||
post(new Runnable() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
if (mSortOperationPending) {
|
|
||||||
doSort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -829,14 +636,4 @@ public class FolderPagedView extends PagedView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class ViewComparator implements Comparator<View> {
|
|
||||||
private final Collator mCollator = Collator.getInstance();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int compare(View lhs, View rhs) {
|
|
||||||
return mCollator.compare( ((ShortcutInfo) lhs.getTag()).title.toString(),
|
|
||||||
((ShortcutInfo) rhs.getTag()).title.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user