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

Commit 385ce933 authored by Chihhang Chuang's avatar Chihhang Chuang Committed by chihhangchuang
Browse files

Fix abnormal ripple effect of bottom tab

Root cause: ThemeFragment and GridFragment are updating the bottom action bar visibility from Visible to Gone quickly, the visiblity change of bottom action bar also update the visiblity of bottom nav. So we will see the ripple effect being abnormal.

Solution:
1. Restrict BottomNav to update visibility, not every time.
2. Make sure ThemeFragment and GridFragment didn't update visibility of BottomActionBar several times when initializing.

Video: https://drive.google.com/file/d/1p5cSPnZ6kHXDeXiTZIavJ_mOKMu7wAtY/view?usp=sharing

Test: Manually
Fixes: 159685933
Change-Id: Ia61d7af21c143c9da5e441cbcef34c0397cb3181
parent b85eff5a
Loading
Loading
Loading
Loading
+12 −7
Original line number Diff line number Diff line
@@ -126,10 +126,19 @@ public class CustomizationPickerActivity extends FragmentActivity implements Wal

        setContentView(R.layout.activity_customization_picker_main);
        setUpBottomNavView();
        mBottomActionBar = findViewById(R.id.bottom_actionbar);
        mBottomActionBar.addVisibilityChangeListener(
                isBottomActionBarVisible -> {
                    boolean isBottomNavVisible = mBottomNav.getVisibility() == View.VISIBLE;
                    // Switch the visibility of BottomNav if visibility of BottomActionBar and
                    // BottomNav are same.
                    if (isBottomActionBarVisible == isBottomNavVisible) {
                        mBottomNav.setVisibility(isBottomActionBarVisible
                                ? View.GONE : View.VISIBLE);
                    }
                });

        FragmentManager fm = getSupportFragmentManager();
        Fragment fragment = fm.findFragmentById(R.id.fragment_container);

        Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.fragment_container);
        if (fragment == null) {
            // App launch specific logic: log the "app launched" event and set up daily logging.
            mUserEventLogger.logAppLaunched();
@@ -143,10 +152,6 @@ public class CustomizationPickerActivity extends FragmentActivity implements Wal
                    WALLPAPER_FOCUS.equals(getIntent().getStringExtra(WALLPAPER_FLAVOR_EXTRA))
                            ? R.id.nav_wallpaper : R.id.nav_theme);
        }

        mBottomActionBar = findViewById(R.id.bottom_actionbar);
        mBottomActionBar.addVisibilityChangeListener(
                isVisible -> mBottomNav.setVisibility(isVisible ? View.GONE : View.VISIBLE));
    }

    @Override
+28 −17
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ import androidx.recyclerview.widget.RecyclerView;

import com.android.customization.model.CustomizationManager.Callback;
import com.android.customization.model.CustomizationManager.OptionsFetchedListener;
import com.android.customization.model.CustomizationOption;
import com.android.customization.model.grid.GridOption;
import com.android.customization.model.grid.GridOptionsManager;
import com.android.customization.module.ThemesUserEventLogger;
@@ -63,8 +64,8 @@ public class GridFragment extends AppbarFragment {

    private static final int FULL_PREVIEW_REQUEST_CODE = 1000;
    private static final String KEY_STATE_SELECTED_OPTION = "GridFragment.selectedOption";
    private static final String KEY_STATE_BOTTOM_ACTION_BAR_VISIBILITY =
            "GridFragment.bottomActionBarVisibility";
    private static final String KEY_STATE_BOTTOM_ACTION_BAR_VISIBLE =
            "GridFragment.bottomActionBarVisible";

    private static final String TAG = "GridFragment";

@@ -177,8 +178,7 @@ public class GridFragment extends AppbarFragment {
            outState.putParcelable(KEY_STATE_SELECTED_OPTION, mSelectedOption);
        }
        if (mBottomActionBar != null) {
            outState.putBoolean(KEY_STATE_BOTTOM_ACTION_BAR_VISIBILITY,
                    mBottomActionBar.isVisible());
            outState.putBoolean(KEY_STATE_BOTTOM_ACTION_BAR_VISIBLE, mBottomActionBar.isVisible());
        }
    }

@@ -211,14 +211,9 @@ public class GridFragment extends AppbarFragment {
            public void onOptionsLoaded(List<GridOption> options) {
                mLoading.hide();
                mOptionsController = new OptionSelectorController<>(mOptionsContainer, options);
                mOptionsController.addListener(selected -> {
                    mSelectedOption = (GridOption) selected;
                    mBottomActionBar.show();
                    mEventLogger.logGridSelected(mSelectedOption);
                    mGridOptionPreviewer.setGridOption(mSelectedOption);
                });
                mOptionsController.initOptions(mGridManager);

                // Find the selected Grid option.
                GridOption previouslySelectedOption = null;
                if (savedInstanceState != null) {
                    previouslySelectedOption = findEquivalent(
@@ -227,15 +222,15 @@ public class GridFragment extends AppbarFragment {
                mSelectedOption = previouslySelectedOption != null
                        ? previouslySelectedOption
                        : getActiveOption(options);
                // Will trigger selected listener.

                mOptionsController.setSelectedOption(mSelectedOption);
                boolean bottomActionBarVisibility = savedInstanceState != null
                        && savedInstanceState.getBoolean(KEY_STATE_BOTTOM_ACTION_BAR_VISIBILITY);
                if (bottomActionBarVisibility) {
                onOptionSelected(mSelectedOption);
                restoreBottomActionBarVisibility(savedInstanceState);

                mOptionsController.addListener(selectedOption -> {
                    onOptionSelected(selectedOption);
                    mBottomActionBar.show();
                } else {
                    mBottomActionBar.hide();
                }
                });
            }

            @Override
@@ -275,6 +270,22 @@ public class GridFragment extends AppbarFragment {
        mError.setVisibility(View.VISIBLE);
    }

    private void onOptionSelected(CustomizationOption selectedOption) {
        mSelectedOption = (GridOption) selectedOption;
        mEventLogger.logGridSelected(mSelectedOption);
        mGridOptionPreviewer.setGridOption(mSelectedOption);
    }

    private void restoreBottomActionBarVisibility(@Nullable Bundle savedInstanceState) {
        boolean isBottomActionBarVisible = savedInstanceState != null
                && savedInstanceState.getBoolean(KEY_STATE_BOTTOM_ACTION_BAR_VISIBLE);
        if (isBottomActionBarVisible) {
            mBottomActionBar.show();
        } else {
            mBottomActionBar.hide();
        }
    }

    private void showFullPreview() {
        Bundle bundle = new Bundle();
        bundle.putParcelable(EXTRA_WALLPAPER_INFO, mHomeWallpaper);
+54 −35
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ import androidx.recyclerview.widget.RecyclerView;

import com.android.customization.model.CustomizationManager.Callback;
import com.android.customization.model.CustomizationManager.OptionsFetchedListener;
import com.android.customization.model.CustomizationOption;
import com.android.customization.model.theme.ThemeBundle;
import com.android.customization.model.theme.ThemeManager;
import com.android.customization.model.theme.custom.CustomTheme;
@@ -68,8 +69,8 @@ public class ThemeFragment extends AppbarFragment {

    private static final String TAG = "ThemeFragment";
    private static final String KEY_SELECTED_THEME = "ThemeFragment.SelectedThemeBundle";
    private static final String KEY_STATE_BOTTOM_ACTION_BAR_VISIBILITY =
            "ThemeFragment.bottomActionBarVisibility";
    private static final String KEY_STATE_BOTTOM_ACTION_BAR_VISIBLE =
            "ThemeFragment.bottomActionBarVisible";
    private static final int FULL_PREVIEW_REQUEST_CODE = 1000;

    /**
@@ -221,8 +222,7 @@ public class ThemeFragment extends AppbarFragment {
            outState.putString(KEY_SELECTED_THEME, mSelectedTheme.getSerializedPackages());
        }
        if (mBottomActionBar != null) {
            outState.putBoolean(KEY_STATE_BOTTOM_ACTION_BAR_VISIBILITY,
                    mBottomActionBar.isVisible());
            outState.putBoolean(KEY_STATE_BOTTOM_ACTION_BAR_VISIBLE, mBottomActionBar.isVisible());
        }
    }

@@ -275,30 +275,10 @@ public class ThemeFragment extends AppbarFragment {
            @Override
            public void onOptionsLoaded(List<ThemeBundle> options) {
                mOptionsController = new OptionSelectorController<>(mOptionsContainer, options);
                mOptionsController.addListener(selected -> {
                    mLoading.hide();
                    if (selected instanceof CustomTheme && !((CustomTheme) selected).isDefined()) {
                        navigateToCustomTheme((CustomTheme) selected);
                    } else {
                        mSelectedTheme = (ThemeBundle) selected;
                        mSelectedTheme.setOverrideThemeWallpaper(mCurrentHomeWallpaper);
                        mEventLogger.logThemeSelected(mSelectedTheme,
                                selected instanceof CustomTheme);
                        mThemeOptionPreviewer.setPreviewInfo(mSelectedTheme.getPreviewInfo());
                        if (mThemeInfoView != null && mSelectedTheme != null) {
                            mThemeInfoView.populateThemeInfo(mSelectedTheme);
                        }

                        if (selected instanceof CustomTheme) {
                            mBottomActionBar.showActionsOnly(INFORMATION, CUSTOMIZE, APPLY);
                        } else {
                            mBottomActionBar.showActionsOnly(INFORMATION, APPLY);
                        }
                        mBottomActionBar.show();
                    }
                });
                mOptionsController.initOptions(mThemeManager);

                // Find out the selected theme option.
                // 1. Find previously selected theme.
                String previouslySelected = savedInstanceState != null
                        ? savedInstanceState.getString(KEY_SELECTED_THEME) : null;
                ThemeBundle previouslySelectedTheme = null;
@@ -312,22 +292,26 @@ public class ThemeFragment extends AppbarFragment {
                        activeTheme = theme;
                    }
                }
                // 2. Use active theme if no previously selected theme.
                mSelectedTheme = previouslySelectedTheme != null
                        ? previouslySelectedTheme
                        : activeTheme;

                // 3. Select the default theme if there is no matching custom enabled theme.
                if (mSelectedTheme == null) {
                    // Select the default theme if there is no matching custom enabled theme
                    mSelectedTheme = findDefaultThemeBundle(options);
                }

                mOptionsController.setSelectedOption(mSelectedTheme);
                boolean bottomActionBarVisibility = savedInstanceState != null
                        && savedInstanceState.getBoolean(KEY_STATE_BOTTOM_ACTION_BAR_VISIBILITY);
                if (bottomActionBarVisibility) {
                onOptionSelected(mSelectedTheme);
                restoreBottomActionBarVisibility(savedInstanceState);

                mOptionsController.addListener(selectedOption -> {
                    onOptionSelected(selectedOption);
                    if (!isAddCustomThemeOption(selectedOption)) {
                        mBottomActionBar.show();
                } else {
                    mBottomActionBar.hide();
                    }
                });
                mLoading.hide();
            }
            @Override
            public void onError(@Nullable Throwable throwable) {
@@ -370,6 +354,41 @@ public class ThemeFragment extends AppbarFragment {
        return null;
    }

    private void onOptionSelected(CustomizationOption selectedOption) {
        if (isAddCustomThemeOption(selectedOption)) {
            navigateToCustomTheme((CustomTheme) selectedOption);
        } else {
            mSelectedTheme = (ThemeBundle) selectedOption;
            mSelectedTheme.setOverrideThemeWallpaper(mCurrentHomeWallpaper);
            mEventLogger.logThemeSelected(mSelectedTheme,
                    selectedOption instanceof CustomTheme);
            mThemeOptionPreviewer.setPreviewInfo(mSelectedTheme.getPreviewInfo());
            if (mThemeInfoView != null && mSelectedTheme != null) {
                mThemeInfoView.populateThemeInfo(mSelectedTheme);
            }

            if (selectedOption instanceof CustomTheme) {
                mBottomActionBar.showActionsOnly(INFORMATION, CUSTOMIZE, APPLY);
            } else {
                mBottomActionBar.showActionsOnly(INFORMATION, APPLY);
            }
        }
    }

    private void restoreBottomActionBarVisibility(@Nullable Bundle savedInstanceState) {
        boolean isBottomActionBarVisible = savedInstanceState != null
                && savedInstanceState.getBoolean(KEY_STATE_BOTTOM_ACTION_BAR_VISIBLE);
        if (isBottomActionBarVisible) {
            mBottomActionBar.show();
        } else {
            mBottomActionBar.hide();
        }
    }

    private boolean isAddCustomThemeOption(CustomizationOption option) {
        return option instanceof CustomTheme && !((CustomTheme) option).isDefined();
    }

    private void navigateToCustomTheme(CustomTheme themeToEdit) {
        Intent intent = new Intent(getActivity(), CustomThemeActivity.class);
        intent.putExtra(CustomThemeActivity.EXTRA_THEME_TITLE, themeToEdit.getTitle());