OSDN Git Service

Don't close all apps when touching deep shortcuts container.
[android-x86/packages-apps-Launcher3.git] / src / com / android / launcher3 / allapps / AllAppsContainerView.java
index b4ec8c2..13e2357 100644 (file)
@@ -22,22 +22,19 @@ import android.graphics.Point;
 import android.graphics.Rect;
 import android.support.v7.widget.RecyclerView;
 import android.text.Selection;
+import android.text.Spannable;
+import android.text.SpannableString;
 import android.text.SpannableStringBuilder;
 import android.text.method.TextKeyListener;
 import android.util.AttributeSet;
-import android.view.Gravity;
 import android.view.KeyEvent;
-import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewConfiguration;
 import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
 
 import com.android.launcher3.AppInfo;
 import com.android.launcher3.BaseContainerView;
-import com.android.launcher3.BubbleTextView;
 import com.android.launcher3.CellLayout;
 import com.android.launcher3.DeleteDropTarget;
 import com.android.launcher3.DeviceProfile;
@@ -51,8 +48,11 @@ import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.Workspace;
 import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.dragndrop.DragOptions;
 import com.android.launcher3.folder.Folder;
+import com.android.launcher3.graphics.TintedDrawableSpan;
 import com.android.launcher3.keyboard.FocusedItemDecorator;
+import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
 import com.android.launcher3.util.ComponentKey;
 
 import java.nio.charset.Charset;
