Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit acebd1f6 authored by Samuel Fufa's avatar Samuel Fufa
Browse files

[Search][Motion] Introduce header protection in AllApps

ScrimView exposes ScrimDrawingController that allow FloatingHeaderView to observe AllApps scroll progress and draw header protection on Scrim. In addition, search box independently adopts header protection background to ensure proper clipping behavior.

Test: local
preview: https://drive.google.com/file/d/1_E577AAJ0LBg0zrKJQSEJK9GQnrtx7uv/view?usp=sharing&resourcekey=0-MTxjlB3xWyJ3qPvr4qMdig
Bug: 184946772
Change-Id: I64c0f4f50d26c475d31542148a15c7c145588d3f
parent f94540b2
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -92,7 +92,8 @@
    <dimen name="all_apps_background_canvas_width">700dp</dimen>
    <dimen name="all_apps_background_canvas_height">475dp</dimen>
    <dimen name="all_apps_header_pill_height">50dp</dimen>
    <dimen name="all_apps_header_pill_corner_radius">50dp</dimen>
    <dimen name="all_apps_header_pill_corner_radius">48dp</dimen>
    <dimen name="all_apps_header_tab_height">48dp</dimen>
    <dimen name="all_apps_tabs_indicator_height">2dp</dimen>
    <dimen name="all_apps_header_top_padding">36dp</dimen>
    <dimen name="all_apps_work_profile_tab_footer_top_padding">16dp</dimen>
+1 −1
Original line number Diff line number Diff line
@@ -1192,7 +1192,7 @@ public class Launcher extends StatefulActivity<LauncherState> implements Launche

        // Setup the drag controller (drop targets have to be added in reverse order in priority)
        mDropTargetBar.setup(mDragController);
        mAllAppsController.setupViews(mAppsView);
        mAllAppsController.setupViews(mScrimView, mAppsView);
    }

    /**
+68 −3
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
@@ -44,6 +45,7 @@ import android.view.WindowInsets;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.core.graphics.ColorUtils;
import androidx.core.os.BuildCompat;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager;
@@ -66,6 +68,7 @@ import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.util.ItemInfoMatcher;
import com.android.launcher3.util.Themes;
import com.android.launcher3.views.RecyclerViewFastScroller;
import com.android.launcher3.views.ScrimView;
import com.android.launcher3.views.SpringRelativeLayout;
import com.android.launcher3.workprofile.PersonalWorkSlidingTabStrip.OnActivePageChangedListener;

@@ -73,13 +76,16 @@ import com.android.launcher3.workprofile.PersonalWorkSlidingTabStrip.OnActivePag
 * The all apps view container.
 */
public class AllAppsContainerView extends SpringRelativeLayout implements DragSource,
        Insettable, OnDeviceProfileChangeListener, OnActivePageChangedListener {
        Insettable, OnDeviceProfileChangeListener, OnActivePageChangedListener,
        ScrimView.ScrimDrawingController {

    private static final float FLING_VELOCITY_MULTIPLIER = 1000f;

    // Starts the springs after at least 25% of the animation has passed.
    private static final float FLING_ANIMATION_THRESHOLD = 0.25f;

    private final Paint mHeaderPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

    protected final BaseDraggingActivity mLauncher;
    protected final AdapterHolder[] mAH;
    private final ItemInfoMatcher mPersonalMatcher = ItemInfoMatcher.ofUser(Process.myUserHandle());
@@ -93,7 +99,7 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo
    private View mSearchContainer;
    private AllAppsPagedView mViewPager;

    private FloatingHeaderView mHeader;
    protected FloatingHeaderView mHeader;
    private WorkModeSwitch mWorkModeSwitch;


@@ -107,7 +113,14 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo

    private Rect mInsets = new Rect();

    SearchAdapterProvider mSearchAdapterProvider;
    private SearchAdapterProvider mSearchAdapterProvider;
    private final int mHeaderTopPadding;
    private final int mScrimColor;
    private final int mHeaderProtectionColor;
    private final float mHeaderThreshold;
    private ScrimView mScrimView;
    private int mHeaderColor;


    public AllAppsContainerView(Context context) {
        this(context, null);
@@ -121,8 +134,19 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo
        super(context, attrs, defStyleAttr);

        mLauncher = BaseDraggingActivity.fromContext(context);

        mScrimColor = Themes.getAttrColor(context, R.attr.allAppsScrimColor);
        mHeaderThreshold = getResources().getDimensionPixelSize(
                R.dimen.dynamic_grid_cell_border_spacing);
        mHeaderTopPadding = context.getResources()
                .getDimensionPixelSize(R.dimen.all_apps_header_top_padding);
        int accentColor = Themes.getColorAccent(getContext());
        mHeaderProtectionColor = ColorUtils.blendARGB(mScrimColor, accentColor, .3f);

        mLauncher.addOnDeviceProfileChangeListener(this);



        mSearchAdapterProvider = mLauncher.createSearchAdapterProvider(this);
        mSearchQueryBuilder = new SpannableStringBuilder();
        Selection.setSelection(mSearchQueryBuilder, 0);
@@ -300,6 +324,7 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo
        }
        // Reset the search bar and base recycler view after transitioning home
        mSearchUiManager.resetSearch();
        updateHeaderScroll(0);
    }

    @Override
@@ -625,6 +650,26 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo
        outRect.offset(0, (int) getTranslationY());
    }

    @Override
    public void setTranslationY(float translationY) {
        super.setTranslationY(translationY);
        invalidateHeader();
    }

    public void setScrimView(ScrimView scrimView) {
        mScrimView = scrimView;
    }

    @Override
    public void drawOnScrim(Canvas canvas) {
        mHeaderPaint.setColor(mHeaderColor);
        mHeaderPaint.setAlpha((int) (getAlpha() * Color.alpha(mHeaderColor)));
        if (mHeaderPaint.getColor() != mScrimColor && mHeaderPaint.getColor() != 0) {
            canvas.drawRect(0, 0, getWidth(), mHeaderTopPadding + getTranslationY(),
                    mHeaderPaint);
        }
    }

    public class AdapterHolder {
        public static final int MAIN = 0;
        public static final int WORK = 1;
@@ -725,4 +770,24 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo
            return mOverlay;
        }
    }


    protected void updateHeaderScroll(int scrolledOffset) {
        float prog = Math.max(0, Math.min(1, (float) scrolledOffset / mHeaderThreshold));
        int headerColor = ColorUtils.setAlphaComponent(mHeaderProtectionColor, (int) (prog * 255));
        if (headerColor != mHeaderColor) {
            mHeaderColor = headerColor;
            getSearchView().setBackgroundColor(mHeaderColor);
            invalidateHeader();
        }
    }

    /**
     * redraws header protection
     */
    public void invalidateHeader() {
        if (mScrimView != null) {
            mScrimView.invalidate();
        }
    }
}
+10 −1
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@ import androidx.recyclerview.widget.RecyclerView;
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.BaseRecyclerView;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.R;
import com.android.launcher3.logging.StatsLogManager;
@@ -52,6 +53,7 @@ import java.util.List;
public class AllAppsRecyclerView extends BaseRecyclerView {
    private static final String TAG = "AllAppsContainerView";
    private static final boolean DEBUG = false;
    private final Launcher mLauncher;

