Adding sort switch in FolderPagedView
> Adding options column in DB to store generation purpose flags > Storing isSorted flag in FolderInfo > Adding a switch for A-Z sorting (only visible if pageCount > 1) > When in sorted mode, spring-load snaps to the target location for 1.5 seconds Change-Id: I8c7c778d2cc3ccbd35a2890a1a705e1c1a7e9a66
This commit is contained in:
@@ -45,7 +45,9 @@
|
||||
android:id="@+id/folder_footer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal" >
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="12dp"
|
||||
android:paddingEnd="8dp" >
|
||||
|
||||
<com.android.launcher3.FolderEditText
|
||||
android:id="@+id/folder_name"
|
||||
@@ -55,7 +57,7 @@
|
||||
android:layout_weight="1"
|
||||
android:background="#00000000"
|
||||
android:fontFamily="sans-serif-condensed"
|
||||
android:gravity="center_horizontal"
|
||||
android:gravity="start"
|
||||
android:hint="@string/folder_hint_text"
|
||||
android:imeOptions="flagNoExtractUi"
|
||||
android:paddingBottom="@dimen/folder_name_padding"
|
||||
@@ -71,8 +73,34 @@
|
||||
android:id="@+id/folder_page_indicator"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="12dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
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>
|
||||
@@ -89,6 +89,8 @@
|
||||
<string name="rename_action">OK</string>
|
||||
<!-- Buttons in Rename folder dialog box -->
|
||||
<string name="cancel_action">Cancel</string>
|
||||
<!-- Label for button to sort folder contents. [CHAR_LIMIT=10] -->
|
||||
<string name="sort_alphabetical">A-Z</string>
|
||||
|
||||
<!-- Shortcuts -->
|
||||
<skip />
|
||||
|
||||
@@ -85,6 +85,12 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
@@ -423,8 +429,11 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
|
||||
if (!(getParent() instanceof DragLayer)) return;
|
||||
|
||||
if (ALLOW_FOLDER_SCROLL) {
|
||||
// Always open on the first page.
|
||||
mPagedView.snapToPageImmediately(0);
|
||||
mPagedView.completePendingPageChanges();
|
||||
if (!(mDragInProgress && mPagedView.mIsSorted)) {
|
||||
// Open on the first page.
|
||||
mPagedView.snapToPageImmediately(0);
|
||||
}
|
||||
}
|
||||
|
||||
Animator openFolderAnim = null;
|
||||
@@ -531,9 +540,15 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
|
||||
|
||||
public void beginExternalDrag(ShortcutInfo item) {
|
||||
mCurrentDragInfo = item;
|
||||
mEmptyCellRank = mContent.allocateNewLastItemRank();
|
||||
mEmptyCellRank = mContent.allocateRankForNewItem(item);
|
||||
mIsExternalDrag = true;
|
||||
mDragInProgress = true;
|
||||
if (ALLOW_FOLDER_SCROLL && mPagedView.mIsSorted) {
|
||||
mScrollPauseAlarm.setOnAlarmListener(null);
|
||||
mScrollPauseAlarm.cancelAlarm();
|
||||
mScrollPauseAlarm.setAlarm(SORTED_STICKY_REORDER_DELAY);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void sendCustomAccessibilityEvent(int type, String text) {
|
||||
@@ -747,6 +762,7 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
|
||||
if (!successfulDrop) {
|
||||
mSuppressFolderDeletion = true;
|
||||
}
|
||||
mScrollPauseAlarm.cancelAlarm();
|
||||
completeDragExit();
|
||||
}
|
||||
}
|
||||
@@ -1155,7 +1171,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.createAndAddViewForRank(item, mContent.allocateNewLastItemRank());
|
||||
mContent.createAndAddViewForRank(item, mContent.allocateRankForNewItem(item));
|
||||
LauncherModel.addOrMoveItemInDatabase(
|
||||
mLauncher, item, mInfo.id, 0, item.cellX, item.cellY);
|
||||
}
|
||||
@@ -1304,10 +1320,10 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
|
||||
ArrayList<ShortcutInfo> bindItems(ArrayList<ShortcutInfo> children);
|
||||
|
||||
/**
|
||||
* Create space for a new item at the end, and returns the rank for that item.
|
||||
* Create space for a new item, and returns the rank for that item.
|
||||
* Resizes the content if necessary.
|
||||
*/
|
||||
int allocateNewLastItemRank();
|
||||
int allocateRankForNewItem(ShortcutInfo info);
|
||||
|
||||
View createAndAddViewForRank(ShortcutInfo item, int rank);
|
||||
|
||||
|
||||
@@ -133,7 +133,7 @@ public class FolderCellLayout extends CellLayout implements Folder.FolderContent
|
||||
}
|
||||
|
||||
@Override
|
||||
public int allocateNewLastItemRank() {
|
||||
public int allocateRankForNewItem(ShortcutInfo info) {
|
||||
int rank = getItemCount();
|
||||
mFolder.rearrangeChildren(rank + 1);
|
||||
return rank;
|
||||
|
||||
@@ -29,11 +29,20 @@ import java.util.Arrays;
|
||||
*/
|
||||
public class FolderInfo extends ItemInfo {
|
||||
|
||||
public static final int NO_FLAGS = 0x00000000;
|
||||
|
||||
/**
|
||||
* The folder is locked in sorted mode
|
||||
*/
|
||||
public static final int FLAG_ITEMS_SORTED = 0x00000001;
|
||||
|
||||
/**
|
||||
* Whether this folder has been opened
|
||||
*/
|
||||
boolean opened;
|
||||
|
||||
public int options;
|
||||
|
||||
/**
|
||||
* The apps and shortcuts
|
||||
*/
|
||||
@@ -83,6 +92,8 @@ public class FolderInfo extends ItemInfo {
|
||||
void onAddToDatabase(Context context, ContentValues values) {
|
||||
super.onAddToDatabase(context, values);
|
||||
values.put(LauncherSettings.Favorites.TITLE, title.toString());
|
||||
values.put(LauncherSettings.Favorites.OPTIONS, options);
|
||||
|
||||
}
|
||||
|
||||
void addListener(FolderListener listener) {
|
||||
@@ -121,4 +132,25 @@ public class FolderInfo extends ItemInfo {
|
||||
+ " cellX=" + cellX + " cellY=" + cellY + " spanX=" + spanX
|
||||
+ " spanY=" + spanY + " dropPos=" + Arrays.toString(dropPos) + ")";
|
||||
}
|
||||
|
||||
public boolean hasOption(int optionFlag) {
|
||||
return (options & optionFlag) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param option flag to set or clear
|
||||
* @param isEnabled whether to set or clear the flag
|
||||
* @param context if not null, save changes to the db.
|
||||
*/
|
||||
public void setOption(int option, boolean isEnabled, Context context) {
|
||||
int oldOptions = options;
|
||||
if (isEnabled) {
|
||||
options |= option;
|
||||
} else {
|
||||
options &= ~option;
|
||||
}
|
||||
if (context != null && oldOptions != options) {
|
||||
LauncherModel.updateItemInDatabase(context, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,15 +20,22 @@ import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
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.PageIndicator.PageMarkerResources;
|
||||
import com.android.launcher3.Workspace.ItemOperator;
|
||||
|
||||
import java.text.Collator;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
@@ -40,14 +47,19 @@ public class FolderPagedView extends PagedView 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 SPAN_TO_PAGE_DURATION = 350;
|
||||
private static final int SORT_ANIM_HIDE_DURATION = 130;
|
||||
private static final int SORT_ANIM_SHOW_DURATION = 160;
|
||||
|
||||
private static final int[] sTempPosArray = new int[2];
|
||||
|
||||
// TODO: Remove this restriction
|
||||
private static final int MAX_ITEMS_PER_PAGE = 3;
|
||||
private static final int MAX_ITEMS_PER_PAGE = 4;
|
||||
|
||||
private final LayoutInflater mInflater;
|
||||
private final IconCache mIconCache;
|
||||
private final HashMap<View, Runnable> mPageChangingViews = new HashMap<>();
|
||||
private final HashMap<View, Runnable> mPendingAnimations = new HashMap<>();
|
||||
|
||||
private final int mMaxCountX;
|
||||
private final int mMaxCountY;
|
||||
@@ -61,6 +73,13 @@ public class FolderPagedView extends PagedView implements Folder.FolderContent {
|
||||
private FocusIndicatorView mFocusIndicatorView;
|
||||
private PagedFolderKeyEventListener mKeyListener;
|
||||
|
||||
private View mSortButton;
|
||||
private Switch mSortSwitch;
|
||||
private View mPageIndicator;
|
||||
|
||||
private boolean mSortOperationPending;
|
||||
boolean mIsSorted;
|
||||
|
||||
public FolderPagedView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
LauncherAppState app = LauncherAppState.getInstance();
|
||||
@@ -80,6 +99,134 @@ public class FolderPagedView extends PagedView implements Folder.FolderContent {
|
||||
mFolder = folder;
|
||||
mFocusIndicatorView = (FocusIndicatorView) folder.findViewById(R.id.focus_indicator);
|
||||
mKeyListener = new PagedFolderKeyEventListener(folder);
|
||||
|
||||
mSortButton = folder.findViewById(R.id.folder_sort);
|
||||
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);
|
||||
}
|
||||
|
||||
private void onSortClicked() {
|
||||
if (mSortOperationPending) {
|
||||
return;
|
||||
}
|
||||
if (mIsSorted) {
|
||||
setIsSorted(false, true);
|
||||
} else {
|
||||
mSortOperationPending = true;
|
||||
doSort();
|
||||
}
|
||||
}
|
||||
|
||||
private void setIsSorted(boolean isSorted, boolean saveChanges) {
|
||||
mIsSorted = isSorted;
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -125,6 +272,7 @@ public class FolderPagedView extends PagedView implements Folder.FolderContent {
|
||||
|
||||
@Override
|
||||
public ArrayList<ShortcutInfo> bindItems(ArrayList<ShortcutInfo> items) {
|
||||
mIsSorted = mFolder.mInfo.hasOption(FolderInfo.FLAG_ITEMS_SORTED);
|
||||
ArrayList<View> icons = new ArrayList<View>();
|
||||
for (ShortcutInfo item : items) {
|
||||
icons.add(createNewView(item));
|
||||
@@ -138,20 +286,33 @@ public class FolderPagedView extends PagedView implements Folder.FolderContent {
|
||||
* Also sets the current page to the last page.
|
||||
*/
|
||||
@Override
|
||||
public int allocateNewLastItemRank() {
|
||||
public int allocateRankForNewItem(ShortcutInfo info) {
|
||||
int rank = getItemCount();
|
||||
int total = rank + 1;
|
||||
// Rearrange the items as the grid size might change.
|
||||
mFolder.rearrangeChildren(total);
|
||||
ArrayList<View> views = new ArrayList<View>(mFolder.getItemsInReadingOrder());
|
||||
if (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;
|
||||
}
|
||||
|
||||
setCurrentPage(getChildCount() - 1);
|
||||
}
|
||||
|
||||
views.add(rank, null);
|
||||
arrangeChildren(views, views.size(), false);
|
||||
setCurrentPage(rank / mMaxItemsPerPage);
|
||||
return rank;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View createAndAddViewForRank(ShortcutInfo item, int rank) {
|
||||
View icon = createNewView(item);
|
||||
addViewForRank(createNewView(item), item, rank);
|
||||
addViewForRank(icon, item, rank);
|
||||
return icon;
|
||||
}
|
||||
|
||||
@@ -259,6 +420,10 @@ public class FolderPagedView extends PagedView implements Folder.FolderContent {
|
||||
int position = 0;
|
||||
int newX, newY, rank;
|
||||
|
||||
boolean isSorted = mIsSorted;
|
||||
|
||||
ViewComparator comparator = new ViewComparator();
|
||||
View lastView = null;
|
||||
rank = 0;
|
||||
for (int i = 0; i < itemCount; i++) {
|
||||
View v = list.size() > i ? list.get(i) : null;
|
||||
@@ -273,6 +438,10 @@ public class FolderPagedView extends PagedView implements Folder.FolderContent {
|
||||
}
|
||||
|
||||
if (v != null) {
|
||||
if (lastView != null) {
|
||||
isSorted &= comparator.compare(lastView, v) <= 0;
|
||||
}
|
||||
|
||||
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) v.getLayoutParams();
|
||||
newX = position % mGridCountX;
|
||||
newY = position / mGridCountX;
|
||||
@@ -292,6 +461,7 @@ public class FolderPagedView extends PagedView implements Folder.FolderContent {
|
||||
v, -1, mFolder.mLauncher.getViewIdForItem(info), lp, true);
|
||||
}
|
||||
|
||||
lastView = v;
|
||||
rank ++;
|
||||
position++;
|
||||
}
|
||||
@@ -305,6 +475,19 @@ public class FolderPagedView extends PagedView implements Folder.FolderContent {
|
||||
if (removed) {
|
||||
setCurrentPage(0);
|
||||
}
|
||||
|
||||
setIsSorted(isSorted, saveChanges);
|
||||
|
||||
// Update footer
|
||||
if (getPageCount() > 1) {
|
||||
mPageIndicator.setVisibility(View.VISIBLE);
|
||||
mSortButton.setVisibility(View.VISIBLE);
|
||||
mFolder.mFolderName.setGravity(Gravity.START);
|
||||
} else {
|
||||
mPageIndicator.setVisibility(View.GONE);
|
||||
mSortButton.setVisibility(View.GONE);
|
||||
mFolder.mFolderName.setGravity(Gravity.CENTER_HORIZONTAL);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -407,6 +590,17 @@ public class FolderPagedView extends PagedView implements Folder.FolderContent {
|
||||
if (mFolder != null) {
|
||||
mFolder.updateTextViewFocus();
|
||||
}
|
||||
if (mSortOperationPending && getNextPage() == 0) {
|
||||
post(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (mSortOperationPending) {
|
||||
doSort();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -433,8 +627,8 @@ public class FolderPagedView extends PagedView implements Folder.FolderContent {
|
||||
* Finish animation all the views which are animating across pages
|
||||
*/
|
||||
public void completePendingPageChanges() {
|
||||
if (!mPageChangingViews.isEmpty()) {
|
||||
HashMap<View, Runnable> pendingViews = new HashMap<>(mPageChangingViews);
|
||||
if (!mPendingAnimations.isEmpty()) {
|
||||
HashMap<View, Runnable> pendingViews = new HashMap<>(mPendingAnimations);
|
||||
for (Map.Entry<View, Runnable> e : pendingViews.entrySet()) {
|
||||
e.getKey().animate().cancel();
|
||||
e.getValue().run();
|
||||
@@ -533,7 +727,7 @@ public class FolderPagedView extends PagedView implements Folder.FolderContent {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
mPageChangingViews.remove(v);
|
||||
mPendingAnimations.remove(v);
|
||||
v.setTranslationX(oldTranslateX);
|
||||
((CellLayout) v.getParent().getParent()).removeView(v);
|
||||
addViewForRank(v, (ShortcutInfo) v.getTag(), newRank);
|
||||
@@ -544,7 +738,7 @@ public class FolderPagedView extends PagedView implements Folder.FolderContent {
|
||||
.setDuration(REORDER_ANIMATION_DURATION)
|
||||
.setStartDelay(0)
|
||||
.withEndAction(endAction);
|
||||
mPageChangingViews.put(v, endAction);
|
||||
mPendingAnimations.put(v, endAction);
|
||||
}
|
||||
}
|
||||
moveStart = rankToMove;
|
||||
@@ -569,4 +763,14 @@ public class FolderPagedView extends PagedView implements Folder.FolderContent {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -961,6 +961,7 @@ public class LauncherModel extends BroadcastReceiver
|
||||
final int screenIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SCREEN);
|
||||
final int cellXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLX);
|
||||
final int cellYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLY);
|
||||
final int optionsIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.OPTIONS);
|
||||
|
||||
FolderInfo folderInfo = null;
|
||||
switch (c.getInt(itemTypeIndex)) {
|
||||
@@ -975,6 +976,7 @@ public class LauncherModel extends BroadcastReceiver
|
||||
folderInfo.screenId = c.getInt(screenIndex);
|
||||
folderInfo.cellX = c.getInt(cellXIndex);
|
||||
folderInfo.cellY = c.getInt(cellYIndex);
|
||||
folderInfo.options = c.getInt(optionsIndex);
|
||||
|
||||
return folderInfo;
|
||||
}
|
||||
@@ -1862,9 +1864,8 @@ public class LauncherModel extends BroadcastReceiver
|
||||
LauncherSettings.Favorites.RESTORED);
|
||||
final int profileIdIndex = c.getColumnIndexOrThrow(
|
||||
LauncherSettings.Favorites.PROFILE_ID);
|
||||
//final int uriIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.URI);
|
||||
//final int displayModeIndex = c.getColumnIndexOrThrow(
|
||||
// LauncherSettings.Favorites.DISPLAY_MODE);
|
||||
final int optionsIndex = c.getColumnIndexOrThrow(
|
||||
LauncherSettings.Favorites.OPTIONS);
|
||||
|
||||
ShortcutInfo info;
|
||||
String intentDescription;
|
||||
@@ -2114,6 +2115,7 @@ public class LauncherModel extends BroadcastReceiver
|
||||
folderInfo.cellY = c.getInt(cellYIndex);
|
||||
folderInfo.spanX = 1;
|
||||
folderInfo.spanY = 1;
|
||||
folderInfo.options = c.getInt(optionsIndex);
|
||||
|
||||
// check & update map of what's occupied
|
||||
if (!checkItemPlacement(occupied, folderInfo)) {
|
||||
|
||||
@@ -57,7 +57,7 @@ public class LauncherProvider extends ContentProvider {
|
||||
private static final String TAG = "Launcher.LauncherProvider";
|
||||
private static final boolean LOGD = false;
|
||||
|
||||
private static final int DATABASE_VERSION = 22;
|
||||
private static final int DATABASE_VERSION = 23;
|
||||
|
||||
static final String OLD_AUTHORITY = "com.android.launcher2.settings";
|
||||
static final String AUTHORITY = ProviderConfig.AUTHORITY;
|
||||
@@ -413,7 +413,8 @@ public class LauncherProvider extends ContentProvider {
|
||||
"modified INTEGER NOT NULL DEFAULT 0," +
|
||||
"restored INTEGER NOT NULL DEFAULT 0," +
|
||||
"profileId INTEGER DEFAULT " + userSerialNumber + "," +
|
||||
"rank INTEGER NOT NULL DEFAULT 0" +
|
||||
"rank INTEGER NOT NULL DEFAULT 0," +
|
||||
"options INTEGER NOT NULL DEFAULT 0" +
|
||||
");");
|
||||
addWorkspacesTable(db);
|
||||
|
||||
@@ -524,18 +525,9 @@ public class LauncherProvider extends ContentProvider {
|
||||
}
|
||||
}
|
||||
case 15: {
|
||||
db.beginTransaction();
|
||||
try {
|
||||
// Insert new column for holding restore status
|
||||
db.execSQL("ALTER TABLE favorites " +
|
||||
"ADD COLUMN restored INTEGER NOT NULL DEFAULT 0;");
|
||||
db.setTransactionSuccessful();
|
||||
} catch (SQLException ex) {
|
||||
Log.e(TAG, ex.getMessage(), ex);
|
||||
if (!addIntegerColumn(db, Favorites.RESTORED, 0)) {
|
||||
// Old version remains, which means we wipe old data
|
||||
break;
|
||||
} finally {
|
||||
db.endTransaction();
|
||||
}
|
||||
}
|
||||
case 16: {
|
||||
@@ -573,6 +565,12 @@ public class LauncherProvider extends ContentProvider {
|
||||
break;
|
||||
}
|
||||
case 22: {
|
||||
if (!addIntegerColumn(db, Favorites.OPTIONS, 0)) {
|
||||
// Old version remains, which means we wipe old data
|
||||
break;
|
||||
}
|
||||
}
|
||||
case 23: {
|
||||
// DB Upgraded successfully
|
||||
return;
|
||||
}
|
||||
@@ -682,20 +680,21 @@ public class LauncherProvider extends ContentProvider {
|
||||
}
|
||||
|
||||
private boolean addProfileColumn(SQLiteDatabase db) {
|
||||
UserManagerCompat userManager = UserManagerCompat.getInstance(mContext);
|
||||
// Default to the serial number of this user, for older
|
||||
// shortcuts.
|
||||
long userSerialNumber = userManager.getSerialNumberForUser(
|
||||
UserHandleCompat.myUserHandle());
|
||||
return addIntegerColumn(db, Favorites.PROFILE_ID, userSerialNumber);
|
||||
}
|
||||
|
||||
private boolean addIntegerColumn(SQLiteDatabase db, String columnName, long defaultValue) {
|
||||
db.beginTransaction();
|
||||
try {
|
||||
UserManagerCompat userManager = UserManagerCompat.getInstance(mContext);
|
||||
// Default to the serial number of this user, for older
|
||||
// shortcuts.
|
||||
long userSerialNumber = userManager.getSerialNumberForUser(
|
||||
UserHandleCompat.myUserHandle());
|
||||
// Insert new column for holding user serial number
|
||||
db.execSQL("ALTER TABLE favorites " +
|
||||
"ADD COLUMN profileId INTEGER DEFAULT "
|
||||
+ userSerialNumber + ";");
|
||||
db.execSQL("ALTER TABLE favorites ADD COLUMN "
|
||||
+ columnName + " INTEGER NOT NULL DEFAULT " + defaultValue + ";");
|
||||
db.setTransactionSuccessful();
|
||||
} catch (SQLException ex) {
|
||||
// Old version remains, which means we wipe old data
|
||||
Log.e(TAG, ex.getMessage(), ex);
|
||||
return false;
|
||||
} finally {
|
||||
|
||||
@@ -309,5 +309,11 @@ class LauncherSettings {
|
||||
* <p>Type: INTEGER</p>
|
||||
*/
|
||||
static final String RANK = "rank";
|
||||
|
||||
/**
|
||||
* Stores general flag based options for {@link ItemInfo}s.
|
||||
* <p>Type: INTEGER</p>
|
||||
*/
|
||||
static final String OPTIONS = "options";
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user