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

Commit 0ab3bc3f authored by Santiago Etchebehere's avatar Santiago Etchebehere
Browse files

Improve loading of Grid preview cards

Change the way we calculate the card size to avoid a second
layout pass on them.
Load the wallpaper asset only once and reuse on all options
background.
Use a faster transition for loading the grid preview itself.

Bug: 123648086
Change-Id: I4b9f249854c128ad2a68566fd11f158a3c5ac548
parent 115b0de0
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
-->
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
@@ -27,7 +28,8 @@
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:background="@color/secondary_color"/>
        android:background="@color/secondary_color"
        app:card_style="screen_aspect_ratio"/>

    <LinearLayout
        android:id="@+id/options_section"
+3 −2
Original line number Diff line number Diff line
@@ -17,7 +17,7 @@
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_height="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:background="@color/category_picker_background_color">
    <include layout="@layout/section_header"/>
@@ -27,7 +27,8 @@
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:background="@color/secondary_color"/>
        android:background="@color/secondary_color"
        app:card_style="screen_aspect_ratio"/>

    <LinearLayout
        android:id="@+id/options_section"

res/values/attrs.xml

0 → 100644
+29 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--

     Copyright (C) 2019 The Android Open Source Project

     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at

          http://www.apache.org/licenses/LICENSE-2.0

     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
-->
<resources xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- PreviewPager specific attributes. -->
    <declare-styleable name="PreviewPager">
        <attr name="card_style" format="integer">
            <!-- The cards are sized so that a small part of the next card in the pager can be seen
                peeking from the side. -->
            <enum name="peeking" value="0" />
            <!-- Cards are sized to match the screen's aspect ratio (based on available height) -->
            <enum name="screen_aspect_ratio" value="1" />
        </attr>
    </declare-styleable>
</resources>
 No newline at end of file
+33 −21
Original line number Diff line number Diff line
@@ -54,6 +54,8 @@ import com.bumptech.glide.request.RequestOptions;
 */
public class GridFragment extends ToolbarFragment {

    private static final int PREVIEW_FADE_DURATION_MS = 100;

    /**
     * Interface to be implemented by an Activity hosting a {@link GridFragment}
     */
@@ -67,11 +69,11 @@ public class GridFragment extends ToolbarFragment {
        return fragment;
    }

    private boolean mIsWallpaperInfoReady;
    private WallpaperInfo mHomeWallpaper;
    private float mScreenAspectRatio;
    private int mPageHeight;
    private int mPageWidth;
    private int mCardHeight;
    private int mCardWidth;
    private BitmapDrawable mCardBackground;
    private GridPreviewAdapter mAdapter;
    private RecyclerView mOptionsContainer;
    private OptionSelectorController mOptionsController;
@@ -94,7 +96,7 @@ public class GridFragment extends ToolbarFragment {
        setUpToolbar(view);
        mPreviewPager = view.findViewById(R.id.grid_preview_pager);
        mOptionsContainer = view.findViewById(R.id.options_container);
        final Resources res = getContext().getResources();
        final Resources res = getResources();
        DisplayMetrics dm = res.getDisplayMetrics();
        mScreenAspectRatio = (float) dm.heightPixels / dm.widthPixels;
        setUpOptions();
@@ -103,29 +105,41 @@ public class GridFragment extends ToolbarFragment {
            getActivity().finish();
        });
        CurrentWallpaperInfoFactory factory = InjectorProvider.getInjector()
                .getCurrentWallpaperFactory(getActivity().getApplicationContext());
                .getCurrentWallpaperFactory(getContext().getApplicationContext());