    private AlphabeticalAppsList mApps;
    private final int mNumAppsPerRow;
@@ -87,6 +89,7 @@ public class AllAppsRecyclerView extends BaseRecyclerView {
                R.dimen.all_apps_empty_search_bg_top_offset);
        mNumAppsPerRow = LauncherAppState.getIDP(context).numColumns;
        mFastScrollHelper = new AllAppsFastScrollHelper(this);
        mLauncher = Launcher.getLauncher(context);
    }

    /**
@@ -199,6 +202,12 @@ public class AllAppsRecyclerView extends BaseRecyclerView {
        }
    }

    @Override
    public void onScrolled(int dx, int dy) {
        super.onScrolled(dx, dy);
        mLauncher.getAppsView().updateHeaderScroll(getCurrentScrollY());
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent e) {
        boolean result = super.onInterceptTouchEvent(e);
+13 −2
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@ import com.android.launcher3.anim.PropertySetter;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.statemanager.StateManager.StateHandler;
import com.android.launcher3.states.StateAnimationConfig;
import com.android.launcher3.views.ScrimView;

/**
 * Handles AllApps view transition.
@@ -88,6 +89,7 @@ public class AllAppsTransitionController
    private float mProgress;        // [0, 1], mShiftRange * mProgress = shiftCurrent

    private float mScrollRangeDelta = 0;
    private ScrimView mScrimView;

    public AllAppsTransitionController(Launcher l) {
        mLauncher = l;
@@ -181,19 +183,28 @@ public class AllAppsTransitionController

        Interpolator allAppsFade = config.getInterpolator(ANIM_ALL_APPS_FADE, LINEAR);
        setter.setViewAlpha(mAppsView, hasAllAppsContent ? 1 : 0, allAppsFade);

        boolean shouldProtectHeader =
                ALL_APPS == state || mLauncher.getStateManager().getState() == ALL_APPS;
        mScrimView.setDrawingController(shouldProtectHeader ? mAppsView : null);
    }

    public AnimatorListenerAdapter getProgressAnimatorListener() {
        return AnimationSuccessListener.forRunnable(this::onProgressAnimationEnd);
    }

    public void setupViews(AllAppsContainerView appsView) {
    /**
     * see Launcher#setupViews
     */
    public void setupViews(ScrimView scrimView, AllAppsContainerView appsView) {
        mScrimView = scrimView;
        mAppsView = appsView;
        if (FeatureFlags.ENABLE_DEVICE_SEARCH.get() && Utilities.ATLEAST_R) {
            mLauncher.getSystemUiController().updateUiState(UI_STATE_ALLAPPS,
                    View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                            | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
        }
        mAppsView.setScrimView(scrimView);
    }

    /**
Loading