summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWinson Chung <winsonc@google.com>2015-05-12 18:40:31 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2015-05-12 18:40:32 +0000
commitf6d7f4f21c4d3efa08084d3caaa1a19660ca5777 (patch)
tree77d49691c9788d63704d01f41d7d05da9fb69c45
parent44d0aacd5f44623ba87f1c8b3693d74df69d50e5 (diff)
parent13eb527b5ae7f564e3ace6137a8d466636d87188 (diff)
downloadandroid_packages_apps_Trebuchet-f6d7f4f21c4d3efa08084d3caaa1a19660ca5777.tar.gz
android_packages_apps_Trebuchet-f6d7f4f21c4d3efa08084d3caaa1a19660ca5777.tar.bz2
android_packages_apps_Trebuchet-f6d7f4f21c4d3efa08084d3caaa1a19660ca5777.zip
Merge "Exploring dense all apps layout." into ub-launcher3-burnaby
-rw-r--r--res/layout/apps_empty_view.xml2
-rw-r--r--res/values-sw600dp/dimens.xml6
-rw-r--r--res/values-sw720dp/dimens.xml2
-rw-r--r--src/com/android/launcher3/AlphabeticalAppsList.java101
-rw-r--r--src/com/android/launcher3/AppsContainerView.java16
-rw-r--r--src/com/android/launcher3/AppsGridAdapter.java8
-rw-r--r--src/com/android/launcher3/BaseContainerView.java5
-rw-r--r--src/com/android/launcher3/Launcher.java9
-rw-r--r--src/com/android/launcher3/widget/WidgetsContainerView.java2
9 files changed, 115 insertions, 36 deletions
diff --git a/res/layout/apps_empty_view.xml b/res/layout/apps_empty_view.xml
index 8408077a2..e4c4e2e8c 100644
--- a/res/layout/apps_empty_view.xml
+++ b/res/layout/apps_empty_view.xml
@@ -18,7 +18,7 @@
android:id="@+id/empty_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_gravity="center"
+ android:gravity="center"
android:paddingTop="24dp"
android:paddingBottom="24dp"
android:paddingRight="@dimen/apps_grid_view_start_margin"
diff --git a/res/values-sw600dp/dimens.xml b/res/values-sw600dp/dimens.xml
index b18464292..2bdd4f0fe 100644
--- a/res/values-sw600dp/dimens.xml
+++ b/res/values-sw600dp/dimens.xml
@@ -18,10 +18,10 @@
<dimen name="app_icon_size">64dp</dimen>
<!-- Apps view -->
- <dimen name="apps_container_inset">24dp</dimen>
- <dimen name="apps_grid_view_start_margin">64dp</dimen>
+ <dimen name="apps_container_inset">18dp</dimen>
+ <dimen name="apps_grid_view_start_margin">0dp</dimen>
<dimen name="apps_view_section_text_size">26sp</dimen>
- <dimen name="apps_view_row_height">76dp</dimen>
+ <dimen name="apps_view_row_height">72dp</dimen>
<dimen name="apps_icon_top_bottom_padding">12dp</dimen>
<!-- AppsCustomize -->
diff --git a/res/values-sw720dp/dimens.xml b/res/values-sw720dp/dimens.xml
index cec6b7db0..39b0c8006 100644
--- a/res/values-sw720dp/dimens.xml
+++ b/res/values-sw720dp/dimens.xml
@@ -16,7 +16,7 @@
<resources>
<dimen name="app_icon_size">72dp</dimen>
- <dimen name="apps_search_bar_height">56dp</dimen>
+ <dimen name="apps_search_bar_height">54dp</dimen>
<dimen name="apps_icon_top_bottom_padding">16dp</dimen>
<!-- QSB -->
diff --git a/src/com/android/launcher3/AlphabeticalAppsList.java b/src/com/android/launcher3/AlphabeticalAppsList.java
index 62cb237e1..de4edcb7b 100644
--- a/src/com/android/launcher3/AlphabeticalAppsList.java
+++ b/src/com/android/launcher3/AlphabeticalAppsList.java
@@ -3,6 +3,7 @@ package com.android.launcher3;
import android.content.ComponentName;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
+import android.util.Log;
import com.android.launcher3.compat.AlphabeticIndexCompat;
import com.android.launcher3.compat.UserHandleCompat;
import com.android.launcher3.compat.UserManagerCompat;
@@ -77,6 +78,9 @@ class AppNameComparator {
*/
public class AlphabeticalAppsList {
+ public static final String TAG = "AlphabeticalAppsList";
+ private static final boolean DEBUG = false;
+
/**
* Info about a section in the alphabetic list
*/
@@ -162,11 +166,58 @@ public class AlphabeticalAppsList {
* A filter interface to limit the set of applications in the apps list.
*/
public interface Filter {
- public boolean retainApp(AppInfo info, String sectionName);
+ boolean retainApp(AppInfo info, String sectionName);
+ }
+
+ /**
+ * Common interface for different merging strategies.
+ */
+ private interface MergeAlgorithm {
+ boolean continueMerging(int sectionAppCount, int numAppsPerRow, int mergeCount);
}
- // The maximum number of rows allowed in a merged section before we stop merging
- private static final int MAX_ROWS_IN_MERGED_SECTION = 3;
+ /**
+ * The logic we use to merge sections on tablets.
+ */
+ private static class TabletMergeAlgorithm implements MergeAlgorithm {
+
+ @Override
+ public boolean continueMerging(int sectionAppCount, int numAppsPerRow, int mergeCount) {
+ // Merge EVERYTHING
+ return true;
+ }
+ }
+
+ /**
+ * The logic we use to merge sections on phones.
+ */
+ private static class PhoneMergeAlgorithm implements MergeAlgorithm {
+
+ private int mMinAppsPerRow;
+ private int mMinRowsInMergedSection;
+ private int mMaxAllowableMerges;
+
+ public PhoneMergeAlgorithm(int minAppsPerRow, int minRowsInMergedSection, int maxNumMerges) {
+ mMinAppsPerRow = minAppsPerRow;
+ mMinRowsInMergedSection = minRowsInMergedSection;
+ mMaxAllowableMerges = maxNumMerges;
+ }
+
+ @Override
+ public boolean continueMerging(int sectionAppCount, int numAppsPerRow, int mergeCount) {
+ // Continue merging if the number of hanging apps on the final row is less than some
+ // fixed number (ragged), the merged rows has yet to exceed some minimum row count,
+ // and while the number of merged sections is less than some fixed number of merges
+ int rows = sectionAppCount / numAppsPerRow;
+ int cols = sectionAppCount % numAppsPerRow;
+ return (0 < cols && cols < mMinAppsPerRow) &&
+ rows < mMinRowsInMergedSection &&
+ mergeCount < mMaxAllowableMerges;
+ }
+ }
+
+ private static final int MIN_ROWS_IN_MERGED_SECTION_PHONE = 3;
+ private static final int MAX_NUM_MERGES_PHONE = 2;
private List<AppInfo> mApps = new ArrayList<>();
private List<AppInfo> mFilteredApps = new ArrayList<>();
@@ -174,13 +225,13 @@ public class AlphabeticalAppsList {
private List<SectionInfo> mSections = new ArrayList<>();
private List<FastScrollSectionInfo> mFastScrollerSections = new ArrayList<>();
private List<ComponentName> mPredictedApps = new ArrayList<>();
+ private HashMap<CharSequence, String> mCachedSectionNames = new HashMap<>();
private RecyclerView.Adapter mAdapter;
private Filter mFilter;
private AlphabeticIndexCompat mIndexer;
private AppNameComparator mAppNameComparator;
+ private MergeAlgorithm mMergeAlgorithm;
private int mNumAppsPerRow;
- // The maximum number of section merges we allow at a given time before we stop merging
- private int mMaxAllowableMerges = Integer.MAX_VALUE;
public AlphabeticalAppsList(Context context, int numAppsPerRow) {
mIndexer = new AlphabeticIndexCompat(context);
@@ -193,7 +244,16 @@ public class AlphabeticalAppsList {
*/
public void setNumAppsPerRow(int numAppsPerRow) {
mNumAppsPerRow = numAppsPerRow;
- mMaxAllowableMerges = (int) Math.ceil(numAppsPerRow / 2f);
+
+ // Update the merge algorithm
+ DeviceProfile grid = LauncherAppState.getInstance().getDynamicGrid().getDeviceProfile();
+ if (grid.isPhone()) {
+ mMergeAlgorithm = new PhoneMergeAlgorithm((int) Math.ceil(numAppsPerRow / 2f),
+ MIN_ROWS_IN_MERGED_SECTION_PHONE, MAX_NUM_MERGES_PHONE);
+ } else {
+ mMergeAlgorithm = new TabletMergeAlgorithm();
+ }
+
onAppsUpdated();
}
@@ -392,7 +452,15 @@ public class AlphabeticalAppsList {
for (int i = 0; i < numApps; i++) {
boolean isPredictedApp = i < numPredictedApps;
AppInfo info = allApps.get(i);
- String sectionName = isPredictedApp ? "" : mIndexer.computeSectionName(info.title);
+ String sectionName = "";
+ if (!isPredictedApp) {
+ // Only cache section names from non-predicted apps
+ sectionName = mCachedSectionNames.get(info.title);
+ if (sectionName == null) {
+ sectionName = mIndexer.computeSectionName(info.title);
+ mCachedSectionNames.put(info.title, sectionName);
+ }
+ }
// Check if we want to retain this app
if (mFilter != null && !mFilter.retainApp(info, sectionName)) {
@@ -429,20 +497,14 @@ public class AlphabeticalAppsList {
// Go through each section and try and merge some of the sections
if (AppsContainerView.GRID_MERGE_SECTIONS && !hasFilter()) {
- int minNumAppsPerRow = (int) Math.ceil(mNumAppsPerRow / 2f);
int sectionAppCount = 0;
for (int i = 0; i < mSections.size(); i++) {
SectionInfo section = mSections.get(i);
sectionAppCount = section.numApps;
int mergeCount = 1;
- // Merge rows if the last app in this section is in a column that is greater than
- // 0, but less than the min number of apps per row. In addition, apply the
- // constraint to stop merging if the number of rows in the section is greater than
- // some limit, and also if there are no lessons to merge.
- while (0 < (sectionAppCount % mNumAppsPerRow) &&
- (sectionAppCount % mNumAppsPerRow) < minNumAppsPerRow &&
- (sectionAppCount / mNumAppsPerRow) < MAX_ROWS_IN_MERGED_SECTION &&
+ // Merge rows based on the current strategy
+ while (mMergeAlgorithm.continueMerging(sectionAppCount, mNumAppsPerRow, mergeCount) &&
(i + 1) < mSections.size()) {
SectionInfo nextSection = mSections.remove(i + 1);
@@ -465,10 +527,13 @@ public class AlphabeticalAppsList {
}
section.numApps += nextSection.numApps;
sectionAppCount += nextSection.numApps;
- mergeCount++;
- if (mergeCount >= mMaxAllowableMerges) {
- break;
+
+ if (DEBUG) {
+ Log.d(TAG, "Merging: " + nextSection.firstAppItem.sectionName +
+ " to " + section.firstAppItem.sectionName +
+ " mergedNumRows: " + (sectionAppCount / mNumAppsPerRow));
}
+ mergeCount++;
}
}
}
diff --git a/src/com/android/launcher3/AppsContainerView.java b/src/com/android/launcher3/AppsContainerView.java
index b8d30d081..8a5c6605e 100644
--- a/src/com/android/launcher3/AppsContainerView.java
+++ b/src/com/android/launcher3/AppsContainerView.java
@@ -213,7 +213,13 @@ public class AppsContainerView extends BaseContainerView implements DragSource,
new AppsContainerSearchEditTextView.OnBackKeyListener() {
@Override
public void onBackKey() {
- hideSearchField(true, true);
+ // Only hide the search field if there is no query, or if there
+ // are no filtered results
+ String query = Utilities.trim(
+ mSearchBarEditView.getEditableText().toString());
+ if (query.isEmpty() || mApps.hasNoFilteredResults()) {
+ hideSearchField(true, true);
+ }
}
});
}
@@ -277,15 +283,17 @@ public class AppsContainerView extends BaseContainerView implements DragSource,
} else {
// If there are fixed bounds, then we update the padding to reflect the fixed bounds.
setPadding(mFixedBounds.left, mFixedBounds.top, getMeasuredWidth() - mFixedBounds.right,
- mInsets.bottom);
+ mFixedBounds.bottom);
}
// Update the apps recycler view, inset it by the container inset as well
+ DeviceProfile grid = LauncherAppState.getInstance().getDynamicGrid().getDeviceProfile();
+ int startMargin = grid.isPhone() ? mContentMarginStart : 0;
int inset = mFixedBounds.isEmpty() ? mContainerInset : mFixedBoundsContainerInset;
if (isRtl) {
- mAppsRecyclerView.setPadding(inset, inset, inset + mContentMarginStart, inset);
+ mAppsRecyclerView.setPadding(inset, inset, inset + startMargin, inset);
} else {
- mAppsRecyclerView.setPadding(inset + mContentMarginStart, inset, inset, inset);
+ mAppsRecyclerView.setPadding(inset + startMargin, inset, inset, inset);
}
// Update the header bar
diff --git a/src/com/android/launcher3/AppsGridAdapter.java b/src/com/android/launcher3/AppsGridAdapter.java
index 9ecb2eeb6..563044916 100644
--- a/src/com/android/launcher3/AppsGridAdapter.java
+++ b/src/com/android/launcher3/AppsGridAdapter.java
@@ -90,6 +90,7 @@ class AppsGridAdapter extends RecyclerView.Adapter<AppsGridAdapter.ViewHolder> {
return;
}
+ DeviceProfile grid = LauncherAppState.getInstance().getDynamicGrid().getDeviceProfile();
List<AlphabeticalAppsList.AdapterItem> items = mApps.getAdapterItems();
boolean hasDrawnPredictedAppDivider = false;
int childCount = parent.getChildCount();
@@ -104,8 +105,6 @@ class AppsGridAdapter extends RecyclerView.Adapter<AppsGridAdapter.ViewHolder> {
if (shouldDrawItemDivider(holder, items) && !hasDrawnPredictedAppDivider) {
// Draw the divider under the predicted app
- DeviceProfile grid = LauncherAppState.getInstance().getDynamicGrid().
- getDeviceProfile();
int top = child.getTop() + child.getHeight();
int left = parent.getPaddingLeft();
int right = parent.getWidth() - parent.getPaddingRight();
@@ -113,7 +112,7 @@ class AppsGridAdapter extends RecyclerView.Adapter<AppsGridAdapter.ViewHolder> {
c.drawLine(left + iconInset, top, right - iconInset, top, mPredictedAppsDividerPaint);
hasDrawnPredictedAppDivider = true;
- } else if (shouldDrawItemSection(holder, i, items)) {
+ } else if (grid.isPhone() && shouldDrawItemSection(holder, i, items)) {
// At this point, we only draw sections for each section break;
int viewTopOffset = (2 * child.getPaddingTop());
int pos = holder.getPosition();
@@ -132,7 +131,8 @@ class AppsGridAdapter extends RecyclerView.Adapter<AppsGridAdapter.ViewHolder> {
continue;
}
- // Find the section code points
+
+ // Find the section name bounds
PointF sectionBounds = getAndCacheSectionBounds(sectionName);
// Calculate where to draw the section
diff --git a/src/com/android/launcher3/BaseContainerView.java b/src/com/android/launcher3/BaseContainerView.java
index 2a8443221..bd1c625e3 100644
--- a/src/com/android/launcher3/BaseContainerView.java
+++ b/src/com/android/launcher3/BaseContainerView.java
@@ -59,11 +59,12 @@ public class BaseContainerView extends FrameLayout implements Insettable {
mFixedBounds.set(fixedBounds);
if (Launcher.DISABLE_ALL_APPS_SEARCH_INTEGRATION) {
mFixedBounds.top = mInsets.top;
- mFixedBounds.bottom = getMeasuredHeight();
+ mFixedBounds.bottom = mInsets.bottom;
}
// To ensure that the child RecyclerView has the full width to handle touches right to
// the edge of the screen, we only apply the top and bottom padding to the bounds
- mFixedBounds.inset(0, mFixedBoundsContainerInset);
+ mFixedBounds.top += mFixedBoundsContainerInset;
+ mFixedBounds.bottom += mFixedBoundsContainerInset;
onFixedBoundsUpdated();
}
// Post the updates since they can trigger a relayout, and this call can be triggered from
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 16e4ce644..a289fce87 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -350,6 +350,9 @@ public class Launcher extends Activity
private DeviceProfile mDeviceProfile;
+ // This is set to the view that launched the activity that navigated the user away from
+ // launcher. Since there is no callback for when the activity has finished launching, enable
+ // the press state and keep this reference to reset the press state when we return to launcher.
private BubbleTextView mWaitingForResume;
protected static HashMap<String, CustomAppWidget> sCustomAppWidgets =
@@ -1021,10 +1024,12 @@ public class Launcher extends Activity
if (mOnResumeState == State.WORKSPACE) {
showWorkspace(false);
} else if (mOnResumeState == State.APPS) {
+ boolean launchedFromApp = (mWaitingForResume != null);
// Don't update the predicted apps if the user is returning to launcher in the apps
- // view as they may be depending on the UI to be static to switch to another app
+ // view after launching an app, as they may be depending on the UI to be static to
+ // switch to another app, otherwise, if it was
showAppsView(false /* animated */, false /* resetListToTop */,
- false /* updatePredictedApps */);
+ !launchedFromApp /* updatePredictedApps */);
} else if (mOnResumeState == State.WIDGETS) {
showWidgetsView(false, false);
}
diff --git a/src/com/android/launcher3/widget/WidgetsContainerView.java b/src/com/android/launcher3/widget/WidgetsContainerView.java
index 439227f52..f8d7d9256 100644
--- a/src/com/android/launcher3/widget/WidgetsContainerView.java
+++ b/src/com/android/launcher3/widget/WidgetsContainerView.java
@@ -373,7 +373,7 @@ public class WidgetsContainerView extends BaseContainerView
} else {
// If there are fixed bounds, then we update the padding to reflect the fixed bounds.
setPadding(mFixedBounds.left, mFixedBounds.top, getMeasuredWidth() - mFixedBounds.right,
- mInsets.bottom);
+ mFixedBounds.bottom);
}
}