        factory.createCurrentWallpaperInfos((homeWallpaper, lockWallpaper, presentationMode) -> {
            mHomeWallpaper = homeWallpaper;
            mIsWallpaperInfoReady = true;
            if (mAdapter != null) {
                mAdapter.onWallpaperInfoLoaded();
            }
            loadWallpaperBackground();

        }, false);
        view.addOnLayoutChangeListener(new OnLayoutChangeListener() {
            @Override
            public void onLayoutChange(View v, int left, int top, int right, int bottom,
                    int oldLeft, int oldTop, int oldRight, int oldBottom) {
                mPageHeight = mPreviewPager.getHeight() - mPreviewPager.getPaddingTop() -
                mCardHeight = mPreviewPager.getHeight() - mPreviewPager.getPaddingTop() -
                        res.getDimensionPixelSize(R.dimen.indicator_container_height);
                mPageWidth = (int) (mPageHeight / mScreenAspectRatio);
                mPreviewPager.forceCardWidth(mPageWidth);
                mCardWidth = (int) (mCardHeight / mScreenAspectRatio);
                view.removeOnLayoutChangeListener(this);
                loadWallpaperBackground();
            }
        });
        return view;
    }

    private void loadWallpaperBackground() {
        if (mHomeWallpaper != null && mCardHeight > 0 && mCardWidth > 0) {
            mHomeWallpaper.getThumbAsset(getContext()).decodeBitmap(mCardWidth,
                    mCardHeight,
                    bitmap -> {
                        mCardBackground =
                                new BitmapDrawable(getResources(), bitmap);
                        if (mAdapter != null) {
                            mAdapter.onWallpaperInfoLoaded();
                        }
                    });
        }
    }

    private void createAdapter() {
        mAdapter = new GridPreviewAdapter(mSelectedOption);
        mPreviewPager.setAdapter(mAdapter);
@@ -181,18 +195,16 @@ public class GridFragment extends ToolbarFragment {
        public void bindPreviewContent() {
            Resources resources = card.getResources();
            bindWallpaperIfAvailable();
            mPreviewAsset.loadDrawable(mActivity, mPreview,
                    resources.getColor(android.R.color.transparent, null));
            mPreviewAsset.loadDrawableWithTransition(mActivity,
                    mPreview /* imageView */,
                    PREVIEW_FADE_DURATION_MS /* duration */,
                    null /* drawableLoadedListener */,
                    resources.getColor(android.R.color.transparent, null) /* placeHolderColorJ */);
        }

        void bindWallpaperIfAvailable() {
            if (card != null && mIsWallpaperInfoReady && mHomeWallpaper != null) {
                mHomeWallpaper.getThumbAsset(card.getContext()).decodeBitmap(mPageWidth,
                        mPageHeight,
                        bitmap -> {
                            mPreview.setBackground(
                                    new BitmapDrawable(card.getResources(), bitmap));
                        });
            if (card != null && mCardBackground != null) {
                mPreview.setBackground(mCardBackground);
            }
        }
    }
+48 −4
Original line number Diff line number Diff line
@@ -17,8 +17,10 @@ package com.android.customization.widget;

import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.database.DataSetObserver;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -39,14 +41,19 @@ import com.android.wallpaper.R;
 */
public class PreviewPager extends LinearLayout {

    private static final int STYLE_PEEKING = 0;
    private static final int STYLE_ASPECT_RATIO = 1;

    private final ViewPager mViewPager;
    private final PageIndicator mPageIndicator;
    private final View mPreviousArrow;
    private final View mNextArrow;
    private final ViewPager.OnPageChangeListener mPageListener;
    private int mPageStyle;

    private PagerAdapter mAdapter;
    private ViewPager.OnPageChangeListener mExternalPageListener;
    private float mScreenAspectRatio;

    public PreviewPager(Context context) {
        this(context, null);
@@ -60,14 +67,30 @@ public class PreviewPager extends LinearLayout {
        super(context, attrs, defStyleAttr);
        LayoutInflater.from(context).inflate(R.layout.preview_pager, this);
        Resources res = context.getResources();
        TypedArray a = context.obtainStyledAttributes(attrs,
                R.styleable.PreviewPager, defStyleAttr, 0);

        mPageStyle = a.getInteger(R.styleable.PreviewPager_card_style, STYLE_PEEKING);

        mViewPager = findViewById(R.id.preview_viewpager);
        mViewPager.setPageMargin(res.getDimensionPixelOffset(R.dimen.preview_page_gap));
        mViewPager.setClipToPadding(false);
        mViewPager.setPadding(res.getDimensionPixelOffset(R.dimen.preview_page_horizontal_margin),
        if (mPageStyle == STYLE_PEEKING) {
            mViewPager.setPadding(
                    res.getDimensionPixelOffset(R.dimen.preview_page_horizontal_margin),
                    res.getDimensionPixelOffset(R.dimen.preview_page_top_margin),
                    res.getDimensionPixelOffset(R.dimen.preview_page_horizontal_margin),
                    res.getDimensionPixelOffset(R.dimen.preview_page_bottom_margin));
        } else if (mPageStyle == STYLE_ASPECT_RATIO) {
            DisplayMetrics dm = res.getDisplayMetrics();
            mScreenAspectRatio = (float) dm.heightPixels / dm.widthPixels;
            mViewPager.setPadding(
                    0,
                    res.getDimensionPixelOffset(R.dimen.preview_page_top_margin),
                    0,
                    res.getDimensionPixelOffset(R.dimen.preview_page_bottom_margin));

        }
        mPageIndicator = findViewById(R.id.page_indicator);
        mPreviousArrow = findViewById(R.id.arrow_previous);
        mPreviousArrow.setOnClickListener(v -> {
@@ -83,6 +106,27 @@ public class PreviewPager extends LinearLayout {
        mViewPager.addOnPageChangeListener(mPageListener);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        if (mPageStyle == STYLE_ASPECT_RATIO && mViewPager.getPaddingStart() == 0) {
            int availableWidth = MeasureSpec.getSize(widthMeasureSpec);
            int availableHeight = MeasureSpec.getSize(heightMeasureSpec);
            int indicatorHeight = ((View) mPageIndicator.getParent()).getLayoutParams().height;
            int pagerHeight = availableHeight - indicatorHeight;
            if (availableWidth > 0) {
                int absoluteCardWidth = (int) ((pagerHeight - mViewPager.getPaddingBottom()
                        - mViewPager.getPaddingTop())/ mScreenAspectRatio);
                int hPadding = (availableWidth / 2) - (absoluteCardWidth / 2);
                mViewPager.setPaddingRelative(
                        hPadding,
                        mViewPager.getPaddingTop(),
                        hPadding,
                        mViewPager.getPaddingBottom());
            }
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    public void forceCardWidth(int widthPixels) {
        mViewPager.addOnLayoutChangeListener(new OnLayoutChangeListener() {
            @Override