Commit a6fb0021 authored by Shakti Sahu's avatar Shakti Sahu Committed by Commit Bot

Query Tiles : Tile UI polish

This CL includes :
1 - Rounding the tiles using RoundedCornerImageView
2 - Gradient overlay above RCIV
3 - Tile width calculation logic depending on screen size

Bug: 1068666
Change-Id: I014a01f17514e8df1da65cfd12e2baf9eb931e2e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2137818
Commit-Queue: Shakti Sahu <shaktisahu@chromium.org>
Reviewed-by: default avatarTheresa  <twellington@chromium.org>
Reviewed-by: default avatarDavid Trainor <dtrainor@chromium.org>
Cr-Commit-Position: refs/heads/master@{#758164}
parent 677e751d
......@@ -71,7 +71,9 @@ if (is_android) {
"android/java/src/org/chromium/chrome/browser/query_tiles/list/TileListProperties.java",
"android/java/src/org/chromium/chrome/browser/query_tiles/list/TileListPropertyViewBinder.java",
"android/java/src/org/chromium/chrome/browser/query_tiles/list/TileListView.java",
"android/java/src/org/chromium/chrome/browser/query_tiles/list/TileSizeSupplier.java",
"android/java/src/org/chromium/chrome/browser/query_tiles/list/TileViewHolder.java",
"android/java/src/org/chromium/chrome/browser/query_tiles/list/TileViewHolderFactory.java",
]
deps = [
......@@ -92,7 +94,12 @@ if (is_android) {
}
android_resources("chrome_upboarding_query_tiles_java_resources") {
sources = [ "android/java/res/layout/query_tile_view.xml" ]
sources = [
"android/java/res/drawable/query_tile_overlay.xml",
"android/java/res/layout/query_tile_view.xml",
"android/java/res/values/dimens.xml",
"android/java/res/values/styles.xml",
]
custom_package = "org.chromium.chrome.query_tiles"
}
......
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2020 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file. -->
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<gradient
android:angle="270"
android:endColor="#99000000"
android:startColor="#00000000"
android:type="linear" />
<corners
android:radius="@dimen/tile_corner_radius"/>
</shape>
......@@ -9,18 +9,31 @@
android:layout_height="86dp"
android:orientation="vertical">
<org.chromium.ui.widget.ChromeImageView
<org.chromium.components.browser_ui.widget.RoundedCornerImageView
android:id="@+id/thumbnail"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_horizontal"
android:scaleType="centerCrop"
android:src="@drawable/chrome_sync_logo"
android:importantForAccessibility="no"/>
android:importantForAccessibility="no"
app:cornerRadiusBottomStart="@dimen/tile_corner_radius"
app:cornerRadiusBottomEnd="@dimen/tile_corner_radius"
app:cornerRadiusTopStart="@dimen/tile_corner_radius"
app:cornerRadiusTopEnd="@dimen/tile_corner_radius" />
<ImageView
android:id="@+id/gradient_overlay"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:importantForAccessibility="no"
app:srcCompat="@drawable/query_tile_overlay"/>
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"/>
android:layout_alignParentBottom="true"
android:layout_marginBottom="12dp"
android:layout_marginStart="16dp"
android:textAppearance="@style/TextAppearance.WhiteText"/>
</RelativeLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2020 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file. -->
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Tile dimensions -->
<dimen name="tile_corner_radius">8dp</dimen>
<dimen name="tile_ideal_width">86dp</dimen>
<!-- Tile container dimensions -->
<dimen name="tile_grid_inter_tile_padding">12dp</dimen>
<dimen name="recycler_view_start_margin">16dp</dimen>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2020 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file. -->
<resources xmlns:tools="http://schemas.android.com/tools">
<style name="TextAppearance.WhiteText">
<item name="android:textColor">@android:color/white</item>
<item name="android:textSize">@dimen/text_size_medium</item>
</style>
</resources>
......@@ -5,12 +5,18 @@
package org.chromium.chrome.browser.query_tiles.list;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.RecyclerView.ItemDecoration;
import androidx.recyclerview.widget.RecyclerView.State;
import org.chromium.chrome.query_tiles.R;
import org.chromium.ui.modelutil.ForwardingListObservable;
import org.chromium.ui.modelutil.PropertyModelChangeProcessor;
import org.chromium.ui.modelutil.RecyclerViewAdapter;
......@@ -22,25 +28,39 @@ import org.chromium.ui.modelutil.RecyclerViewAdapter;
class TileListView {
private final TileListModel mModel;
private final RecyclerView mView;
private final RecyclerViewAdapter<TileViewHolder, Void> mAdapter;
private final LinearLayoutManager mLayoutManager;
private final TileSizeSupplier mTileSizeSupplier;
/** Constructor. */
public TileListView(Context context, TileListModel model) {
mModel = model;
mView = new RecyclerView(context);
mView = new RecyclerView(context) {
@Override
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Reset the adapter to ensure that any cached views are recreated.
setAdapter(null);
setAdapter(mAdapter);
mTileSizeSupplier.recompute();
}
};
mView.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false);
mView.setLayoutManager(mLayoutManager);
mView.addItemDecoration(new ItemDecorationImpl(context));
mTileSizeSupplier = new TileSizeSupplier(context);
PropertyModelChangeProcessor.create(
mModel.getProperties(), mView, new TileListPropertyViewBinder());
RecyclerViewAdapter<TileViewHolder, Void> adapter =
new RecyclerViewAdapter<TileViewHolder, Void>(
new ModelChangeProcessor(mModel), TileViewHolder::create);
mView.setAdapter(adapter);
mView.post(adapter::notifyDataSetChanged);
mAdapter = new RecyclerViewAdapter<>(
new ModelChangeProcessor(mModel), new TileViewHolderFactory(mTileSizeSupplier));
mView.setAdapter(mAdapter);
mView.post(mAdapter::notifyDataSetChanged);
}
/** @return The Android {@link View} representing this widget. */
......@@ -48,6 +68,23 @@ class TileListView {
return mView;
}
private class ItemDecorationImpl extends ItemDecoration {
private final int mInterCellPadding;
public ItemDecorationImpl(Context context) {
mInterCellPadding = context.getResources().getDimensionPixelOffset(
R.dimen.tile_grid_inter_tile_padding);
}
@Override
public void getItemOffsets(@NonNull Rect outRect, @NonNull View view,
@NonNull RecyclerView parent, @NonNull State state) {
int position = parent.getChildAdapterPosition(view);
if (position != 0) outRect.left = mInterCellPadding / 2;
if (position != mModel.size() - 1) outRect.right = mInterCellPadding / 2;
}
}
private static class ModelChangeProcessor extends ForwardingListObservable<Void>
implements RecyclerViewAdapter.Delegate<TileViewHolder, Void> {
private final TileListModel mModel;
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.query_tiles.list;
import android.content.Context;
import android.content.res.Resources;
import org.chromium.base.supplier.Supplier;
import org.chromium.chrome.browser.query_tiles.list.TileSizeSupplier.TileSize;
import org.chromium.chrome.query_tiles.R;
/**
* A helper class to compute dimensions for the carousel layout.
*/
class TileSizeSupplier implements Supplier<TileSize> {
/**
* Contains details to be used by the grid layout when placing items.
*/
public static class TileSize {
public int width;
public int interTilePadding;
}
private final TileSize mComputedTileSize;
private final Resources mResources;
private final int mIdealTileWidth;
private final int mInterTilePadding;
/** Constructor. */
public TileSizeSupplier(Context context) {
mComputedTileSize = new TileSize();
mResources = context.getResources();
mIdealTileWidth = mResources.getDimensionPixelOffset(R.dimen.tile_ideal_width);
mInterTilePadding =
mResources.getDimensionPixelOffset(R.dimen.tile_grid_inter_tile_padding);
recompute();
}
@Override
public TileSize get() {
return mComputedTileSize;
}
/**
* Given a desired cell width, computes the actual item width feasible. Should be
* invoked after a orientation change as well.
* @return The {@link TileSize} containing results of the computation.
*/
public void recompute() {
double idealSpanCount =
(double) getAvailableWidth() / (mIdealTileWidth + mInterTilePadding);
double adjustedSpanCount = Math.round(idealSpanCount);
// For carousel, we need to have the last cell peeking out of the screen.
adjustedSpanCount += 0.5f;
double tileWidthToUse = (getAvailableWidth() - mInterTilePadding * (idealSpanCount - 1))
/ adjustedSpanCount;
mComputedTileSize.interTilePadding = mInterTilePadding;
mComputedTileSize.width = (int) tileWidthToUse;
}
private int getAvailableWidth() {
// TODO(shaktisahu): Cap this for tablet and landscape to 600dp.
return mResources.getDisplayMetrics().widthPixels
- 2 * mResources.getDimensionPixelOffset(R.dimen.recycler_view_start_margin);
}
}
......@@ -4,9 +4,7 @@
package org.chromium.chrome.browser.query_tiles.list;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
......@@ -25,16 +23,6 @@ class TileViewHolder extends ViewHolder {
super(itemView);
}
/**
* Used as a method reference for ViewHolderFactory.
* @see RecyclerViewAdapter.ViewHolderFactory#createViewHolder
*/
public static TileViewHolder create(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.query_tile_view, parent, false);
return new TileViewHolder(view);
}
/**
* Binds the currently held {@link View} to {@code item}.
* @param properties The shared {@link PropertyModel} all items can access.
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.query_tiles.list;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import org.chromium.base.supplier.Supplier;
import org.chromium.chrome.browser.query_tiles.list.TileSizeSupplier.TileSize;
import org.chromium.chrome.query_tiles.R;
import org.chromium.ui.modelutil.RecyclerViewAdapter;
/**
* A factory class to create view holders for the query tiles.
*/
class TileViewHolderFactory implements RecyclerViewAdapter.ViewHolderFactory<TileViewHolder> {
private final Supplier<TileSize> mTileSizeSupplier;
/**
* Constructor.
* @param tileSizeSupplier The {@link TileSize} to provide width and height for the view.
*/
public TileViewHolderFactory(Supplier<TileSize> tileSizeSupplier) {
mTileSizeSupplier = tileSizeSupplier;
}
@Override
public TileViewHolder createViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.query_tile_view, parent, false);
view.getLayoutParams().width = mTileSizeSupplier.get().width;
view.getLayoutParams().height = mTileSizeSupplier.get().width;
return new TileViewHolder(view);
}
}
......@@ -162,7 +162,8 @@ public class RoundedCornerImageView extends AppCompatImageView {
if (drawable instanceof ColorDrawable) {
mRoundedBackgroundPaint.setColor(((ColorDrawable) getDrawable()).getColor());
mRoundedContentPaint = null;
} else if (drawable instanceof BitmapDrawable) {
} else if (drawable instanceof BitmapDrawable
&& ((BitmapDrawable) drawable).getBitmap() != null) {
mRoundedBackgroundPaint.setColor(mFillColor);
mRoundedContentPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
......@@ -210,7 +211,6 @@ public class RoundedCornerImageView extends AppCompatImageView {
Shader shader = mRoundedContentPaint.getShader();
if (shader != null) {
Drawable drawable = getDrawable();
Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
mTmpMatrix.set(getImageMatrix());
mTmpMatrix.preScale((float) drawable.getIntrinsicWidth() / bitmap.getWidth(),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment