Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ ext {
espressoVersion = '3.1.0'
mockitoCoreVersion = '2.25.0'
truthVersion = '0.45'
robolectricVersion = '4.3'
robolectricVersion = '4.7.3'

// Enforce the use of prebuilt dependencies in all sub-projects. This is
// required for the doclava dependency.
Expand All @@ -59,7 +59,7 @@ ext {
? project.property('mavenRepoUrl') : '/tmp/myRepo/')

// Current version of the library (could be in-development/unreleased).
mdcLibraryVersion = '1.6.0-alpha03'
mdcLibraryVersion = '1.6.0-alpha03.1'
mdcLibraryPackage = "com.google.android.material"
mdcLibraryDir = "com/google/android/material"
}
Expand Down Expand Up @@ -155,6 +155,9 @@ def getArchivesBaseName(name) {
subprojects {
tasks.withType(Test) {
maxParallelForks = Runtime.runtime.availableProcessors().intdiv(2) ?: 1
forkEvery = 80
maxHeapSize = "2048m"
minHeapSize = "1024m"
}
}

Expand Down Expand Up @@ -194,6 +197,8 @@ subprojects {
compileSdkVersion rootProject.ext.compileSdkVersion

defaultConfig.minSdkVersion rootProject.ext.minSdkVersion
defaultConfig.targetSdkVersion rootProject.ext.targetSdkVersion

// This disables the builds tools automatic vector -> PNG generation
defaultConfig.generatedDensities = []

Expand Down
56 changes: 50 additions & 6 deletions lib/java/com/google/android/material/appbar/AppBarLayout.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,12 @@
import androidx.coordinatorlayout.widget.CoordinatorLayout;
import androidx.core.graphics.drawable.DrawableCompat;
import androidx.core.util.ObjectsCompat;
import androidx.core.view.AccessibilityDelegateCompat;
import androidx.core.view.NestedScrollingChild;
import androidx.core.view.ViewCompat;
import androidx.core.view.ViewCompat.NestedScrollType;
import androidx.core.view.WindowInsetsCompat;
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat;
import androidx.core.view.accessibility.AccessibilityViewCommand;
import androidx.customview.view.AbsSavedState;
Expand Down Expand Up @@ -1363,6 +1365,8 @@ public abstract static class BaseDragCallback<T extends AppBarLayout> {
@Nullable private WeakReference<View> lastNestedScrollingChildRef;
private BaseDragCallback onDragCallback;

private boolean coordinatorLayoutA11yScrollable;

public BaseBehavior() {}

public BaseBehavior(Context context, AttributeSet attrs) {
Expand Down Expand Up @@ -1736,18 +1740,54 @@ private void updateAccessibilityActions(
if (!(lp.getBehavior() instanceof ScrollingViewBehavior)) {
return;
}
addAccessibilityScrollActions(coordinatorLayout, appBarLayout, scrollingView);

// Don't add actions if the children do not have scrolling flags.
if (!childrenHaveScrollFlags(appBarLayout)) {
return;
}

if (!ViewCompat.hasAccessibilityDelegate(coordinatorLayout)) {
ViewCompat.setAccessibilityDelegate(
coordinatorLayout,
new AccessibilityDelegateCompat() {
@Override
public void onInitializeAccessibilityNodeInfo(
View host, @NonNull AccessibilityNodeInfoCompat info) {
super.onInitializeAccessibilityNodeInfo(host, info);
info.setScrollable(coordinatorLayoutA11yScrollable);
info.setClassName(ScrollView.class.getName());
}
});
}

coordinatorLayoutA11yScrollable =
addAccessibilityScrollActions(coordinatorLayout, appBarLayout, scrollingView);
}

private boolean childrenHaveScrollFlags(AppBarLayout appBarLayout) {
final int childCount = appBarLayout.getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = appBarLayout.getChildAt(i);
final LayoutParams childLp = (LayoutParams) child.getLayoutParams();
final int flags = childLp.scrollFlags;

if (flags != AppBarLayout.LayoutParams.SCROLL_FLAG_NO_SCROLL) {
return true;
}
}
return false;
}

private void addAccessibilityScrollActions(
private boolean addAccessibilityScrollActions(
final CoordinatorLayout coordinatorLayout,
@NonNull final T appBarLayout,
@NonNull final View scrollingView) {
if (getTopBottomOffsetForScrollingSibling() != -appBarLayout.getTotalScrollRange()
&& scrollingView.canScrollVertically(1)) {
// Add a collapsing action if the view can scroll up and the offset isn't the abl scroll
// range. (This offset means the view is completely collapsed). Collapse to minimum height.
boolean a11yScrollable = false;
if (getTopBottomOffsetForScrollingSibling() != -appBarLayout.getTotalScrollRange()) {
// Add a collapsing action if the view offset isn't the abl scroll range.
// (The same offset means the view is completely collapsed). Collapse to minimum height.
addActionToExpand(coordinatorLayout, appBarLayout, ACTION_SCROLL_FORWARD, false);
a11yScrollable = true;
}
// Don't add an expanding action if the sibling offset is 0, which would mean the abl is
// completely expanded.
Expand Down Expand Up @@ -1776,13 +1816,16 @@ public boolean perform(@NonNull View view, @Nullable CommandArguments arguments)
return true;
}
});
a11yScrollable = true;
}
} else {
// If the view can't scroll down, we are probably at the top of the scrolling content so
// expand completely.
addActionToExpand(coordinatorLayout, appBarLayout, ACTION_SCROLL_BACKWARD, true);
a11yScrollable = true;
}
}
return a11yScrollable;
}

