summaryrefslogtreecommitdiffstats
path: root/src/com/android/launcher3/allapps
diff options
context:
space:
mode:
authorSunny Goyal <sunnygoyal@google.com>2017-06-23 16:12:50 -0700
committerSunny Goyal <sunnygoyal@google.com>2017-06-26 14:56:36 -0700
commit89d5c5a31bd6cf4caf815b680ec670896b91803d (patch)
treeb9d0a9a9fd6dec880fb6076bc2b8d4f38870839f /src/com/android/launcher3/allapps
parentbbe504d24d5e0757d1a7772af822b7a6e274c9b4 (diff)
downloadandroid_packages_apps_Trebuchet-89d5c5a31bd6cf4caf815b680ec670896b91803d.tar.gz
android_packages_apps_Trebuchet-89d5c5a31bd6cf4caf815b680ec670896b91803d.tar.bz2
android_packages_apps_Trebuchet-89d5c5a31bd6cf4caf815b680ec670896b91803d.zip
Updating fast scrollbar UI in Landscape
Creating a separate view for FastScrollBar and moving all the relavant logic in the view. For protrait, the touch handling is delegated by the recycler view just like before. For landscape, the dcrollbar does not overlay with recyclerView and handles the touch itself Bug: 37015359 Change-Id: Ie1981326457ba739bdf0ac8063db1065f395f133
Diffstat (limited to 'src/com/android/launcher3/allapps')
-rw-r--r--src/com/android/launcher3/allapps/AllAppsContainerView.java12
-rw-r--r--src/com/android/launcher3/allapps/AllAppsGridAdapter.java14
-rw-r--r--src/com/android/launcher3/allapps/AllAppsRecyclerView.java10
-rw-r--r--src/com/android/launcher3/allapps/AlphabeticalAppsList.java18
-rw-r--r--src/com/android/launcher3/allapps/LandscapeFastScroller.java63
-rw-r--r--src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java12
-rw-r--r--src/com/android/launcher3/allapps/search/HeaderElevationController.java32
7 files changed, 109 insertions, 52 deletions
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index 4954e0c44..47b68a2ee 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -171,19 +171,19 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
* Returns whether the view itself will handle the touch event or not.
*/
public boolean shouldContainerScroll(MotionEvent ev) {
- int[] point = new int[2];
- point[0] = (int) ev.getX();
- point[1] = (int) ev.getY();
- Utilities.mapCoordInSelfToDescendant(mAppsRecyclerView, this, point);
-
// IF the MotionEvent is inside the search box, and the container keeps on receiving
// touch input, container should move down.
if (mLauncher.getDragLayer().isEventOverView(mSearchContainer, ev)) {
return true;
}
+ int[] point = new int[2];
+ point[0] = (int) ev.getX();
+ point[1] = (int) ev.getY();
+ Utilities.mapCoordInSelfToDescendant(
+ mAppsRecyclerView.getScrollBar(), mLauncher.getDragLayer(), point);
// IF the MotionEvent is inside the thumb, container should not be pulled down.
- if (mAppsRecyclerView.getScrollBar().isNearThumb(point[0], point[1])) {
+ if (mAppsRecyclerView.getScrollBar().shouldBlockIntercept(point[0], point[1])) {
return false;
}
diff --git a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
index d6514a83f..1054a5633 100644
--- a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
+++ b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
@@ -69,16 +69,13 @@ public class AllAppsGridAdapter extends RecyclerView.Adapter<AllAppsGridAdapter.
// A divider that separates the apps list and the search market button
public static final int VIEW_TYPE_SEARCH_MARKET_DIVIDER = 1 << 5;
- // The divider under the search field
- public static final int VIEW_TYPE_SEARCH_DIVIDER = 1 << 6;
// The divider that separates prediction icons from the app list
- public static final int VIEW_TYPE_PREDICTION_DIVIDER = 1 << 7;
- public static final int VIEW_TYPE_APPS_LOADING_DIVIDER = 1 << 8;
- public static final int VIEW_TYPE_DISCOVERY_ITEM = 1 << 9;
+ public static final int VIEW_TYPE_PREDICTION_DIVIDER = 1 << 6;
+ public static final int VIEW_TYPE_APPS_LOADING_DIVIDER = 1 << 7;
+ public static final int VIEW_TYPE_DISCOVERY_ITEM = 1 << 8;
// Common view type masks
- public static final int VIEW_TYPE_MASK_DIVIDER = VIEW_TYPE_SEARCH_DIVIDER
- | VIEW_TYPE_SEARCH_MARKET_DIVIDER
+ public static final int VIEW_TYPE_MASK_DIVIDER = VIEW_TYPE_SEARCH_MARKET_DIVIDER
| VIEW_TYPE_PREDICTION_DIVIDER;
public static final int VIEW_TYPE_MASK_ICON = VIEW_TYPE_ICON
| VIEW_TYPE_PREDICTION_ICON;
@@ -319,9 +316,6 @@ public class AllAppsGridAdapter extends RecyclerView.Adapter<AllAppsGridAdapter.
}
});
return new ViewHolder(searchMarketView);
- case VIEW_TYPE_SEARCH_DIVIDER:
- return new ViewHolder(mLayoutInflater.inflate(
- R.layout.all_apps_search_divider, parent, false));
case VIEW_TYPE_APPS_LOADING_DIVIDER:
View loadingDividerView = mLayoutInflater.inflate(
R.layout.all_apps_discovery_loading_divider, parent, false);
diff --git a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
index 0607a1e5d..2b2fddcdd 100644
--- a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
@@ -72,7 +72,6 @@ public class AllAppsRecyclerView extends BaseRecyclerView {
super(context, attrs, defStyleAttr);
Resources res = getResources();
addOnItemTouchListener(this);
- mScrollbar.setDetachThumbOnFastScroll();
mEmptySearchBackgroundTopOffset = res.getDimensionPixelSize(
R.dimen.all_apps_empty_search_bg_top_offset);
}
@@ -110,7 +109,6 @@ public class AllAppsRecyclerView extends BaseRecyclerView {
RecyclerView.RecycledViewPool pool = getRecycledViewPool();
int approxRows = (int) Math.ceil(grid.availableHeightPx / grid.allAppsIconSizePx);
pool.setMaxRecycledViews(AllAppsGridAdapter.VIEW_TYPE_EMPTY_SEARCH, 1);
- pool.setMaxRecycledViews(AllAppsGridAdapter.VIEW_TYPE_SEARCH_DIVIDER, 1);
pool.setMaxRecycledViews(AllAppsGridAdapter.VIEW_TYPE_SEARCH_MARKET_DIVIDER, 1);
pool.setMaxRecycledViews(AllAppsGridAdapter.VIEW_TYPE_SEARCH_MARKET, 1);
pool.setMaxRecycledViews(AllAppsGridAdapter.VIEW_TYPE_ICON, approxRows * mNumAppsPerRow);
@@ -137,8 +135,6 @@ public class AllAppsRecyclerView extends BaseRecyclerView {
AllAppsGridAdapter.VIEW_TYPE_PREDICTION_DIVIDER,
AllAppsGridAdapter.VIEW_TYPE_SEARCH_MARKET_DIVIDER);
putSameHeightFor(adapter, widthMeasureSpec, heightMeasureSpec,
- AllAppsGridAdapter.VIEW_TYPE_SEARCH_DIVIDER);
- putSameHeightFor(adapter, widthMeasureSpec, heightMeasureSpec,
AllAppsGridAdapter.VIEW_TYPE_SEARCH_MARKET);
putSameHeightFor(adapter, widthMeasureSpec, heightMeasureSpec,
AllAppsGridAdapter.VIEW_TYPE_EMPTY_SEARCH);
@@ -164,7 +160,9 @@ public class AllAppsRecyclerView extends BaseRecyclerView {
*/
public void scrollToTop() {
// Ensure we reattach the scrollbar if it was previously detached while fast-scrolling
- mScrollbar.reattachThumbToScroll();
+ if (mScrollbar != null) {
+ mScrollbar.reattachThumbToScroll();
+ }
scrollToPosition(0);
}
@@ -356,7 +354,7 @@ public class AllAppsRecyclerView extends BaseRecyclerView {
}
@Override
- protected boolean supportsFastScrolling() {
+ public boolean supportsFastScrolling() {
// Only allow fast scrolling when the user is not searching, since the results are not
// grouped in a meaningful order
return !mApps.hasFilter();
diff --git a/src/com/android/launcher3/allapps/AlphabeticalAppsList.java b/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
index 7bf66510a..608e898ae 100644
--- a/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
+++ b/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
@@ -138,13 +138,6 @@ public class AlphabeticalAppsList {
return item;
}
- public static AdapterItem asSearchDivider(int pos) {
- AdapterItem item = new AdapterItem();
- item.viewType = AllAppsGridAdapter.VIEW_TYPE_SEARCH_DIVIDER;
- item.position = pos;
- return item;
- }
-
public static AdapterItem asMarketDivider(int pos) {
AdapterItem item = new AdapterItem();
item.viewType = AllAppsGridAdapter.VIEW_TYPE_SEARCH_MARKET_DIVIDER;
@@ -195,8 +188,6 @@ public class AlphabeticalAppsList {
private int mNumPredictedAppsPerRow;
private int mNumAppRowsInAdapter;
- private boolean mHasSearchDivider = true;
-
public AlphabeticalAppsList(Context context) {
mLauncher = Launcher.getLauncher(context);
mIndexer = new AlphabeticIndexCompat(context);
@@ -352,10 +343,6 @@ public class AlphabeticalAppsList {
onAppsUpdated();
}
- public void disableSearchDivider() {
- mHasSearchDivider = false;
- }
-
/**
* Updates internals when the set of apps are updated.
*/
@@ -442,11 +429,6 @@ public class AlphabeticalAppsList {
}
}
- if (mHasSearchDivider) {
- // Add the search divider
- mAdapterItems.add(AdapterItem.asSearchDivider(position++));
- }
-
// Process the predicted app components
mPredictedApps.clear();
if (mPredictedAppComponents != null && !mPredictedAppComponents.isEmpty() && !hasFilter()) {
diff --git a/src/com/android/launcher3/allapps/LandscapeFastScroller.java b/src/com/android/launcher3/allapps/LandscapeFastScroller.java
new file mode 100644
index 000000000..cdde65760
--- /dev/null
+++ b/src/com/android/launcher3/allapps/LandscapeFastScroller.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2017 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.allapps;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+
+import com.android.launcher3.views.RecyclerViewFastScroller;
+
+/**
+ * Extension of {@link RecyclerViewFastScroller} to be used in landscape layout.
+ */
+public class LandscapeFastScroller extends RecyclerViewFastScroller {
+
+ public LandscapeFastScroller(Context context) {
+ super(context);
+ }
+
+ public LandscapeFastScroller(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public LandscapeFastScroller(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+
+ @Override
+ public boolean handleTouchEvent(MotionEvent ev) {
+ // We handle our own touch event, no need to handle recycler view touch delegates.
+ return false;
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ event.offsetLocation(0, -mRv.getPaddingTop());
+ if (super.handleTouchEvent(event)) {
+ getParent().requestDisallowInterceptTouchEvent(true);
+ }
+ event.offsetLocation(0, mRv.getPaddingTop());
+ return true;
+ }
+
+ @Override
+ public boolean shouldBlockIntercept(int x, int y) {
+ // If the user touched the scroll bar area, block swipe
+ return x >= 0 && x < getWidth() && y >= 0 && y < getHeight();
+ }
+}
diff --git a/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java b/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java
index 3f06ec9dd..5cb12d592 100644
--- a/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java
+++ b/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java
@@ -54,12 +54,13 @@ public class AppsSearchContainerLayout extends FrameLayout
private final int mSearchBoxHeight;
private final AllAppsSearchBarController mSearchBarController;
private final SpannableStringBuilder mSearchQueryBuilder;
- private final HeaderElevationController mElevationController;
private ExtendedEditText mSearchInput;
private AlphabeticalAppsList mApps;
private AllAppsRecyclerView mAppsRecyclerView;
private AllAppsGridAdapter mAdapter;
+ private View mDivider;
+ private HeaderElevationController mElevationController;
public AppsSearchContainerLayout(Context context) {
this(context, null);
@@ -77,7 +78,6 @@ public class AppsSearchContainerLayout extends FrameLayout
mSearchBoxHeight = getResources()
.getDimensionPixelSize(R.dimen.all_apps_search_bar_field_height);
mSearchBarController = new AllAppsSearchBarController();
- mElevationController = new HeaderElevationController(this);
mSearchQueryBuilder = new SpannableStringBuilder();
Selection.setSelection(mSearchQueryBuilder, 0);
@@ -87,6 +87,8 @@ public class AppsSearchContainerLayout extends FrameLayout
protected void onFinishInflate() {
super.onFinishInflate();
mSearchInput = findViewById(R.id.search_box_input);
+ mDivider = findViewById(R.id.search_divider);
+ mElevationController = new HeaderElevationController(mDivider);
// Update the hint to contain the icon.
// Prefix the original hint with two spaces. The first space gets replaced by the icon
@@ -96,6 +98,12 @@ public class AppsSearchContainerLayout extends FrameLayout
spanned.setSpan(new TintedDrawableSpan(getContext(), R.drawable.ic_allapps_search),
0, 1, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
mSearchInput.setHint(spanned);
+
+ DeviceProfile dp = mLauncher.getDeviceProfile();
+ if (!dp.isVerticalBarLayout()) {
+ LayoutParams lp = (LayoutParams) mDivider.getLayoutParams();
+ lp.leftMargin = lp.rightMargin = dp.edgeMarginPx;
+ }
}
@Override
diff --git a/src/com/android/launcher3/allapps/search/HeaderElevationController.java b/src/com/android/launcher3/allapps/search/HeaderElevationController.java
index ab4e88fc8..7cd32b26e 100644
--- a/src/com/android/launcher3/allapps/search/HeaderElevationController.java
+++ b/src/com/android/launcher3/allapps/search/HeaderElevationController.java
@@ -4,11 +4,11 @@ import android.content.res.Resources;
import android.graphics.Outline;
import android.support.v7.widget.RecyclerView;
import android.view.View;
+import android.view.ViewGroup;
import android.view.ViewOutlineProvider;
import com.android.launcher3.BaseRecyclerView;
import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
/**
* Helper class for controlling the header elevation in response to RecyclerView scroll.
@@ -16,6 +16,7 @@ import com.android.launcher3.Utilities;
public class HeaderElevationController extends RecyclerView.OnScrollListener {
private final View mHeader;
+ private final View mHeaderChild;
private final float mMaxElevation;
private final float mScrollToElevation;
@@ -28,23 +29,27 @@ public class HeaderElevationController extends RecyclerView.OnScrollListener {
mScrollToElevation = res.getDimension(R.dimen.all_apps_header_scroll_to_elevation);
// We need to provide a custom outline so the shadow only appears on the bottom edge.
- // The top, left and right edges are all extended out, and the shadow is clipped
- // by the parent.
+ // The top, left and right edges are all extended out to match parent's edge, so that
+ // the shadow is clipped by the parent.
final ViewOutlineProvider vop = new ViewOutlineProvider() {
@Override
public void getOutline(View view, Outline outline) {
- final View parent = (View) mHeader.getParent();
+ // Set the left and top to be at the parents edge. Since the coordinates are
+ // relative to this view,
+ // (x = -view.getLeft()) for this view => (x = 0) for parent
+ final int left = -view.getLeft();
+ final int top = -view.getTop();
- final int left = parent.getLeft(); // Use the parent to account for offsets
- final int top = view.getTop();
- final int right = left + view.getWidth();
- final int bottom = view.getBottom();
-
- final int offset = Utilities.pxFromDp(mMaxElevation, res.getDisplayMetrics());
+ // Since the view is centered align, the spacing on left and right are same.
+ // Add same spacing on the right to reach parent's edge.
+ final int right = view.getWidth() - left;
+ final int bottom = view.getHeight();
+ final int offset = (int) mMaxElevation;
outline.setRect(left - offset, top - offset, right + offset, bottom);
}
};
mHeader.setOutlineProvider(vop);
+ mHeaderChild = ((ViewGroup) mHeader).getChildAt(0);
}
public void reset() {
@@ -63,6 +68,13 @@ public class HeaderElevationController extends RecyclerView.OnScrollListener {
float newElevation = mMaxElevation * elevationPct;
if (Float.compare(mHeader.getElevation(), newElevation) != 0) {
mHeader.setElevation(newElevation);
+
+ // To simulate a scrolling effect for the header, we translate the header down, and
+ // its content up by the same amount, so that it gets clipped by the parent, making it
+ // look like the content was scrolled out of the view.
+ int shift = Math.min(mHeader.getHeight(), scrollY);
+ mHeader.setTranslationY(-shift);
+ mHeaderChild.setTranslationY(shift);
}
}