Merge "Evenly space theme options." into ub-launcher3-qt-dev
am: 16020ba23f
Change-Id: Ifd4b0426145029b8b339e10dfa3319b567c6c82a
diff --git a/res/layout/theme_color_option.xml b/res/layout/theme_color_option.xml
index 0b7ca9e..72acd8b 100644
--- a/res/layout/theme_color_option.xml
+++ b/res/layout/theme_color_option.xml
@@ -15,10 +15,10 @@
limitations under the License.
-->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_marginHorizontal="6dp"
- android:paddingHorizontal="4dp">
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:padding="4dp">
<ImageView
android:id="@+id/option_tile"
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 465a926..30123ed 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -57,7 +57,6 @@
<dimen name="theme_option_title_font_text_size">12sp</dimen>
<dimen name="option_tile_margin_horizontal">4dp</dimen>
- <dimen name="option_tile_margin_horizontal_ends">10dp</dimen>
<dimen name="theme_option_label_margin">4dp</dimen>
<dimen name="preview_card_corner_radius">8dp</dimen>
diff --git a/res/values/integers.xml b/res/values/integers.xml
new file mode 100644
index 0000000..6e2db17
--- /dev/null
+++ b/res/values/integers.xml
@@ -0,0 +1,19 @@
+<?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>
+ <integer name="options_grid_num_columns">4</integer>
+</resources>
diff --git a/src/com/android/customization/picker/theme/CustomThemeActivity.java b/src/com/android/customization/picker/theme/CustomThemeActivity.java
index df14c86..40d1fe8 100644
--- a/src/com/android/customization/picker/theme/CustomThemeActivity.java
+++ b/src/com/android/customization/picker/theme/CustomThemeActivity.java
@@ -339,7 +339,8 @@
return CustomThemeComponentFragment.newInstance(
CustomThemeActivity.this.getString(R.string.custom_theme_fragment_title),
position,
- titleResId);
+ titleResId,
+ true);
}
}
diff --git a/src/com/android/customization/picker/theme/CustomThemeComponentFragment.java b/src/com/android/customization/picker/theme/CustomThemeComponentFragment.java
index f2088ae..cd2c067 100644
--- a/src/com/android/customization/picker/theme/CustomThemeComponentFragment.java
+++ b/src/com/android/customization/picker/theme/CustomThemeComponentFragment.java
@@ -40,6 +40,7 @@
public class CustomThemeComponentFragment extends ToolbarFragment {
private static final String ARG_KEY_POSITION = "CustomThemeComponentFragment.position";
private static final String ARG_KEY_TITLE_RES_ID = "CustomThemeComponentFragment.title_res";
+ private static final String ARG_USE_GRID_LAYOUT = "CustomThemeComponentFragment.use_grid";;
private CustomThemeComponentFragmentHost mHost;
public interface CustomThemeComponentFragmentHost {
@@ -55,10 +56,16 @@
public static CustomThemeComponentFragment newInstance(CharSequence toolbarTitle, int position,
int titleResId) {
+ return newInstance(toolbarTitle, position, titleResId, false);
+ }
+
+ public static CustomThemeComponentFragment newInstance(CharSequence toolbarTitle, int position,
+ int titleResId, boolean allowGridLayout) {
CustomThemeComponentFragment fragment = new CustomThemeComponentFragment();
Bundle arguments = ToolbarFragment.createArguments(toolbarTitle);
arguments.putInt(ARG_KEY_POSITION, position);
arguments.putInt(ARG_KEY_TITLE_RES_ID, titleResId);
+ arguments.putBoolean(ARG_USE_GRID_LAYOUT, allowGridLayout);
fragment.setArguments(arguments);
return fragment;
}
@@ -67,6 +74,7 @@
private CustomThemeManager mCustomThemeManager;
private int mPosition;
@StringRes private int mTitleResId;
+ private boolean mUseGridLayout;
private RecyclerView mOptionsContainer;
private OptionSelectorController<ThemeComponentOption> mOptionsController;
@@ -79,6 +87,7 @@
super.onCreate(savedInstanceState);
mPosition = getArguments().getInt(ARG_KEY_POSITION);
mTitleResId = getArguments().getInt(ARG_KEY_TITLE_RES_ID);
+ mUseGridLayout = getArguments().getBoolean(ARG_USE_GRID_LAYOUT);
mProvider = mHost.getComponentOptionProvider(mPosition);
mCustomThemeManager = mHost.getCustomThemeManager();
}
@@ -144,7 +153,8 @@
private void setUpOptions() {
mProvider.fetch(options -> {
- mOptionsController = new OptionSelectorController(mOptionsContainer, options);
+ mOptionsController = new OptionSelectorController(
+ mOptionsContainer, options, mUseGridLayout, false);
mOptionsController.addListener(selected -> {
mSelectedOption = (ThemeComponentOption) selected;
diff --git a/src/com/android/customization/widget/HorizontalSpacerItemDecoration.java b/src/com/android/customization/widget/HorizontalSpacerItemDecoration.java
index f17d52f..df38e6e 100644
--- a/src/com/android/customization/widget/HorizontalSpacerItemDecoration.java
+++ b/src/com/android/customization/widget/HorizontalSpacerItemDecoration.java
@@ -11,24 +11,22 @@
/**
* RecyclerView ItemDecorator that adds a horizontal space of the given size between items
- * (except the first and last)
+ * and double that space on the ends.
*/
public class HorizontalSpacerItemDecoration extends ItemDecoration {
private final int mOffset;
- private final int mEndOffset;
- public HorizontalSpacerItemDecoration(@Dimension int offset, @Dimension int endOffset) {
+ public HorizontalSpacerItemDecoration(@Dimension int offset) {
mOffset = offset;
- mEndOffset = endOffset;
}
@Override
public void getItemOffsets(@NonNull Rect outRect, @NonNull View view,
@NonNull RecyclerView parent, @NonNull State state) {
int position = parent.getChildAdapterPosition(view);
- int left = position == 0 ? mEndOffset : mOffset;
- int right = (position == parent.getAdapter().getItemCount() - 1) ? mEndOffset : mOffset;
+ int left = position == 0 ? mOffset * 2: mOffset;
+ int right = (position == parent.getAdapter().getItemCount() - 1) ? mOffset * 2 : mOffset;
outRect.set(left, 0, right, 0);
}
}
diff --git a/src/com/android/customization/widget/OptionSelectorController.java b/src/com/android/customization/widget/OptionSelectorController.java
index 615d7d8..b311abe 100644
--- a/src/com/android/customization/widget/OptionSelectorController.java
+++ b/src/com/android/customization/widget/OptionSelectorController.java
@@ -18,18 +18,22 @@
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
+import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.view.WindowManager;
import android.widget.TextView;
import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.android.customization.model.CustomizationManager;
import com.android.customization.model.CustomizationOption;
+import com.android.customization.model.theme.custom.ThemeComponentOption;
import com.android.wallpaper.R;
import java.util.HashSet;
@@ -49,6 +53,7 @@
* Interface to be notified when an option is selected by the user.
*/
public interface OptionSelectedListener {
+
/**
* Called when an option has been selected (and marked as such in the UI)
*/
@@ -57,6 +62,8 @@
private final RecyclerView mContainer;
private final List<T> mOptions;
+ private final boolean mUseGrid;
+ private final boolean mShowCheckmark;
private final Set<OptionSelectedListener> mListeners = new HashSet<>();
private RecyclerView.Adapter<TileViewHolder> mAdapter;
@@ -64,8 +71,15 @@
private CustomizationOption mAppliedOption;
public OptionSelectorController(RecyclerView container, List<T> options) {
+ this(container, options, false, true);
+ }
+
+ public OptionSelectorController(RecyclerView container, List<T> options,
+ boolean useGrid, boolean showCheckmark) {
mContainer = container;
mOptions = options;
+ mUseGrid = useGrid;
+ mShowCheckmark = showCheckmark;
}
public void addListener(OptionSelectedListener listener) {
@@ -140,7 +154,7 @@
holder.itemView.setActivated(option.equals(mSelectedOption));
holder.itemView.setOnClickListener(view -> setSelectedOption(option));
- if (option.equals(mAppliedOption)) {
+ if (mShowCheckmark && option.equals(mAppliedOption)) {
Resources res = mContainer.getContext().getResources();
Drawable checkmark = res.getDrawable(R.drawable.ic_check_circle_filled_24px);
Drawable frame = holder.itemView.getForeground();
@@ -171,10 +185,38 @@
mContainer.setLayoutManager(new LinearLayoutManager(mContainer.getContext(),
LinearLayoutManager.HORIZONTAL, false));
Resources res = mContainer.getContext().getResources();
- mContainer.addItemDecoration(new HorizontalSpacerItemDecoration(
- res.getDimensionPixelOffset(R.dimen.option_tile_margin_horizontal),
- res.getDimensionPixelOffset(R.dimen.option_tile_margin_horizontal_ends)));
mContainer.setAdapter(mAdapter);
+
+ // Measure RecyclerView to get to the total amount of space used by all options.
+ mContainer.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
+ DisplayMetrics metrics = new DisplayMetrics();
+ // TODO: retrieve fixed container width for landscape
+ mContainer.getContext().getSystemService(WindowManager.class)
+ .getDefaultDisplay().getMetrics(metrics);
+ int totalWidth = mContainer.getMeasuredWidth();
+
+ if (mUseGrid) {
+ int numColumns = res.getInteger(R.integer.options_grid_num_columns);
+ int widthPerItem = totalWidth / mAdapter.getItemCount();
+ int extraSpace = metrics.widthPixels - widthPerItem * numColumns;
+ int containerSidePadding = extraSpace / (numColumns + 1);
+ mContainer.setLayoutManager(new GridLayoutManager(mContainer.getContext(), numColumns));
+ mContainer.setPaddingRelative(containerSidePadding, 0, containerSidePadding, 0);
+ mContainer.setOverScrollMode(View.OVER_SCROLL_NEVER);
+ return;
+ }
+
+ int extraSpace = metrics.widthPixels - totalWidth;
+ if (extraSpace >= 0) {
+ mContainer.setOverScrollMode(View.OVER_SCROLL_NEVER);
+ }
+ int itemSideMargin = res.getDimensionPixelOffset(R.dimen.option_tile_margin_horizontal);
+ int defaultTotalPadding = itemSideMargin * (mAdapter.getItemCount() * 2 + 2);
+ if (extraSpace > defaultTotalPadding) {
+ int spaceBetweenItems = extraSpace / (mAdapter.getItemCount() + 1);
+ itemSideMargin = spaceBetweenItems / 2;
+ }
+ mContainer.addItemDecoration(new HorizontalSpacerItemDecoration(itemSideMargin));
}
public void resetOptions(List<T> options) {