diff options
author | Sunny Goyal <sunnygoyal@google.com> | 2016-10-12 20:49:31 -0700 |
---|---|---|
committer | Sunny Goyal <sunnygoyal@google.com> | 2016-10-19 07:42:34 +0100 |
commit | d164b7f4abcba6cc965c2264257569f88ad5e4a5 (patch) | |
tree | d3e76ff708d2f647dcf101706ab03f5759d9ea75 /src/com/android/launcher3/widget | |
parent | 67115b1a84006374ebb1b0daf20eab95db267838 (diff) | |
download | android_packages_apps_Trebuchet-d164b7f4abcba6cc965c2264257569f88ad5e4a5.tar.gz android_packages_apps_Trebuchet-d164b7f4abcba6cc965c2264257569f88ad5e4a5.tar.bz2 android_packages_apps_Trebuchet-d164b7f4abcba6cc965c2264257569f88ad5e4a5.zip |
Fixing static instance of Indexer being created in the model
Indexer depends on the locale and should be created when ever the config
changes. Moving the widget indexing to the adapter (similar to allApps)
which gets created whenever the activity is recreated.
This fixes the bug where widgets indexing breaks if locale changes while launcher
process is alive
Also fixing the bug in widget model cloning where the HashMap was not cloning
the underlying ArrayList
Change-Id: I7dbe6290e73299c4c07aa7fa564077a2649e1a4c
Diffstat (limited to 'src/com/android/launcher3/widget')
5 files changed, 159 insertions, 24 deletions
diff --git a/src/com/android/launcher3/widget/WidgetItemComparator.java b/src/com/android/launcher3/widget/WidgetItemComparator.java new file mode 100644 index 000000000..b5aaeb9fe --- /dev/null +++ b/src/com/android/launcher3/widget/WidgetItemComparator.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2016 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.widget; + +import com.android.launcher3.compat.UserHandleCompat; +import com.android.launcher3.model.WidgetItem; + +import java.text.Collator; +import java.util.Comparator; + +/** + * Comparator for sorting WidgetItem based on their user, title and size. + */ +public class WidgetItemComparator implements Comparator<WidgetItem> { + + private final UserHandleCompat mMyUserHandle = UserHandleCompat.myUserHandle(); + private final Collator mCollator = Collator.getInstance(); + + @Override + public int compare(WidgetItem a, WidgetItem b) { + // Independent of how the labels compare, if only one of the two widget info belongs to + // work profile, put that one in the back. + boolean thisWorkProfile = !mMyUserHandle.equals(a.user); + boolean otherWorkProfile = !mMyUserHandle.equals(b.user); + if (thisWorkProfile ^ otherWorkProfile) { + return thisWorkProfile ? 1 : -1; + } + + int labelCompare = mCollator.compare(a.label, b.label); + if (labelCompare != 0) { + return labelCompare; + } + + // If the label is same, put the smaller widget before the larger widget. If the area is + // also same, put the widget with smaller height before. + int thisArea = a.spanX * a.spanY; + int otherArea = b.spanX * b.spanY; + return thisArea == otherArea + ? Integer.compare(a.spanY, b.spanY) + : Integer.compare(thisArea, otherArea); + } +} diff --git a/src/com/android/launcher3/widget/WidgetListRowEntry.java b/src/com/android/launcher3/widget/WidgetListRowEntry.java new file mode 100644 index 000000000..3e89eeb9b --- /dev/null +++ b/src/com/android/launcher3/widget/WidgetListRowEntry.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2016 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.widget; + +import com.android.launcher3.ItemInfo; +import com.android.launcher3.model.PackageItemInfo; +import com.android.launcher3.model.WidgetItem; + +import java.util.ArrayList; + +/** + * Holder class to store all the information related to a single row in the widget list + */ +public class WidgetListRowEntry { + + public final PackageItemInfo pkgItem; + + public final ArrayList<WidgetItem> widgets; + + /** + * Character that is used as a section name for the {@link ItemInfo#title}. + * (e.g., "G" will be stored if title is "Google") + */ + public String titleSectionName; + + public WidgetListRowEntry(PackageItemInfo pkgItem, ArrayList<WidgetItem> items) { + this.pkgItem = pkgItem; + this.widgets = items; + } + +} diff --git a/src/com/android/launcher3/widget/WidgetsContainerView.java b/src/com/android/launcher3/widget/WidgetsContainerView.java index 56702cc25..2e1294251 100644 --- a/src/com/android/launcher3/widget/WidgetsContainerView.java +++ b/src/com/android/launcher3/widget/WidgetsContainerView.java @@ -43,9 +43,12 @@ import com.android.launcher3.Utilities; import com.android.launcher3.WidgetPreviewLoader; import com.android.launcher3.dragndrop.DragController; import com.android.launcher3.graphics.LauncherIcons; +import com.android.launcher3.model.PackageItemInfo; +import com.android.launcher3.model.WidgetItem; import com.android.launcher3.model.WidgetsModel; import com.android.launcher3.userevent.nano.LauncherLogProto; import com.android.launcher3.userevent.nano.LauncherLogProto.Target; +import com.android.launcher3.util.MultiHashMap; import com.android.launcher3.util.Thunk; /** @@ -297,9 +300,8 @@ public class WidgetsContainerView extends BaseContainerView /** * Initialize the widget data model. */ - public void addWidgets(WidgetsModel model) { - mRecyclerView.setWidgets(model); - mAdapter.setWidgetsModel(model); + public void setWidgets(MultiHashMap<PackageItemInfo, WidgetItem> model) { + mAdapter.setWidgets(model); mAdapter.notifyDataSetChanged(); View loader = getContentView().findViewById(R.id.loader); diff --git a/src/com/android/launcher3/widget/WidgetsListAdapter.java b/src/com/android/launcher3/widget/WidgetsListAdapter.java index ed0870811..a5846ec33 100644 --- a/src/com/android/launcher3/widget/WidgetsListAdapter.java +++ b/src/com/android/launcher3/widget/WidgetsListAdapter.java @@ -31,10 +31,17 @@ import com.android.launcher3.LauncherAppState; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.WidgetPreviewLoader; +import com.android.launcher3.compat.AlphabeticIndexCompat; +import com.android.launcher3.model.PackageItemInfo; import com.android.launcher3.model.WidgetItem; -import com.android.launcher3.model.WidgetsModel; +import com.android.launcher3.util.LabelComparator; +import com.android.launcher3.util.MultiHashMap; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; import java.util.List; +import java.util.Map; /** * List view adapter for the widget tray. @@ -55,7 +62,8 @@ public class WidgetsListAdapter extends Adapter<WidgetsRowViewHolder> { private final View.OnClickListener mIconClickListener; private final View.OnLongClickListener mIconLongClickListener; - private WidgetsModel mWidgetsModel; + private final ArrayList<WidgetListRowEntry> mEntries = new ArrayList<>(); + private final AlphabeticIndexCompat mIndexer; private final int mIndent; @@ -65,26 +73,40 @@ public class WidgetsListAdapter extends Adapter<WidgetsRowViewHolder> { mLayoutInflater = LayoutInflater.from(context); mWidgetPreviewLoader = LauncherAppState.getInstance().getWidgetCache(); + mIndexer = new AlphabeticIndexCompat(context); + mIconClickListener = iconClickListener; mIconLongClickListener = iconLongClickListener; mIndent = context.getResources().getDimensionPixelSize(R.dimen.widget_section_indent); } - public void setWidgetsModel(WidgetsModel w) { - mWidgetsModel = w; + public void setWidgets(MultiHashMap<PackageItemInfo, WidgetItem> widgets) { + mEntries.clear(); + WidgetItemComparator widgetComparator = new WidgetItemComparator(); + + for (Map.Entry<PackageItemInfo, ArrayList<WidgetItem>> entry : widgets.entrySet()) { + WidgetListRowEntry row = new WidgetListRowEntry(entry.getKey(), entry.getValue()); + row.titleSectionName = mIndexer.computeSectionName(row.pkgItem.title); + Collections.sort(row.widgets, widgetComparator); + mEntries.add(row); + } + + Collections.sort(mEntries, new WidgetListRowEntryComparator()); } @Override public int getItemCount() { - if (mWidgetsModel == null) { - return 0; - } - return mWidgetsModel.getPackageSize(); + return mEntries.size(); + } + + public String getSectionName(int pos) { + return mEntries.get(pos).titleSectionName; } @Override public void onBindViewHolder(WidgetsRowViewHolder holder, int pos) { - List<WidgetItem> infoList = mWidgetsModel.getSortedWidgets(pos); + WidgetListRowEntry entry = mEntries.get(pos); + List<WidgetItem> infoList = entry.widgets; ViewGroup row = holder.cellContainer; if (DEBUG) { @@ -119,7 +141,7 @@ public class WidgetsListAdapter extends Adapter<WidgetsRowViewHolder> { } // Bind the views in the application info section. - holder.title.applyFromPackageItemInfo(mWidgetsModel.getPackageItemInfo(pos)); + holder.title.applyFromPackageItemInfo(entry.pkgItem); // Bind the view in the widget horizontal tray region. for (int i=0; i < infoList.size(); i++) { @@ -173,4 +195,18 @@ public class WidgetsListAdapter extends Adapter<WidgetsRowViewHolder> { public long getItemId(int pos) { return pos; } + + /** + * Comparator for sorting WidgetListRowEntry based on package title + */ + public static class WidgetListRowEntryComparator implements Comparator<WidgetListRowEntry> { + + private final LabelComparator mComparator = new LabelComparator(); + + @Override + public int compare(WidgetListRowEntry a, WidgetListRowEntry b) { + return mComparator.compare(a.pkgItem.title.toString(), b.pkgItem.title.toString()); + } + } + } diff --git a/src/com/android/launcher3/widget/WidgetsRecyclerView.java b/src/com/android/launcher3/widget/WidgetsRecyclerView.java index 4b23ae088..e0a80c679 100644 --- a/src/com/android/launcher3/widget/WidgetsRecyclerView.java +++ b/src/com/android/launcher3/widget/WidgetsRecyclerView.java @@ -31,7 +31,7 @@ import com.android.launcher3.model.WidgetsModel; public class WidgetsRecyclerView extends BaseRecyclerView { private static final String TAG = "WidgetsRecyclerView"; - private WidgetsModel mWidgets; + private WidgetsListAdapter mAdapter; public WidgetsRecyclerView(Context context) { this(context, null); @@ -64,11 +64,10 @@ public class WidgetsRecyclerView extends BaseRecyclerView { return Color.WHITE; } - /** - * Sets the widget model in this view, used to determine the fast scroll position. - */ - public void setWidgets(WidgetsModel widgets) { - mWidgets = widgets; + @Override + public void setAdapter(Adapter adapter) { + super.setAdapter(adapter); + mAdapter = (WidgetsListAdapter) adapter; } /** @@ -84,15 +83,14 @@ public class WidgetsRecyclerView extends BaseRecyclerView { // Stop the scroller if it is scrolling stopScroll(); - int rowCount = mWidgets.getPackageSize(); + int rowCount = mAdapter.getItemCount(); float pos = rowCount * touchFraction; int availableScrollHeight = getAvailableScrollHeight(); LinearLayoutManager layoutManager = ((LinearLayoutManager) getLayoutManager()); layoutManager.scrollToPositionWithOffset(0, (int) -(availableScrollHeight * touchFraction)); int posInt = (int) ((touchFraction == 1)? pos -1 : pos); - PackageItemInfo p = mWidgets.getPackageItemInfo(posInt); - return p.titleSectionName; + return mAdapter.getSectionName(posInt); } /** @@ -137,13 +135,13 @@ public class WidgetsRecyclerView extends BaseRecyclerView { @Override protected int getAvailableScrollHeight() { View child = getChildAt(0); - int height = child.getMeasuredHeight() * mWidgets.getPackageSize(); + int height = child.getMeasuredHeight() * mAdapter.getItemCount(); int totalHeight = getPaddingTop() + height + getPaddingBottom(); int availableScrollHeight = totalHeight - getScrollbarTrackHeight(); return availableScrollHeight; } private boolean isModelNotReady() { - return mWidgets == null || mWidgets.getPackageSize() == 0; + return mAdapter.getItemCount() == 0; } }
\ No newline at end of file |