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

Commit 095e7562 authored by Steven Ng's avatar Steven Ng
Browse files

Fix UI overlapping and void space in the full widgets picker

The issue is caused by not updating the header container after widgets
recycler view items changed due to item click.

Test: Expand / collapse items in the full widgets picker. No UI
      overlapping or void space is observed.
Bug: 186121915
Change-Id: I6a12bbdcca921d66c6d62601bb59cea66a33640b
parent e675a8e6
Loading
Loading
Loading
Loading
+23 −6
Original line number Diff line number Diff line
@@ -48,6 +48,8 @@ final class SearchAndRecommendationsScrollController implements

    private WidgetsRecyclerView mCurrentRecyclerView;

    private OnContentChangeListener mOnContentChangeListener = () -> applyVerticalTransition();

    /**
     * The vertical distance, in pixels, until the search is pinned at the top of the screen when
     * the user scrolls down the recycler view.
@@ -82,19 +84,21 @@ final class SearchAndRecommendationsScrollController implements
        mViewHolder.mContainer.setSearchAndRecommendationScrollController(this);
        mSearchAndRecommendationViewParent = (View) mViewHolder.mContainer.getParent();
        mPrimaryRecyclerView = primaryRecyclerView;
        mCurrentRecyclerView = mPrimaryRecyclerView;
        mWorkRecyclerView = workRecyclerView;
        mSearchRecyclerView = searchRecyclerView;
        mPrimaryWorkTabsView = personalWorkTabsView;
        mPrimaryWorkViewPager = primaryWorkViewPager;
        mCurrentRecyclerView = mPrimaryRecyclerView;
        mTabsHeight = tabsHeight;
        setCurrentRecyclerView(mPrimaryRecyclerView);
    }

    /** Sets the current active {@link WidgetsRecyclerView}. */
    public void setCurrentRecyclerView(WidgetsRecyclerView currentRecyclerView) {
        if (mCurrentRecyclerView != null) {
            mCurrentRecyclerView.setOnContentChangeListener(null);
        }
        mCurrentRecyclerView = currentRecyclerView;
        mCurrentRecyclerView = currentRecyclerView;
        mCurrentRecyclerView.setOnContentChangeListener(mOnContentChangeListener);
        mViewHolder.mHeaderTitle.setTranslationY(0);
        mViewHolder.mRecommendedWidgetsTable.setTranslationY(0);
        mViewHolder.mSearchBar.setTranslationY(0);
@@ -216,12 +220,16 @@ final class SearchAndRecommendationsScrollController implements
        return hasMarginOrPaddingUpdated;
    }

    @Override
    public void onScrollChanged() {
        applyVerticalTransition();
    }

    /**
     * Changes the displacement of collapsible views (e.g. title & widget recommendations) and fixed
     * views (e.g. recycler views, tabs) upon scrolling.
     * views (e.g. recycler views, tabs) upon scrolling / content changes in the recycler view.
     */
    @Override
    public void onScrollChanged() {
    private void applyVerticalTransition() {
        // Always use the recycler view offset because fast scroller offset has a different scale.
        int recyclerViewYOffset = mCurrentRecyclerView.getCurrentScrollY();
        if (recyclerViewYOffset < 0) return;
@@ -299,4 +307,13 @@ final class SearchAndRecommendationsScrollController implements
        return view.getMeasuredHeight() + marginLayoutParams.bottomMargin
                + marginLayoutParams.topMargin;
    }

    /**
     * A listener to be notified when there is a content change in the recycler view that may affect
     * the relative position of the search and recommendation container.
     */
    public interface OnContentChangeListener {
        /** Notifies a content change in the recycler view. */
        void onContentChanged();
    }
}
+39 −15
Original line number Diff line number Diff line
@@ -23,6 +23,8 @@ import android.view.MotionEvent;
import android.view.View;
import android.widget.TableLayout;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.RecyclerView.OnItemTouchListener;
@@ -35,6 +37,7 @@ import com.android.launcher3.widget.model.WidgetsListBaseEntry;
import com.android.launcher3.widget.model.WidgetsListContentEntry;
import com.android.launcher3.widget.model.WidgetsListHeaderEntry;
import com.android.launcher3.widget.model.WidgetsListSearchHeaderEntry;
import com.android.launcher3.widget.picker.SearchAndRecommendationsScrollController.OnContentChangeListener;

/**
 * The widgets recycler view.
@@ -50,6 +53,7 @@ public class WidgetsRecyclerView extends BaseRecyclerView implements OnItemTouch
    private boolean mTouchDownOnScroller;
    private HeaderViewDimensionsProvider mHeaderViewDimensionsProvider;
    private int mLastVisibleWidgetContentTableHeight = 0;
    @Nullable private OnContentChangeListener mOnContentChangeListener;

    public WidgetsRecyclerView(Context context) {
        this(context, null);
@@ -86,6 +90,22 @@ public class WidgetsRecyclerView extends BaseRecyclerView implements OnItemTouch
        mAdapter = (WidgetsListAdapter) adapter;
    }

    @Override
    public void onChildAttachedToWindow(@NonNull View child) {
        super.onChildAttachedToWindow(child);
        if (mOnContentChangeListener != null) {
            mOnContentChangeListener.onContentChanged();
        }
    }

    @Override
    public void onChildDetachedFromWindow(@NonNull View child) {
        super.onChildDetachedFromWindow(child);
        if (mOnContentChangeListener != null) {
            mOnContentChangeListener.onContentChanged();
        }
    }

    /**
     * Maps the touch (from 0..1) to the adapter position that should be visible.
     */
@@ -207,6 +227,25 @@ public class WidgetsRecyclerView extends BaseRecyclerView implements OnItemTouch
        mHeaderViewDimensionsProvider = headerViewDimensionsProvider;
    }

    @Override
    public void scrollToTop() {
        if (mScrollbar != null) {
            mScrollbar.reattachThumbToScroll();
        }

        if (getLayoutManager() instanceof LinearLayoutManager) {
            if (getCurrentScrollY() == 0) {
                // We are at the top, so don't scrollToPosition (would cause unnecessary relayout).
                return;
            }
        }
        scrollToPosition(0);
    }

    public void setOnContentChangeListener(@Nullable OnContentChangeListener listener) {
        mOnContentChangeListener = listener;
    }

    /**
     * Returns the sum of the height, in pixels, of this list adapter's items from index 0 until
     * {@code untilIndex}.
@@ -244,19 +283,4 @@ public class WidgetsRecyclerView extends BaseRecyclerView implements OnItemTouch
         */
        int getHeaderViewHeight();
    }

    @Override
    public void scrollToTop() {
        if (mScrollbar != null) {
            mScrollbar.reattachThumbToScroll();
        }

        if (getLayoutManager() instanceof LinearLayoutManager) {
            if (getCurrentScrollY() == 0) {
                // We are at the top, so don't scrollToPosition (would cause unnecessary relayout).
                return;
            }
        }
        scrollToPosition(0);
    }
}