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

Commit 5e7c89c3 authored by Steven Ng's avatar Steven Ng Committed by Android (Google) Code Review
Browse files

Merge "Better estimate the height of widget recycler view" into sc-dev

parents 133a5d5e 53d1364e
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -19,7 +19,7 @@
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="?android:attr/selectableItemBackground"
    android:paddingVertical="20dp"
    android:paddingVertical="@dimen/widget_list_header_view_vertical_padding"
    android:orientation="horizontal">

    <ImageView
+2 −0
Original line number Diff line number Diff line
@@ -108,6 +108,8 @@
    <dimen name="widget_cell_vertical_padding">8dp</dimen>
    <dimen name="widget_cell_horizontal_padding">16dp</dimen>

    <dimen name="widget_list_header_view_vertical_padding">20dp</dimen>

    <dimen name="widget_preview_shadow_blur">0.5dp</dimen>
    <dimen name="widget_preview_key_shadow_distance">1dp</dimen>
    <dimen name="widget_preview_corner_radius">2dp</dimen>
+6 −4
Original line number Diff line number Diff line
@@ -385,14 +385,16 @@ public class WidgetsFullSheet extends BaseWidgetSheet

    @Override
    public int getHeaderViewHeight() {
        // No need to check work profile here because mInitialTabHeight is always 0 if there is no
        // work profile.
        return mInitialTabsHeight
                + measureHeightWithVerticalMargins(mSearchAndRecommendationViewHolder.mContainer);
        return measureHeightWithVerticalMargins(mSearchAndRecommendationViewHolder.mCollapseHandle)
                + measureHeightWithVerticalMargins(mSearchAndRecommendationViewHolder.mHeaderTitle)
                + measureHeightWithVerticalMargins(mSearchAndRecommendationViewHolder.mSearchBar);
    }

    /** private the height, in pixel, + the vertical margins of a given view. */
    private static int measureHeightWithVerticalMargins(View view) {
        if (view.getVisibility() != VISIBLE) {
            return 0;
        }
        MarginLayoutParams marginLayoutParams = (MarginLayoutParams) view.getLayoutParams();
        return view.getMeasuredHeight() + marginLayoutParams.bottomMargin
                + marginLayoutParams.topMargin;
+5 −0
Original line number Diff line number Diff line
@@ -122,6 +122,11 @@ public class WidgetsListAdapter extends Adapter<ViewHolder> implements OnHeaderC
        return mVisibleEntries.size();
    }

    /** Returns all items that will be drawn in a recycler view. */
    public List<WidgetsListBaseEntry> getItems() {
        return mVisibleEntries;
    }

    /** Gets the section name for {@link com.android.launcher3.views.RecyclerViewFastScroller}. */
    public String getSectionName(int pos) {
        return mVisibleEntries.get(pos).mTitleSectionName;
+57 −7
Original line number Diff line number Diff line
@@ -21,13 +21,19 @@ import android.graphics.Point;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.TableLayout;

import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.RecyclerView.OnItemTouchListener;

import com.android.launcher3.BaseRecyclerView;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.R;
import com.android.launcher3.views.ActivityContext;
import com.android.launcher3.widget.model.WidgetsListBaseEntry;
import com.android.launcher3.widget.model.WidgetsListContentEntry;
import com.android.launcher3.widget.model.WidgetsListHeaderEntry;

/**
 * The widgets recycler view.
@@ -39,8 +45,10 @@ public class WidgetsRecyclerView extends BaseRecyclerView implements OnItemTouch
    private final int mScrollbarTop;

    private final Point mFastScrollerOffset = new Point();
    private final int mEstimatedWidgetListHeaderHeight;
    private boolean mTouchDownOnScroller;
    private HeaderViewDimensionsProvider mHeaderViewDimensionsProvider;
    private int mLastVisibleWidgetContentTableHeight = 0;

    public WidgetsRecyclerView(Context context) {
        this(context, null);
@@ -55,6 +63,12 @@ public class WidgetsRecyclerView extends BaseRecyclerView implements OnItemTouch
        super(context, attrs, defStyleAttr);
        mScrollbarTop = getResources().getDimensionPixelSize(R.dimen.dynamic_grid_edge_margin);
        addOnItemTouchListener(this);

        ActivityContext activity = ActivityContext.lookupContext(getContext());
        DeviceProfile grid = activity.getDeviceProfile();
        mEstimatedWidgetListHeaderHeight = grid.iconSizePx
                + 2 * context.getResources().getDimensionPixelSize(
                        R.dimen.widget_list_header_view_vertical_padding);
    }

    @Override
@@ -123,21 +137,32 @@ public class WidgetsRecyclerView extends BaseRecyclerView implements OnItemTouch

        View child = getChildAt(0);
        int rowIndex = getChildPosition(child);
        int y = (child.getMeasuredHeight() * rowIndex);
        for (int i = 0; i < getChildCount(); i++) {
            View view = getChildAt(i);
            if (view instanceof TableLayout) {
                // This assumes there is ever only one content shown in this recycler view.
                mLastVisibleWidgetContentTableHeight = view.getMeasuredHeight();
            }
        }

        int scrollPosition = getItemsHeight(rowIndex);
        int offset = getLayoutManager().getDecoratedTop(child);

        return getPaddingTop() + y - offset;
        return getPaddingTop() + scrollPosition - offset;
    }

    /**
     * Returns the available scroll height:
     *   AvailableScrollHeight = Total height of the all items - last page height
     * Returns the available scroll height, in pixel.
     *
     * <p>If the recycler view can't be scrolled, returns 0.
     */
    @Override
    protected int getAvailableScrollHeight() {
        View child = getChildAt(0);
        return child.getMeasuredHeight() * mAdapter.getItemCount() + getScrollBarTop()
                + getPaddingBottom() - mScrollbar.getHeight();
        // AvailableScrollHeight = Total height of the all items - first page height
        int firstPageHeight = getMeasuredHeight() - getPaddingTop() - getPaddingBottom();
        int totalHeightOfAllItems = getItemsHeight(/* untilIndex= */ mAdapter.getItemCount());
        int availableScrollHeight = totalHeightOfAllItems - firstPageHeight;
        return Math.max(0, availableScrollHeight);
    }

    private boolean isModelNotReady() {
@@ -180,6 +205,31 @@ public class WidgetsRecyclerView extends BaseRecyclerView implements OnItemTouch
        mHeaderViewDimensionsProvider = headerViewDimensionsProvider;
    }

    /**
     * Returns the sum of the height, in pixels, of this list adapter's items from index 0 until
     * {@code untilIndex}.
     *
     * <p>If the untilIndex is larger than the total number of items in this adapter, returns the
     * sum of all items' height.
     */
    private int getItemsHeight(int untilIndex) {
        if (untilIndex > mAdapter.getItems().size()) {
            untilIndex = mAdapter.getItems().size();
        }
        int totalItemsHeight = 0;
        for (int i = 0; i < untilIndex; i++) {
            WidgetsListBaseEntry entry = mAdapter.getItems().get(i);
            if (entry instanceof WidgetsListHeaderEntry) {
                totalItemsHeight += mEstimatedWidgetListHeaderHeight;
            } else if (entry instanceof WidgetsListContentEntry) {
                totalItemsHeight += mLastVisibleWidgetContentTableHeight;
            } else {
                throw new UnsupportedOperationException("Can't estimate height for " + entry);
            }
        }
        return totalItemsHeight;
    }

    /**
     * Provides dimensions of the header view that is shown at the top of a
     * {@link WidgetsRecyclerView}.