Skip to content

Commit

Permalink
[MaterialToolbar] Support scaleType and adjustViewBounds for logo
Browse files Browse the repository at this point in the history
Resolves #2562

GIT_ORIGIN_REV_ID=c675c6a12e2fc242d2e9e019913df650b87eea2b
PiperOrigin-RevId: 428837808
  • Loading branch information
P1NG2WIN authored and raajkumars committed Feb 15, 2022
1 parent 85ed993 commit b01051b
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 0 deletions.
7 changes: 7 additions & 0 deletions docs/components/TopAppBar.md
Expand Up @@ -706,6 +706,13 @@ Element | Attribute | Related meth
**Height** | `app:height` | N/A | `?attr/actionBarSize`
**Overlay window** | `app:windowActionModeOverlay` (in app theme) | N/A | `false`

#### Toolbar logo attributes

Element | Attribute | Related method(s) | Default value
--------------------- | -------------------------------------------- | --------------------------------------------------------- | -------------
**AdjustViewBounds** | `app:logoAdjustViewBounds` | `setLogoAdjustViewBounds`<br>`isLogoAdjustViewBounds` | `false`
**ScaleType** | `app:logoScaleType` | `setLogoScaleType`<br>`getLogoScaleType` | ImageView's default

#### Styles

Element | Style
Expand Down
74 changes: 74 additions & 0 deletions lib/java/com/google/android/material/appbar/MaterialToolbar.java
Expand Up @@ -32,6 +32,8 @@
import android.util.AttributeSet;
import android.util.Pair;
import android.view.View;
import android.view.View.MeasureSpec;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
Expand Down Expand Up @@ -69,10 +71,24 @@ public class MaterialToolbar extends Toolbar {

private static final int DEF_STYLE_RES = R.style.Widget_MaterialComponents_Toolbar;

private static final ImageView.ScaleType[] LOGO_SCALE_TYPE_ARRAY = {
ImageView.ScaleType.MATRIX,
ImageView.ScaleType.FIT_XY,
ImageView.ScaleType.FIT_START,
ImageView.ScaleType.FIT_CENTER,
ImageView.ScaleType.FIT_END,
ImageView.ScaleType.CENTER,
ImageView.ScaleType.CENTER_CROP,
ImageView.ScaleType.CENTER_INSIDE
};

@Nullable private Integer navigationIconTint;
private boolean titleCentered;
private boolean subtitleCentered;

@Nullable private ImageView.ScaleType logoScaleType;
@Nullable private Boolean logoAdjustViewBounds;

public MaterialToolbar(@NonNull Context context) {
this(context, null);
}
Expand All @@ -97,6 +113,15 @@ public MaterialToolbar(@NonNull Context context, @Nullable AttributeSet attrs, i
titleCentered = a.getBoolean(R.styleable.MaterialToolbar_titleCentered, false);
subtitleCentered = a.getBoolean(R.styleable.MaterialToolbar_subtitleCentered, false);

final int index = a.getInt(R.styleable.MaterialToolbar_logoScaleType, -1);
if (index >= 0 && index < LOGO_SCALE_TYPE_ARRAY.length) {
logoScaleType = LOGO_SCALE_TYPE_ARRAY[index];
}

if (a.hasValue(R.styleable.MaterialToolbar_logoAdjustViewBounds)) {
logoAdjustViewBounds = a.getBoolean(R.styleable.MaterialToolbar_logoAdjustViewBounds, false);
}

a.recycle();

initBackground(context);
Expand All @@ -107,6 +132,7 @@ protected void onLayout(boolean changed, int left, int top, int right, int botto
super.onLayout(changed, left, top, right, bottom);

maybeCenterTitleViews();
updateLogoImageView();
}

private void maybeCenterTitleViews() {
Expand Down Expand Up @@ -178,6 +204,54 @@ private void layoutTitleCenteredHorizontally(
titleView.layout(titleLeft, titleView.getTop(), titleRight, titleView.getBottom());
}

private void updateLogoImageView() {
ImageView logoImageView = ToolbarUtils.getLogoImageView(this);

if (logoImageView != null) {
if (logoAdjustViewBounds != null) {
logoImageView.setAdjustViewBounds(logoAdjustViewBounds);
}
if (logoScaleType != null) {
logoImageView.setScaleType(logoScaleType);
}
}
}

/**
* Returns scale type of logo's ImageView
*
* @see #setLogoScaleType(ImageView.ScaleType). Default - null
*/
@Nullable
public ImageView.ScaleType getLogoScaleType() {
return logoScaleType;
}

/** Sets ImageView.ScaleType for logo's ImageView. */
public void setLogoScaleType(@NonNull ImageView.ScaleType logoScaleType) {
if (this.logoScaleType != logoScaleType) {
this.logoScaleType = logoScaleType;
requestLayout();
}
}

/**
* Returns logo's ImageView adjustViewBounds
*
* @see #setLogoAdjustViewBounds(boolean). Default - false
*/
public boolean isLogoAdjustViewBounds() {
return logoAdjustViewBounds != null && logoAdjustViewBounds;
}

/** Sets ImageView.adjustViewBounds for logo's ImageView. */
public void setLogoAdjustViewBounds(boolean logoAdjustViewBounds) {
if (this.logoAdjustViewBounds == null || this.logoAdjustViewBounds != logoAdjustViewBounds) {
this.logoAdjustViewBounds = logoAdjustViewBounds;
requestLayout();
}
}

@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
Expand Down
Expand Up @@ -85,5 +85,7 @@
<public name="titleCentered" type="attr"/>
<public name="subtitleCentered" type="attr"/>
<public name="titlePositionInterpolator" type="attr"/>
<public name="logoAdjustViewBounds" type="attr"/>
<public name="logoScaleType" type="attr"/>
</resources>

27 changes: 27 additions & 0 deletions lib/java/com/google/android/material/appbar/res/values/attrs.xml
Expand Up @@ -276,6 +276,33 @@
should be centered horizontally within the toolbar. Default is false.
-->
<attr name="subtitleCentered" format="boolean" />
<!-- adjust view bounds for logo's imageView. -->
<attr name="logoAdjustViewBounds" format="boolean" />
<!-- scale type for logo's imageView. -->
<attr name="logoScaleType">
<!-- Scale using the image matrix when drawing. See
{@link android.widget.ImageView#setImageMatrix(Matrix)}. -->
<enum name="matrix" value="0" />
<!-- Scale the image using {@link android.graphics.Matrix.ScaleToFit#FILL}. -->
<enum name="fitXY" value="1" />
<!-- Scale the image using {@link android.graphics.Matrix.ScaleToFit#START}. -->
<enum name="fitStart" value="2" />
<!-- Scale the image using {@link android.graphics.Matrix.ScaleToFit#CENTER}. -->
<enum name="fitCenter" value="3" />
<!-- Scale the image using {@link android.graphics.Matrix.ScaleToFit#END}. -->
<enum name="fitEnd" value="4" />
<!-- Center the image in the view, but perform no scaling. -->
<enum name="center" value="5" />
<!-- Scale the image uniformly (maintain the image's aspect ratio) so both dimensions
(width and height) of the image will be equal to or larger than the corresponding
dimension of the view (minus padding). The image is then centered in the view. -->
<enum name="centerCrop" value="6" />
<!-- Scale the image uniformly (maintain the image's aspect ratio) so that both
dimensions (width and height) of the image will be equal to or less than the
corresponding dimension of the view (minus padding). The image is then centered in
the view. -->
<enum name="centerInside" value="7" />
</attr>
</declare-styleable>

</resources>
22 changes: 22 additions & 0 deletions lib/java/com/google/android/material/internal/ToolbarUtils.java
Expand Up @@ -23,6 +23,7 @@
import android.text.TextUtils;
import android.view.View;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.IdRes;
import androidx.annotation.NonNull;
Expand Down Expand Up @@ -66,6 +67,27 @@ private static TextView getTextView(@NonNull Toolbar toolbar, CharSequence text)
return null;
}

@Nullable
public static ImageView getLogoImageView(@NonNull Toolbar toolbar) {
return getImageView(toolbar, toolbar.getLogo());
}

@Nullable
private static ImageView getImageView(@NonNull Toolbar toolbar, @Nullable Drawable content) {
for (int i = 0; i < toolbar.getChildCount(); i++) {
View child = toolbar.getChildAt(i);
if (child instanceof ImageView) {
ImageView imageView = (ImageView) child;
if (content != null
&& imageView.getDrawable().getConstantState().equals(content.getConstantState())
) {
return imageView;
}
}
}
return null;
}

@Nullable
public static View getSecondaryActionMenuItemView(@NonNull Toolbar toolbar) {
ActionMenuView actionMenuView = getActionMenuView(toolbar);
Expand Down

0 comments on commit b01051b

Please sign in to comment.