diff --git a/res/layout/all_apps.xml b/res/layout/all_apps.xml index c42c15c70a..6e9109523e 100644 --- a/res/layout/all_apps.xml +++ b/res/layout/all_apps.xml @@ -31,7 +31,7 @@ - - + diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java index 6684851972..0c992ba284 100644 --- a/src/com/android/launcher3/allapps/AllAppsContainerView.java +++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java @@ -85,8 +85,7 @@ public class AllAppsContainerView extends RelativeLayout implements DragSource, private SearchUiManager mSearchUiManager; private View mSearchContainer; private InterceptingViewPager mViewPager; - private ViewGroup mHeader; - private FloatingHeaderHandler mFloatingHeaderHandler; + private FloatingHeaderView mHeader; private TabsPagerAdapter mTabsPagerAdapter; private SpannableStringBuilder mSearchQueryBuilder = null; @@ -234,8 +233,8 @@ public class AllAppsContainerView extends RelativeLayout implements DragSource, for (int i = 0; i < mAH.length; i++) { updatePromiseAppProgress(app, mAH[i].recyclerView); } - if (mFloatingHeaderHandler != null) { - updatePromiseAppProgress(app, mFloatingHeaderHandler.getContentView()); + if (isHeaderVisible()) { + updatePromiseAppProgress(app, mHeader.getPredictionRow()); } } @@ -286,8 +285,8 @@ public class AllAppsContainerView extends RelativeLayout implements DragSource, mAH[i].recyclerView.scrollToTop(); } } - if (mFloatingHeaderHandler != null) { - mFloatingHeaderHandler.reset(); + if (isHeaderVisible()) { + mHeader.reset(); } // Reset the search bar and base recycler view after transitioning home mSearchUiManager.reset(); @@ -309,7 +308,6 @@ public class AllAppsContainerView extends RelativeLayout implements DragSource, }); mHeader = findViewById(R.id.all_apps_header); - mFloatingHeaderHandler = new FloatingHeaderHandler(mHeader); rebindAdapters(mUsingTabs); mSearchContainer = findViewById(R.id.search_container_all_apps); @@ -447,7 +445,6 @@ public class AllAppsContainerView extends RelativeLayout implements DragSource, if (FeatureFlags.ALL_APPS_PREDICTION_ROW_VIEW) { setupHeader(); } else { - mFloatingHeaderHandler = null; mHeader.setVisibility(View.GONE); } } @@ -501,7 +498,7 @@ public class AllAppsContainerView extends RelativeLayout implements DragSource, @Override public void onPageSelected(int pos) { tabs.updateTabTextColor(pos); - mFloatingHeaderHandler.setMainActive(pos == 0); + mHeader.setMainActive(pos == 0); applyTouchDelegate(); if (mAH[pos].recyclerView != null) { mAH[pos].recyclerView.bindFastScrollbar(); @@ -524,14 +521,16 @@ public class AllAppsContainerView extends RelativeLayout implements DragSource, } public void setPredictedApps(List> apps) { - if (mFloatingHeaderHandler != null) { - mFloatingHeaderHandler.getContentView().setPredictedApps(apps); + if (isHeaderVisible()) { + mHeader.getPredictionRow().setPredictedApps(apps); } mAH[AdapterHolder.MAIN].appsList.setPredictedApps(apps); boolean hasPredictions = !apps.isEmpty(); if (mHasPredictions != hasPredictions) { mHasPredictions = hasPredictions; - setupHeader(); + if (FeatureFlags.ALL_APPS_PREDICTION_ROW_VIEW) { + setupHeader(); + } } } @@ -547,12 +546,12 @@ public class AllAppsContainerView extends RelativeLayout implements DragSource, return mUsingTabs; } - public FloatingHeaderHandler getFloatingHeaderHandler() { - return mFloatingHeaderHandler; + public FloatingHeaderView getFloatingHeaderView() { + return mHeader; } private void setupHeader() { - if (mFloatingHeaderHandler == null) { + if (mHeader == null) { return; } mHeader.setVisibility(View.VISIBLE); @@ -565,8 +564,8 @@ public class AllAppsContainerView extends RelativeLayout implements DragSource, } AllAppsRecyclerView mainRV = mAH[AdapterHolder.MAIN].recyclerView; AllAppsRecyclerView workRV = mAH[AdapterHolder.WORK].recyclerView; - mFloatingHeaderHandler.setup(mainRV, workRV, contentHeight); - mFloatingHeaderHandler.getContentView().setup(mAH[AdapterHolder.MAIN].adapter, + mHeader.setup(mainRV, workRV, contentHeight); + mHeader.getPredictionRow().setup(mAH[AdapterHolder.MAIN].adapter, mComponentToAppMap, mNumPredictedAppsPerRow); int padding = contentHeight; @@ -584,7 +583,7 @@ public class AllAppsContainerView extends RelativeLayout implements DragSource, mAH[i].adapter.setLastSearchQuery(query); } boolean hasQuery = !TextUtils.isEmpty(query); - if (mFloatingHeaderHandler != null && mUsingTabs && hasQuery) { + if (mUsingTabs && hasQuery) { mSearchModeWhileUsingTabs = true; rebindAdapters(false); // hide tabs } else if (mSearchModeWhileUsingTabs && !hasQuery) { @@ -630,12 +629,16 @@ public class AllAppsContainerView extends RelativeLayout implements DragSource, public List getPredictedApps() { if (mUsingTabs) { - return mFloatingHeaderHandler.getContentView().getPredictedApps(); + return mHeader.getPredictionRow().getPredictedApps(); } else { return mAH[AdapterHolder.MAIN].appsList.getPredictedApps(); } } + private boolean isHeaderVisible() { + return mHeader != null && mHeader.getVisibility() == View.VISIBLE; + } + public class AdapterHolder { public static final int MAIN = 0; public static final int WORK = 1; @@ -685,8 +688,8 @@ public class AllAppsContainerView extends RelativeLayout implements DragSource, ? paddingTopForTabs : padding.top; recyclerView.setPadding(padding.left, paddingTop, padding.right, padding.bottom); } - if (mFloatingHeaderHandler != null) { - mFloatingHeaderHandler.getContentView() + if (isHeaderVisible()) { + mHeader.getPredictionRow() .setPadding(padding.left, 0 , padding.right, 0); } } @@ -698,8 +701,8 @@ public class AllAppsContainerView extends RelativeLayout implements DragSource, } adapter.setNumAppsPerRow(mNumAppsPerRow); appsList.setNumAppsPerRow(mNumAppsPerRow, mNumPredictedAppsPerRow); - if (mFloatingHeaderHandler != null) { - mFloatingHeaderHandler.getContentView() + if (isHeaderVisible()) { + mHeader.getPredictionRow() .setNumAppsPerRow(mNumPredictedAppsPerRow); } } diff --git a/src/com/android/launcher3/allapps/FloatingHeaderHandler.java b/src/com/android/launcher3/allapps/FloatingHeaderView.java similarity index 74% rename from src/com/android/launcher3/allapps/FloatingHeaderHandler.java rename to src/com/android/launcher3/allapps/FloatingHeaderView.java index b4685ea372..39e6818864 100644 --- a/src/com/android/launcher3/allapps/FloatingHeaderHandler.java +++ b/src/com/android/launcher3/allapps/FloatingHeaderView.java @@ -15,30 +15,65 @@ */ package com.android.launcher3.allapps; + import android.animation.ValueAnimator; +import android.content.Context; import android.content.res.Resources; import android.graphics.Rect; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.v7.widget.RecyclerView; +import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; import android.widget.RelativeLayout; import com.android.launcher3.R; -public class FloatingHeaderHandler extends RecyclerView.OnScrollListener - implements ValueAnimator.AnimatorUpdateListener { +public class FloatingHeaderView extends RelativeLayout implements + ValueAnimator.AnimatorUpdateListener { private static final boolean SHOW_PREDICTIONS_ONLY_ON_TOP = true; - private final View mHeaderView; - private final PredictionRowView mPredictionRow; - private final ViewGroup mTabLayout; - private final View mDivider; private final Rect mClip = new Rect(0, 0, Integer.MAX_VALUE, Integer.MAX_VALUE); private final ValueAnimator mAnimator = ValueAnimator.ofInt(0, 0); + private final RecyclerView.OnScrollListener mOnScrollListener = new RecyclerView.OnScrollListener() { + @Override + public void onScrollStateChanged(RecyclerView recyclerView, int newState) { + if (SHOW_PREDICTIONS_ONLY_ON_TOP) { + return; + } + if (!mTopOnlyMode && newState == RecyclerView.SCROLL_STATE_IDLE + && mTranslationY != -mMaxTranslation && mTranslationY != 0) { + float scroll = Math.abs(getCurrentScroll()); + boolean expand = scroll > mMaxTranslation + ? Math.abs(mTranslationY) < mMaxTranslation / 2 : true; + setExpanded(expand); + } + } + @Override + public void onScrolled(RecyclerView rv, int dx, int dy) { + boolean isMainRV = rv == mMainRV; + if (isMainRV != mMainRVActive) { + return; + } + + if (mAnimator.isStarted()) { + mAnimator.cancel(); + } + + int current = - (isMainRV + ? mMainRV.getCurrentScrollY() + : mWorkRV.getCurrentScrollY()); + moved(current); + apply(); + } + }; + + private PredictionRowView mPredictionRow; + private ViewGroup mTabLayout; + private View mDivider; private AllAppsRecyclerView mMainRV; private AllAppsRecyclerView mWorkRV; private boolean mTopOnlyMode; @@ -50,15 +85,24 @@ public class FloatingHeaderHandler extends RecyclerView.OnScrollListener private int mWorkScrolledY; private boolean mMainRVActive; - public FloatingHeaderHandler(@NonNull ViewGroup header) { - mHeaderView = header; - mTabLayout = header.findViewById(R.id.tabs); - mDivider = header.findViewById(R.id.divider); - mPredictionRow = header.findViewById(R.id.header_content); + public FloatingHeaderView(@NonNull Context context) { + this(context, null); + } + + public FloatingHeaderView(@NonNull Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + } + + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + mTabLayout = findViewById(R.id.tabs); + mDivider = findViewById(R.id.divider); + mPredictionRow = findViewById(R.id.header_content); } public void setup(@NonNull AllAppsRecyclerView personalRV, @Nullable AllAppsRecyclerView workRV, - int predictionRowHeight) { + int predictionRowHeight) { mTopOnlyMode = workRV == null; mTabLayout.setVisibility(mTopOnlyMode ? View.GONE : View.VISIBLE); mPredictionRow.getLayoutParams().height = predictionRowHeight; @@ -71,13 +115,13 @@ public class FloatingHeaderHandler extends RecyclerView.OnScrollListener private AllAppsRecyclerView setupRV(AllAppsRecyclerView old, AllAppsRecyclerView updated) { if (old != updated && updated != null ) { - updated.addOnScrollListener(this); + updated.addOnScrollListener(mOnScrollListener); } return updated; } private void setupDivider() { - Resources res = mHeaderView.getResources(); + Resources res = getResources(); int verticalGap = res.getDimensionPixelSize(R.dimen.all_apps_divider_margin_vertical); int sideGap = res.getDimensionPixelSize(R.dimen.dynamic_grid_edge_margin); mDivider.setPadding(sideGap, verticalGap,sideGap, mTopOnlyMode ? verticalGap : 0); @@ -93,11 +137,7 @@ public class FloatingHeaderHandler extends RecyclerView.OnScrollListener setExpanded(true); } - public View getHeaderView() { - return mHeaderView; - } - - public PredictionRowView getContentView() { + public PredictionRowView getPredictionRow() { return mPredictionRow; } @@ -109,24 +149,6 @@ public class FloatingHeaderHandler extends RecyclerView.OnScrollListener return mDivider; } - @Override - public void onScrolled(RecyclerView rv, int dx, int dy) { - boolean isMainRV = rv == mMainRV; - if (isMainRV != mMainRVActive) { - return; - } - - if (mAnimator.isStarted()) { - mAnimator.cancel(); - } - - int current = - (isMainRV - ? mMainRV.getCurrentScrollY() - : mWorkRV.getCurrentScrollY()); - moved(current); - apply(); - } - public void reset() { mMainScrolledY = 0; mWorkScrolledY = 0; @@ -182,20 +204,6 @@ public class FloatingHeaderHandler extends RecyclerView.OnScrollListener } } - @Override - public void onScrollStateChanged(RecyclerView recyclerView, int newState) { - if (SHOW_PREDICTIONS_ONLY_ON_TOP) { - return; - } - if (!mTopOnlyMode && newState == RecyclerView.SCROLL_STATE_IDLE - && mTranslationY != -mMaxTranslation && mTranslationY != 0) { - float scroll = Math.abs(getCurrentScroll()); - boolean expand = scroll > mMaxTranslation - ? Math.abs(mTranslationY) < mMaxTranslation / 2 : true; - setExpanded(expand); - } - } - private void setExpanded(boolean expand) { int translateTo = expand ? 0 : -mMaxTranslation; mAnimator.setIntValues(mTranslationY, translateTo); @@ -221,3 +229,5 @@ public class FloatingHeaderHandler extends RecyclerView.OnScrollListener } } + +