private void addActionToExpand(
Expand Down Expand Up @@ -2198,6 +2241,7 @@ public void onDependentViewRemoved(
if (dependency instanceof AppBarLayout) {
ViewCompat.removeAccessibilityAction(parent, ACTION_SCROLL_FORWARD.getId());
ViewCompat.removeAccessibilityAction(parent, ACTION_SCROLL_BACKWARD.getId());
ViewCompat.setAccessibilityDelegate(parent, null);
}
}

Expand Down
83 changes: 52 additions & 31 deletions lib/java/com/google/android/material/badge/BadgeState.java
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
/*




/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
Expand Down Expand Up @@ -54,12 +58,14 @@
*
* @hide
*/
@RestrictTo(LIBRARY_GROUP)
public final class BadgeState {
/**
* Maximum number of characters a badge supports displaying by default. It could be changed using
* {@link BadgeDrawable#setMaxCharacterCount(int)}.
*/

@RestrictTo(LIBRARY_GROUP
public final class BadgeState
{
/\ * Maximum number of characters a badge supports displaying by default. It could be changed using
* {@link BadgeDrawable#setMaxCharacterCount
{int} </

private static final int DEFAULT_MAX_BADGE_CHARACTER_COUNT = 4;

private static final String BADGE_RESOURCE_TAG = "badge";
Expand All @@ -76,7 +82,8 @@ public final class BadgeState {
@XmlRes int badgeResId,
@AttrRes int defStyleAttr,
@StyleRes int defStyleRes,
@Nullable State storedState) {
@Nullable State storedState

if (storedState == null) {
storedState = new State();
}
Expand Down Expand Up @@ -126,6 +133,7 @@ public final class BadgeState {
// Only set the badge number if it exists in the style.
// Defaulting it to 0 means the badge will incorrectly show text when the user may want a
// numberless badge.

if (storedState.number != State.NOT_SET) {
currentState.number = storedState.number;
} else if (a.hasValue(R.styleable.Badge_number)) {
Expand All @@ -140,7 +148,9 @@ public final class BadgeState {
: storedState.backgroundColor;

// Only set the badge text color if this attribute has explicitly been set, otherwise use the
// text color specified in the TextAppearance.
// text color specified in the TextAppearance

.
if (storedState.badgeTextColor != null) {
currentState.badgeTextColor = storedState.badgeTextColor;
} else if (a.hasValue(R.styleable.Badge_badgeTextColor)) {
Expand Down Expand Up @@ -170,6 +180,7 @@ public final class BadgeState {
// Set the offsets when the badge has text. Default to using the badge "dot" offsets
// (horizontalOffsetWithoutText and verticalOffsetWithoutText) if there is no offsets defined
// for badges with text.

currentState.horizontalOffsetWithText =
storedState.horizontalOffsetWithText == null
? a.getDimensionPixelOffset(
Expand Down Expand Up @@ -402,7 +413,6 @@ private static int readColorFromAttributes(
Context context, @NonNull TypedArray a, @StyleableRes int index) {
return MaterialResources.getColorStateList(context, a, index).getDefaultColor();
}

/**
* Internal {@link Parcelable} state used to represent, save, and restore {@link BadgeDrawable}
* states.
Expand Down Expand Up @@ -491,25 +501,36 @@ public int describeContents() {
}

@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeInt(badgeResId);
dest.writeSerializable(backgroundColor);
dest.writeSerializable(badgeTextColor);
dest.writeInt(alpha);
dest.writeInt(number);
dest.writeInt(maxCharacterCount);
public void writeToParcel(@NonNull Parcel dest, int flags)
{
dest.writeInt(badgeResId)
dest.writeSerializable(backgroundColor)
dest.writeSerializable(badgeTextColor)
dest.writeInt(alpha)
dest.writeInt(number)
dest.writeInt(maxCharacterCount)
dest.writeString(
contentDescriptionNumberless == null ? null : contentDescriptionNumberless.toString());
dest.writeInt(contentDescriptionQuantityStrings);
dest.writeSerializable(badgeGravity);
dest.writeSerializable(horizontalOffsetWithoutText);
dest.writeSerializable(verticalOffsetWithoutText);
dest.writeSerializable(horizontalOffsetWithText);
dest.writeSerializable(verticalOffsetWithText);
dest.writeSerializable(additionalHorizontalOffset);
dest.writeSerializable(additionalVerticalOffset);
dest.writeSerializable(isVisible);
dest.writeSerializable(numberLocale);
}
}
}

: contentDescriptionNumberless == null ? null

: contentDescriptionNumberless.toString());

dest.writeInt(contentDescriptionQuantityStrings
dest.writeSerializable(badgeGravity
dest.writeSerializable(horizontalOffsetWithoutText
dest.writeSerializable(verticalOffsetWithoutText
dest.writeSerializable(horizontalOffsetWithText
dest.writeSerializable(verticalOffsetWithText
dest.writeSerializable(additionalHorizontalOffset
dest.writeSerializable(additionalVerticalOffset
dest.writeSerializable(isVisible
dest.writeSerializable(numberLocale









Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/
package com.google.android.material.datepicker;

import static org.hamcrest.Matchers.is;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;

import android.os.Build.VERSION_CODES;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,14 @@
import androidx.appcompat.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.GridView;
import android.widget.TextView.BufferType;
import androidx.core.util.Pair;
import androidx.test.core.app.ApplicationProvider;
import com.google.android.material.internal.ParcelableTestUtils;
import com.google.android.material.textfield.TextInputLayout;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import org.junit.Assert;
import org.junit.Before;
Expand Down Expand Up @@ -81,12 +83,13 @@ public void textInputValid() {
@Test
public void textInputFormatError() {
View root = getRootView();
((ViewGroup) activity.findViewById(android.R.id.content)).addView(root);

TextInputLayout startTextInput = root.findViewById(R.id.mtrl_picker_text_input_range_start);
TextInputLayout endTextInput = root.findViewById(R.id.mtrl_picker_text_input_range_end);
startTextInput.getEditText().setText("22/22/2010", BufferType.EDITABLE);
endTextInput.getEditText().setText("555-555-5555", BufferType.EDITABLE);

activity.setContentView(root);
ShadowLooper.runUiThreadTasksIncludingDelayedTasks();

assertThat(startTextInput.getError()).isNotNull();
Expand Down Expand Up @@ -210,8 +213,12 @@ public void textInputHintValidWithPTLocale() {
activity.setContentView(root);
ShadowLooper.runUiThreadTasksIncludingDelayedTasks();

assertThat(startTextInput.getPlaceholderText().toString()).isEqualTo("dd-mm-aaaa");
assertThat(endTextInput.getPlaceholderText().toString()).isEqualTo("dd-mm-aaaa");
// Some JVMs format PT dates as dd-mm-aaaa, and some as dd/mm/aaaa. Derive the expected result
// programatically to account for the difference.
boolean slashDateFormat = new SimpleDateFormat().toLocalizedPattern().startsWith("dd/");
String expectedDateFormat = slashDateFormat ? "dd/mm/aaaa" : "dd-mm-aaaa";
assertThat(startTextInput.getPlaceholderText().toString()).isEqualTo(expectedDateFormat);
assertThat(endTextInput.getPlaceholderText().toString()).isEqualTo(expectedDateFormat);
}

private View getRootView() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@

import com.google.android.material.R;

import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.nullValue;
import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsNull.nullValue;
import static org.junit.Assert.assertThat;

import android.content.Context;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import com.google.android.material.R;

import static android.os.Build.VERSION_CODES.JELLY_BEAN;
import static com.google.common.truth.Truth.assertThat;

import android.content.Context;
Expand All @@ -31,6 +32,7 @@
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import org.robolectric.annotation.LooperMode;
import org.robolectric.annotation.internal.DoNotInstrument;
import org.robolectric.shadow.api.Shadow;
Expand All @@ -40,6 +42,7 @@
/** Tests for {@link com.google.android.material.snackbar.Snackbar}. */
@RunWith(RobolectricTestRunner.class)
@DoNotInstrument
@Config(sdk = JELLY_BEAN)
public class SnackbarTest {

private Snackbar snackbar;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@
import static com.google.android.material.testutils.TestUtilsActions.setTitle;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;

import android.graphics.Color;
import android.os.Build;
Expand Down Expand Up @@ -148,4 +150,14 @@ protected void assertAccessibilityHasScrollBackwardAction(boolean hasScrollBackw
equalTo(hasScrollBackward));
}
}

protected void assertAccessibilityScrollable(boolean isScrollable) {
AccessibilityNodeInfoCompat info = AccessibilityNodeInfoCompat.obtain();
ViewCompat.onInitializeAccessibilityNodeInfo(mCoordinatorLayout, info);
if (isScrollable) {
assertTrue(info.isScrollable());
} else {
assertFalse(info.isScrollable());
}
}
}
Loading