@@ -71,7 +71,7 @@ final class FullMergeAlgorithm implements AlphabeticalAppsList.MergeAlgorithm {
             AlphabeticalAppsList.SectionInfo withSection,
             int sectionAppCount, int numAppsPerRow, int mergeCount) {
         // Don't merge the predicted apps
-        if (section.firstAppItem.viewType != AllAppsGridAdapter.ICON_VIEW_TYPE) {
+        if (section.firstAppItem.viewType != AllAppsGridAdapter.VIEW_TYPE_ICON) {
             return false;
         }
         // Otherwise, merge every other section
@@ -103,7 +103,7 @@ final class SimpleSectionMergeAlgorithm implements AlphabeticalAppsList.MergeAlg
             AlphabeticalAppsList.SectionInfo withSection,
             int sectionAppCount, int numAppsPerRow, int mergeCount) {
         // Don't merge the predicted apps
-        if (section.firstAppItem.viewType != AllAppsGridAdapter.ICON_VIEW_TYPE) {
+        if (section.firstAppItem.viewType != AllAppsGridAdapter.VIEW_TYPE_ICON) {
             return false;
         }
 
@@ -150,15 +150,15 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
 
     private View mSearchContainer;
     private ExtendedEditText mSearchInput;
-    private ImageView mSearchIcon;
     private HeaderElevationController mElevationController;
+    private int mSearchContainerOffsetTop;
 
     private SpannableStringBuilder mSearchQueryBuilder = null;
 
     private int mSectionNamesMargin;
     private int mNumAppsPerRow;
     private int mNumPredictedAppsPerRow;
-    private int mRecyclerViewTopBottomPadding;
+    private int mRecyclerViewBottomPadding;
     // This coordinate is relative to this container view
     private final Point mBoundsCheckLastTouchDownPos = new Point(-1, -1);
 
@@ -183,11 +183,11 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
         mItemDecoration = mAdapter.getItemDecoration();
         DeviceProfile grid = mLauncher.getDeviceProfile();
         if (FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP && !grid.isVerticalBarLayout()) {
-            mRecyclerViewTopBottomPadding = 0;
+            mRecyclerViewBottomPadding = 0;
             setPadding(0, 0, 0, 0);
         } else {
-            mRecyclerViewTopBottomPadding =
-                    res.getDimensionPixelSize(R.dimen.all_apps_list_top_bottom_padding);
+            mRecyclerViewBottomPadding =
+                    res.getDimensionPixelSize(R.dimen.all_apps_list_bottom_padding);
         }
         mSearchQueryBuilder = new SpannableStringBuilder();
         Selection.setSelection(mSearchQueryBuilder, 0);
@@ -212,6 +212,7 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
      */
     public void addApps(List<AppInfo> apps) {
         mApps.addApps(apps);
+        mSearchBarController.refreshSearchResult();
     }
 
     /**
@@ -219,6 +220,7 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
      */
     public void updateApps(List<AppInfo> apps) {
         mApps.updateApps(apps);
+        mSearchBarController.refreshSearchResult();
     }
 
     /**
@@ -226,6 +228,7 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
      */
     public void removeApps(List<AppInfo> apps) {
         mApps.removeApps(apps);
+        mSearchBarController.refreshSearchResult();
     }
 
     public void setSearchBarVisible(boolean visible) {
@@ -258,18 +261,31 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
     /**
      * Returns whether the view itself will handle the touch event or not.
      */
-    public boolean shouldContainerScroll(float x, float y) {
+    public boolean shouldContainerScroll(MotionEvent ev) {
         int[] point = new int[2];
-        point[0] = (int) x;
-        point[1] = (int) y;
+        point[0] = (int) ev.getX();
+        point[1] = (int) ev.getY();
         Utilities.mapCoordInSelfToDescendent(mAppsRecyclerView, this, point);
 
-        // if the MotionEvent is inside the thumb, container should not be pulled down.
+        // 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;
+        }
+
+        // IF the MotionEvent is inside the thumb, container should not be pulled down.
         if (mAppsRecyclerView.getScrollBar().isNearThumb(point[0], point[1])) {
             return false;
         }
-        // If scroller is at the very top, then it's okay for the container to be pulled down.
-        if (Float.compare(0f, mAppsRecyclerView.getScrollBar().getThumbOffset().y) == 0) {
+
+        // IF a shortcuts container is open, container should not be pulled down.
+        if (mLauncher.getOpenShortcutsContainer() != null) {
+            return false;
+        }
+
+        // IF scroller is at the very top OR there is no scroll bar because there is probably not
+        // enough items to scroll, THEN it's okay for the container to be pulled down.
+        if (mAppsRecyclerView.getScrollBar().getThumbOffset().y <= 0) {
             return true;
         }
         return false;
@@ -289,6 +305,7 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
      */
     public void reset() {
         // Reset the search bar and base recycler view after transitioning home
+        scrollToTop();
         mSearchBarController.reset();
         mAppsRecyclerView.reset();
     }
@@ -310,37 +327,18 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
 
         mSearchContainer = findViewById(R.id.search_container);
         mSearchInput = (ExtendedEditText) findViewById(R.id.search_box_input);
-        mSearchIcon = (ImageView) findViewById(R.id.search_icon);
 
-        final LinearLayout.LayoutParams searchParams =
-                (LinearLayout.LayoutParams) mSearchInput.getLayoutParams();
-        mSearchInput.setOnFocusChangeListener(new OnFocusChangeListener() {
-            @Override
-            public void onFocusChange(View view, boolean focused) {
-                if (focused) {
-                    searchParams.width = LayoutParams.MATCH_PARENT;
-                    mSearchInput.setLayoutParams(searchParams);
-                    mSearchInput.setGravity(Gravity.FILL_HORIZONTAL | Gravity.CENTER_VERTICAL);
-                    mSearchIcon.setVisibility(View.GONE);
-                } else {
-                    searchParams.width = LayoutParams.WRAP_CONTENT;
-                    mSearchInput.setLayoutParams(searchParams);
-                    mSearchInput.setGravity(Gravity.START | Gravity.CENTER_VERTICAL);
-                    mSearchIcon.setVisibility(View.VISIBLE);
-                }
-            }
-        });
+        // Update the hint to contain the icon.
+        // Prefix the original hint with two spaces. The first space gets replaced by the icon
+        // using span. The second space is used for a singe space character between the hint
+        // and the icon.
+        SpannableString spanned = new SpannableString("  " + mSearchInput.getHint());
+        spanned.setSpan(new TintedDrawableSpan(getContext(), R.drawable.ic_allapps_search),
+                0, 1, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
+        mSearchInput.setHint(spanned);
 
-        final OnClickListener searchFocusListener = new OnClickListener() {
-            @Override
-            public void onClick(View view) {
-                if (!mSearchBarController.isSearchFieldFocused()) {
-                    mSearchBarController.focusSearchField();
-                }
-            }
-        };
-        mSearchInput.setOnClickListener(searchFocusListener);
-        mSearchContainer.setOnClickListener(searchFocusListener);
+        mSearchContainerOffsetTop = getResources().getDimensionPixelSize(
+                R.dimen.all_apps_search_bar_margin_top);
 
         mElevationController = Utilities.ATLEAST_LOLLIPOP
                 ? new HeaderElevationController.ControllerVL(mSearchContainer)
@@ -361,31 +359,13 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
 
         FocusedItemDecorator focusedItemDecorator = new FocusedItemDecorator(mAppsRecyclerView);
         mAppsRecyclerView.addItemDecoration(focusedItemDecorator);
+        mAppsRecyclerView.preMeasureViews(mAdapter);
         mAdapter.setIconFocusListener(focusedItemDecorator.getFocusListener());
 
-        // Precalculate the prediction icon and normal icon sizes
-        LayoutInflater layoutInflater = LayoutInflater.from(getContext());
-        final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(
-                getResources().getDisplayMetrics().widthPixels, MeasureSpec.AT_MOST);
-        final int heightMeasureSpec = MeasureSpec.makeMeasureSpec(
-                getResources().getDisplayMetrics().heightPixels, MeasureSpec.AT_MOST);
-
-        BubbleTextView icon = (BubbleTextView) layoutInflater.inflate(
-                R.layout.all_apps_icon, this, false);
-        icon.applyDummyInfo();
-        icon.measure(widthMeasureSpec, heightMeasureSpec);
-        BubbleTextView predIcon = (BubbleTextView) layoutInflater.inflate(
-                R.layout.all_apps_prediction_bar_icon, this, false);
-        predIcon.applyDummyInfo();
-        predIcon.measure(widthMeasureSpec, heightMeasureSpec);
-        mAppsRecyclerView.setPremeasuredIconHeights(predIcon.getMeasuredHeight(),
-                icon.getMeasuredHeight());
-
-        // TODO(hyunyoungs): clean up setting the content and the reveal view.
         if (FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP) {
-            getContentView().setBackground(null);
             getRevealView().setVisibility(View.VISIBLE);
-            getRevealView().setAlpha(AllAppsTransitionController.ALL_APPS_FINAL_ALPHA);
+            getContentView().setVisibility(View.VISIBLE);
+            getContentView().setBackground(null);
         }
     }
 
@@ -394,16 +374,13 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
 
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        updatePaddingsAndMargins();
-        mContentBounds.set(mHorizontalPadding, 0,
-                MeasureSpec.getSize(widthMeasureSpec) - mHorizontalPadding,
-                MeasureSpec.getSize(heightMeasureSpec));
+        int widthPx = MeasureSpec.getSize(widthMeasureSpec);
+        int heightPx = MeasureSpec.getSize(heightMeasureSpec);
+        updatePaddingsAndMargins(widthPx, heightPx);
+        mContentBounds.set(mContainerPaddingLeft, 0, widthPx - mContainerPaddingRight, heightPx);
 
         DeviceProfile grid = mLauncher.getDeviceProfile();
-        int availableWidth = (!mContentBounds.isEmpty() ? mContentBounds.width() :
-                MeasureSpec.getSize(widthMeasureSpec))
-                - 2 * mAppsRecyclerView.getMaxScrollbarWidth();
-        grid.updateAppsViewNumCols(getResources(), availableWidth);
+        grid.updateAppsViewNumCols();
         if (FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP) {
             if (mNumAppsPerRow != grid.inv.numColumns ||
                     mNumPredictedAppsPerRow != grid.inv.numColumns) {
@@ -414,13 +391,15 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
                 mAdapter.setNumAppsPerRow(mNumAppsPerRow);
                 mApps.setNumAppsPerRow(mNumAppsPerRow, mNumPredictedAppsPerRow, new FullMergeAlgorithm());
                 if (mNumAppsPerRow > 0) {
-                    int iconSize = availableWidth / mNumAppsPerRow;
-                    int iconSpacing = (iconSize - grid.allAppsIconSizePx) / 2;
+                    int rvPadding = mAppsRecyclerView.getPaddingStart(); // Assumes symmetry
                     final int thumbMaxWidth =
                             getResources().getDimensionPixelSize(
                                     R.dimen.container_fastscroll_thumb_max_width);
-                    mSearchContainer.setPaddingRelative(
-                            iconSpacing + thumbMaxWidth, 0, iconSpacing + thumbMaxWidth, 0);
+                    mSearchContainer.setPadding(
+                            rvPadding - mContainerPaddingLeft + thumbMaxWidth,
+                            mSearchContainer.getPaddingTop(),
+                            rvPadding - mContainerPaddingRight + thumbMaxWidth,
+                            mSearchContainer.getPaddingBottom());
                 }
             }
             super.onMeasure(widthMeasureSpec, heightMeasureSpec);
@@ -432,7 +411,7 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
         // Update the number of items in the grid before we measure the view
         // TODO: mSectionNamesMargin is currently 0, but also account for it,
         // if it's enabled in the future.
-        grid.updateAppsViewNumCols(getResources(), availableWidth);
+        grid.updateAppsViewNumCols();
         if (mNumAppsPerRow != grid.allAppsNumCols ||
                 mNumPredictedAppsPerRow != grid.allAppsNumPredictiveCols) {
             mNumAppsPerRow = grid.allAppsNumCols;
@@ -449,14 +428,6 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
             mAppsRecyclerView.setNumAppsPerRow(grid, mNumAppsPerRow);
             mAdapter.setNumAppsPerRow(mNumAppsPerRow);
             mApps.setNumAppsPerRow(mNumAppsPerRow, mNumPredictedAppsPerRow, mergeAlgorithm);
-
-            // TODO: should we not do all this complicated computation but just match the
-            // numAppsPerRow with the workspace?
-            if (mNumAppsPerRow > 0) {
-                int iconSize = availableWidth / mNumAppsPerRow;
-                int iconSpacing = (iconSize - grid.allAppsIconSizePx) / 2;
-                mSearchInput.setPaddingRelative(iconSpacing, 0, iconSpacing, 0);
-            }
         }
 
         // --- remove END when {@code FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP} is enabled. ---
@@ -468,7 +439,7 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
      * container view, we inset the background and padding of the recycler view to allow for the
      * recycler view to handle touch events (for fast scrolling) all the way to the edge.
      */
-    private void updatePaddingsAndMargins() {
+    private void updatePaddingsAndMargins(int widthPx, int heightPx) {
         Rect bgPadding = new Rect();
         getRevealView().getBackground().getPadding(bgPadding);
 
@@ -480,13 +451,12 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
         // names)
         int maxScrollBarWidth = mAppsRecyclerView.getMaxScrollbarWidth();
         int startInset = Math.max(mSectionNamesMargin, maxScrollBarWidth);
-        int topBottomPadding = mRecyclerViewTopBottomPadding;
         if (Utilities.isRtl(getResources())) {
-            mAppsRecyclerView.setPadding(bgPadding.left + maxScrollBarWidth,
-                    topBottomPadding, bgPadding.right + startInset, topBottomPadding);
+            mAppsRecyclerView.setPadding(bgPadding.left + maxScrollBarWidth, 0, bgPadding.right
+                    + startInset, mRecyclerViewBottomPadding);
         } else {
-            mAppsRecyclerView.setPadding(bgPadding.left + startInset, topBottomPadding,
-                    bgPadding.right + maxScrollBarWidth, topBottomPadding);
+            mAppsRecyclerView.setPadding(bgPadding.left + startInset, 0, bgPadding.right +
+                    maxScrollBarWidth, mRecyclerViewBottomPadding);
         }
 
         MarginLayoutParams lp = (MarginLayoutParams) mSearchContainer.getLayoutParams();
@@ -496,11 +466,7 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
         // Clip the view to the left and right edge of the background to
         // to prevent shadows from rendering beyond the edges
         final Rect newClipBounds = new Rect(
-                bgPadding.left,
-                0,
-                getWidth() - bgPadding.right,
-                getHeight()
-        );
+                bgPadding.left, 0, widthPx - bgPadding.right, heightPx);
         setClipBounds(newClipBounds);
 
         // Allow the overscroll effect to reach the edges of the view
@@ -512,18 +478,17 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
                 MarginLayoutParams mlp = (MarginLayoutParams) mAppsRecyclerView.getLayoutParams();
 
                 Rect insets = mLauncher.getDragLayer().getInsets();
-                getContentView().setPadding(0, 0, 0, insets.bottom);
+                getContentView().setPadding(0, 0, 0, 0);
                 int height = insets.top + grid.hotseatCellHeightPx;
 
                 mlp.topMargin = height;
                 mAppsRecyclerView.setLayoutParams(mlp);
 
-                LinearLayout.LayoutParams llp =
-                        (LinearLayout.LayoutParams) mSearchInput.getLayoutParams();
-                llp.topMargin = insets.top;
-                mSearchInput.setLayoutParams(llp);
-                mSearchIcon.setLayoutParams(llp);
-
+                mSearchContainer.setPadding(
+                        mSearchContainer.getPaddingLeft(),
+                        insets.top + mSearchContainerOffsetTop,
+                        mSearchContainer.getPaddingRight(),
+                        mSearchContainer.getPaddingBottom());
                 lp.height = height;
 
                 View navBarBg = findViewById(R.id.nav_bar_bg);
@@ -580,7 +545,7 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
         if (!mLauncher.isDraggingEnabled()) return false;
 
         // Start the drag
-        mLauncher.getWorkspace().beginDragShared(v, this, false);
+        mLauncher.getWorkspace().beginDragShared(v, this, new DragOptions());
         // Enter spring loaded mode
         mLauncher.enterSpringLoadedDragMode();
 
@@ -743,4 +708,9 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
         mSearchQueryBuilder.clearSpans();
         Selection.setSelection(mSearchQueryBuilder, 0);
     }
+
+    @Override
+    public void fillInLaunchSourceData(View v, ItemInfo info, Target target, Target targetParent) {
+        targetParent.containerType = mAppsRecyclerView.getContainerType(v);
+    }
 }