Merge "Fix BottomNavigationView example to use AAPT1 style." into nyc-support-25.1-dev
am: 2c0862c41c
Change-Id: I407d92ce766631aa56b1cda5924759ba9be97242
diff --git a/api/current.txt b/api/current.txt
index 6709b97..6e529c8 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -2040,6 +2040,7 @@
method public void setFadingEnabled(boolean);
method public void setHostCallback(android.support.v17.leanback.media.PlaybackGlueHost.HostCallback);
method public void setOnItemViewClickedListener(android.support.v17.leanback.widget.BaseOnItemViewClickedListener);
+ method public void setOnItemViewSelectedListener(android.support.v17.leanback.widget.BaseOnItemViewSelectedListener);
method public final void setOnKeyInterceptListener(android.view.View.OnKeyListener);
method public void setOnPlaybackItemViewClickedListener(android.support.v17.leanback.widget.BaseOnItemViewClickedListener);
method public void setPlaybackRow(android.support.v17.leanback.widget.Row);
@@ -2124,6 +2125,7 @@
method public void setFadingEnabled(boolean);
method public void setHostCallback(android.support.v17.leanback.media.PlaybackGlueHost.HostCallback);
method public void setOnItemViewClickedListener(android.support.v17.leanback.widget.BaseOnItemViewClickedListener);
+ method public void setOnItemViewSelectedListener(android.support.v17.leanback.widget.BaseOnItemViewSelectedListener);
method public final void setOnKeyInterceptListener(android.view.View.OnKeyListener);
method public void setOnPlaybackItemViewClickedListener(android.support.v17.leanback.widget.BaseOnItemViewClickedListener);
method public void setPlaybackRow(android.support.v17.leanback.widget.Row);
@@ -5264,6 +5266,10 @@
method public static int setAlphaComponent(int, int);
}
+ public final class PaintCompat {
+ method public static boolean hasGlyph(android.graphics.Paint, java.lang.String);
+ }
+
}
package android.support.v4.graphics.drawable {
diff --git a/build.gradle b/build.gradle
index ff9f772..8feee6d 100644
--- a/build.gradle
+++ b/build.gradle
@@ -24,7 +24,7 @@
}
dependencies {
// Keep gradle plugin version in sync with ub_supportlib-master manifest.
- classpath 'com.android.tools.build:gradle:2.2.1'
+ classpath 'com.android.tools.build:gradle:2.2.4'
}
}
@@ -40,8 +40,8 @@
doclava project(':doclava')
}
-ext.supportVersion = '25.2.0'
-ext.extraVersion = 43
+ext.supportVersion = '25.2.0-SNAPSHOT'
+ext.extraVersion = 41
ext.supportRepoOut = ''
ext.buildNumber = Integer.toString(ext.extraVersion)
@@ -163,6 +163,7 @@
Files.write(xml, new File(project.ext.distDir, 'repo-extras.xml'), Charsets.UTF_8)
}
createArchive.dependsOn createXml
+createXml.dependsOn createRepository
task(createSourceProp) << {
def sourceProp =
@@ -488,6 +489,14 @@
}
}
}
+
+ // Update the version meta-data in each Manifest
+ project.afterEvaluate { p ->
+ if (p.hasProperty('android')) {
+ p.android.defaultConfig.manifestPlaceholders =
+ ["support-version": rootProject.ext.supportVersion]
+ }
+ }
}
project.gradle.buildFinished { buildResult ->
diff --git a/compat/Android.mk b/compat/Android.mk
index ba5b958..97916ae 100644
--- a/compat/Android.mk
+++ b/compat/Android.mk
@@ -45,6 +45,7 @@
$(call all-java-files-under,java) \
$(call all-Iaidl-files-under,java)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+LOCAL_MANIFEST_FILE := AndroidManifest-make.xml
LOCAL_SHARED_ANDROID_LIBRARIES := \
android-support-annotations
LOCAL_JAR_EXCLUDE_FILES := none
diff --git a/compat/AndroidManifest-make.xml b/compat/AndroidManifest-make.xml
new file mode 100644
index 0000000..b2bd5bb
--- /dev/null
+++ b/compat/AndroidManifest-make.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ package="android.support.compat">
+ <uses-sdk android:minSdkVersion="9" tools:overrideLibrary="android.support.compat"/>
+ <application />
+</manifest>
diff --git a/compat/AndroidManifest.xml b/compat/AndroidManifest.xml
index b2bd5bb..55ddcff 100644
--- a/compat/AndroidManifest.xml
+++ b/compat/AndroidManifest.xml
@@ -17,5 +17,6 @@
xmlns:tools="http://schemas.android.com/tools"
package="android.support.compat">
<uses-sdk android:minSdkVersion="9" tools:overrideLibrary="android.support.compat"/>
+ <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
<application />
</manifest>
diff --git a/compat/api23/android/support/v4/graphics/PaintCompatApi23.java b/compat/api23/android/support/v4/graphics/PaintCompatApi23.java
new file mode 100644
index 0000000..c51f175
--- /dev/null
+++ b/compat/api23/android/support/v4/graphics/PaintCompatApi23.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+package android.support.v4.graphics;
+
+import android.graphics.Paint;
+import android.support.annotation.NonNull;
+import android.support.annotation.RequiresApi;
+
+@RequiresApi(23)
+class PaintCompatApi23 {
+ static boolean hasGlyph(@NonNull Paint paint, @NonNull String string) {
+ return paint.hasGlyph(string);
+ }
+}
diff --git a/compat/build.gradle b/compat/build.gradle
index 5722998..e87db0e 100644
--- a/compat/build.gradle
+++ b/compat/build.gradle
@@ -15,9 +15,6 @@
testCompile 'junit:junit:4.12'
}
-sourceCompatibility = JavaVersion.VERSION_1_7
-targetCompatibility = JavaVersion.VERSION_1_7
-
android {
compileSdkVersion project.ext.currentSdk
@@ -58,11 +55,7 @@
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
-
- testOptions {
- unitTests.returnDefaultValues = true
compileSdkVersion project.ext.currentSdk
- }
}
android.libraryVariants.all { variant ->
@@ -73,22 +66,6 @@
}
def suffix = name.capitalize()
- def jarTask = project.tasks.create(name: "jar${suffix}", type: Jar){
- dependsOn variant.javaCompile
- from variant.javaCompile.destinationDir
- from 'LICENSE.txt'
- }
- def javadocTask = project.tasks.create(name: "javadoc${suffix}", type: Javadoc) {
- source android.sourceSets.main.java
- classpath = files(variant.javaCompile.classpath.files) + files(
- "${android.sdkDirectory}/platforms/${android.compileSdkVersion}/android.jar")
- }
-
- def javadocJarTask = project.tasks.create(name: "javadocJar${suffix}", type: Jar) {
- classifier = 'javadoc'
- from 'build/docs/javadoc'
- }
-
def sourcesJarTask = project.tasks.create(name: "sourceJar${suffix}", type: Jar) {
classifier = 'sources'
from android.sourceSets.main.java.srcDirs
@@ -96,7 +73,6 @@
exclude('android/service/media/**')
}
- artifacts.add('archives', javadocJarTask);
artifacts.add('archives', sourcesJarTask);
}
diff --git a/compat/gingerbread/android/support/v4/graphics/PaintCompatGingerbread.java b/compat/gingerbread/android/support/v4/graphics/PaintCompatGingerbread.java
new file mode 100644
index 0000000..0d1076f
--- /dev/null
+++ b/compat/gingerbread/android/support/v4/graphics/PaintCompatGingerbread.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+package android.support.v4.graphics;
+
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.support.annotation.NonNull;
+import android.support.annotation.RequiresApi;
+import android.support.v4.util.Pair;
+
+@RequiresApi(9)
+class PaintCompatGingerbread {
+ // U+DFFFD which is very end of unassigned plane.
+ private static final String TOFU_STRING = "\uDB3F\uDFFD";
+
+ private static final ThreadLocal<Pair<Rect, Rect>> sRectThreadLocal = new ThreadLocal<>();
+
+ static boolean hasGlyph(@NonNull Paint paint, @NonNull String string) {
+ final int length = string.length();
+
+ if (length == 1 && Character.isWhitespace(string.charAt(0))) {
+ // measureText + getTextBounds skips whitespace so we need to special case it here
+ return true;
+ }
+
+ final float missingGlyphWidth = paint.measureText(TOFU_STRING);
+ final float width = paint.measureText(string);
+
+ if (width == 0f) {
+ // If the string width is 0, it can't be rendered
+ return false;
+ }
+
+ if (string.codePointCount(0, string.length()) > 1) {
+ // Heuristic to detect fallback glyphs for ligatures like flags and ZWJ sequences
+ // Return false if string is rendered too widely
+ if (width > 2 * missingGlyphWidth) {
+ return false;
+ }
+
+ // Heuristic to detect fallback glyphs for ligatures like flags and ZWJ sequences (2).
+ // If width is greater than or equal to the sum of width of each code point, it is very
+ // likely that the system is using fallback fonts to draw {@code string} in two or more
+ // glyphs instead of a single ligature glyph. (hasGlyph returns false in this case.)
+ // False detections are possible (the ligature glyph may happen to have the same width
+ // as the sum width), but there are no good way to avoid them.
+ // NOTE: This heuristic does not work with proportional glyphs.
+ // NOTE: This heuristic does not work when a ZWJ sequence is partially combined.
+ // E.g. If system has a glyph for "A ZWJ B" and not for "A ZWJ B ZWJ C", this heuristic
+ // returns true for "A ZWJ B ZWJ C".
+ float sumWidth = 0;
+ int i = 0;
+ while (i < length) {
+ int charCount = Character.charCount(string.codePointAt(i));
+ sumWidth += paint.measureText(string, i, i + charCount);
+ i += charCount;
+ }
+ if (width >= sumWidth) {
+ return false;
+ }
+ }
+
+ if (width != missingGlyphWidth) {
+ // If the widths are different then its not tofu
+ return true;
+ }
+
+ // If the widths are the same, lets check the bounds. The chance of them being
+ // different chars with the same bounds is extremely small
+ final Pair<Rect, Rect> rects = obtainEmptyRects();
+ paint.getTextBounds(TOFU_STRING, 0, TOFU_STRING.length(), rects.first);
+ paint.getTextBounds(string, 0, length, rects.second);
+ return !rects.first.equals(rects.second);
+ }
+
+ private static Pair<Rect, Rect> obtainEmptyRects() {
+ Pair<Rect, Rect> rects = sRectThreadLocal.get();
+ if (rects == null) {
+ rects = new Pair(new Rect(), new Rect());
+ sRectThreadLocal.set(rects);
+ } else {
+ rects.first.setEmpty();
+ rects.second.setEmpty();
+ }
+ return rects;
+ }
+}
diff --git a/compat/java/android/support/v4/app/NotificationCompat.java b/compat/java/android/support/v4/app/NotificationCompat.java
index 492d0fd..5d08191 100644
--- a/compat/java/android/support/v4/app/NotificationCompat.java
+++ b/compat/java/android/support/v4/app/NotificationCompat.java
@@ -17,6 +17,7 @@
package android.support.v4.app;
import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
import android.app.Activity;
import android.app.Notification;
@@ -30,6 +31,7 @@
import android.os.Bundle;
import android.os.Parcelable;
import android.support.annotation.ColorInt;
+import android.support.annotation.IntDef;
import android.support.annotation.NonNull;
import android.support.annotation.RestrictTo;
import android.support.v4.os.BuildCompat;
@@ -37,6 +39,7 @@
import android.view.Gravity;
import android.widget.RemoteViews;
+import java.lang.annotation.Retention;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -390,6 +393,10 @@
@ColorInt
public static final int COLOR_DEFAULT = Color.TRANSPARENT;
+ /** @hide */
+ @Retention(SOURCE)
+ @IntDef({VISIBILITY_PUBLIC, VISIBILITY_PRIVATE, VISIBILITY_SECRET})
+ public @interface NotificationVisibility {}
/**
* Notification visibility: Show this notification in its entirety on all lockscreens.
*
@@ -1665,7 +1672,7 @@
* {@link Notification#VISIBILITY_PUBLIC}, or
* {@link Notification#VISIBILITY_SECRET}.
*/
- public Builder setVisibility(int visibility) {
+ public Builder setVisibility(@NotificationVisibility int visibility) {
mVisibility = visibility;
return this;
}
@@ -2147,7 +2154,7 @@
public static MessagingStyle extractMessagingStyleFromNotification(Notification notif) {
MessagingStyle style;
Bundle extras = IMPL.getExtras(notif);
- if (!extras.containsKey(EXTRA_SELF_DISPLAY_NAME)) {
+ if (extras != null && !extras.containsKey(EXTRA_SELF_DISPLAY_NAME)) {
style = null;
} else {
try {
diff --git a/compat/java/android/support/v4/graphics/PaintCompat.java b/compat/java/android/support/v4/graphics/PaintCompat.java
new file mode 100644
index 0000000..66599f7
--- /dev/null
+++ b/compat/java/android/support/v4/graphics/PaintCompat.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+package android.support.v4.graphics;
+
+import android.graphics.Paint;
+import android.os.Build;
+import android.support.annotation.NonNull;
+
+/**
+ * Helper for accessing features in {@link Paint} in a backwards compatible fashion.
+ */
+public final class PaintCompat {
+
+ /**
+ * Determine whether the typeface set on the paint has a glyph supporting the
+ * string in a backwards compatible way.
+ *
+ * @param paint the paint instance to check
+ * @param string the string to test whether there is glyph support
+ * @return true if the typeface set on the given paint has a glyph for the string
+ */
+ public static boolean hasGlyph(@NonNull Paint paint, @NonNull String string) {
+ if (Build.VERSION.SDK_INT >= 23) {
+ return PaintCompatApi23.hasGlyph(paint, string);
+ }
+ return PaintCompatGingerbread.hasGlyph(paint, string);
+ }
+
+ private PaintCompat() {}
+}
diff --git a/compat/jellybean/android/support/v4/app/NotificationCompatJellybean.java b/compat/jellybean/android/support/v4/app/NotificationCompatJellybean.java
index fd873c7..c50e5f0 100644
--- a/compat/jellybean/android/support/v4/app/NotificationCompatJellybean.java
+++ b/compat/jellybean/android/support/v4/app/NotificationCompatJellybean.java
@@ -298,21 +298,24 @@
RemoteInputCompatBase.RemoteInput.Factory remoteInputFactory) {
synchronized (sActionsLock) {
try {
- Object actionObject = getActionObjectsLocked(notif)[actionIndex];
- Bundle actionExtras = null;
- Bundle extras = getExtras(notif);
- if (extras != null) {
- SparseArray<Bundle> actionExtrasMap = extras.getSparseParcelableArray(
- EXTRA_ACTION_EXTRAS);
- if (actionExtrasMap != null) {
- actionExtras = actionExtrasMap.get(actionIndex);
+ Object[] actionObjects = getActionObjectsLocked(notif);
+ if (actionObjects != null) {
+ Object actionObject = actionObjects[actionIndex];
+ Bundle actionExtras = null;
+ Bundle extras = getExtras(notif);
+ if (extras != null) {
+ SparseArray<Bundle> actionExtrasMap = extras.getSparseParcelableArray(
+ EXTRA_ACTION_EXTRAS);
+ if (actionExtrasMap != null) {
+ actionExtras = actionExtrasMap.get(actionIndex);
+ }
}
+ return readAction(factory, remoteInputFactory,
+ sActionIconField.getInt(actionObject),
+ (CharSequence) sActionTitleField.get(actionObject),
+ (PendingIntent) sActionIntentField.get(actionObject),
+ actionExtras);
}
- return readAction(factory, remoteInputFactory,
- sActionIconField.getInt(actionObject),
- (CharSequence) sActionTitleField.get(actionObject),
- (PendingIntent) sActionIntentField.get(actionObject),
- actionExtras);
} catch (IllegalAccessException e) {
Log.e(TAG, "Unable to access notification actions", e);
sActionsAccessFailed = true;
diff --git a/compat/tests/java/android/support/v4/graphics/PaintCompatHasGlyphTest.java b/compat/tests/java/android/support/v4/graphics/PaintCompatHasGlyphTest.java
new file mode 100644
index 0000000..202d30f
--- /dev/null
+++ b/compat/tests/java/android/support/v4/graphics/PaintCompatHasGlyphTest.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+package android.support.v4.graphics;
+
+import static org.junit.Assert.assertEquals;
+
+import android.graphics.Paint;
+import android.support.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+@RunWith(Parameterized.class)
+@SmallTest
+public class PaintCompatHasGlyphTest {
+
+ @Parameterized.Parameters
+ public static Collection<Object[]> data() {
+ return Arrays.asList(new Object[][]{
+ {"B", true},
+ {"\uDB3F\uDFFD", false},
+ {"☺", true},
+ {"Hello", false},
+ {"\u0020", true}, // white space
+ {"\t\t\t", false}, // more white space
+ });
+ }
+
+ private final String mTestString;
+ private final boolean mExpectedResult;
+
+ public PaintCompatHasGlyphTest(String testString, boolean expectedResult) {
+ mTestString = testString;
+ mExpectedResult = expectedResult;
+ }
+
+ @Test
+ public void testHasGlyph() {
+ assertEquals(mExpectedResult, PaintCompat.hasGlyph(new Paint(), mTestString));
+ }
+}
diff --git a/core-ui/Android.mk b/core-ui/Android.mk
index bdad9f9..eb9acca 100644
--- a/core-ui/Android.mk
+++ b/core-ui/Android.mk
@@ -33,6 +33,7 @@
$(call all-java-files-under,api21) \
$(call all-java-files-under,java)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+LOCAL_MANIFEST_FILE := AndroidManifest-make.xml
LOCAL_SHARED_ANDROID_LIBRARIES := \
android-support-compat \
android-support-annotations
diff --git a/core-ui/AndroidManifest-make.xml b/core-ui/AndroidManifest-make.xml
new file mode 100644
index 0000000..9bcc44e
--- /dev/null
+++ b/core-ui/AndroidManifest-make.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ package="android.support.coreui">
+ <uses-sdk android:minSdkVersion="9" tools:overrideLibrary="android.support.coreui"/>
+ <application />
+</manifest>
diff --git a/core-ui/AndroidManifest.xml b/core-ui/AndroidManifest.xml
index 9bcc44e..5357112 100644
--- a/core-ui/AndroidManifest.xml
+++ b/core-ui/AndroidManifest.xml
@@ -17,5 +17,6 @@
xmlns:tools="http://schemas.android.com/tools"
package="android.support.coreui">
<uses-sdk android:minSdkVersion="9" tools:overrideLibrary="android.support.coreui"/>
+ <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
<application />
</manifest>
diff --git a/core-ui/build.gradle b/core-ui/build.gradle
index 89796ea..0b94a96 100644
--- a/core-ui/build.gradle
+++ b/core-ui/build.gradle
@@ -16,9 +16,6 @@
testCompile 'junit:junit:4.12'
}
-sourceCompatibility = JavaVersion.VERSION_1_7
-targetCompatibility = JavaVersion.VERSION_1_7
-
android {
compileSdkVersion project.ext.currentSdk
@@ -54,7 +51,6 @@
testOptions {
unitTests.returnDefaultValues = true
- compileSdkVersion project.ext.currentSdk
}
}
@@ -66,22 +62,6 @@
}
def suffix = name.capitalize()
- def jarTask = project.tasks.create(name: "jar${suffix}", type: Jar){
- dependsOn variant.javaCompile
- from variant.javaCompile.destinationDir
- from 'LICENSE.txt'
- }
- def javadocTask = project.tasks.create(name: "javadoc${suffix}", type: Javadoc) {
- source android.sourceSets.main.java
- classpath = files(variant.javaCompile.classpath.files) + files(
- "${android.sdkDirectory}/platforms/${android.compileSdkVersion}/android.jar")
- }
-
- def javadocJarTask = project.tasks.create(name: "javadocJar${suffix}", type: Jar) {
- classifier = 'javadoc'
- from 'build/docs/javadoc'
- }
-
def sourcesJarTask = project.tasks.create(name: "sourceJar${suffix}", type: Jar) {
classifier = 'sources'
from android.sourceSets.main.java.srcDirs
@@ -89,7 +69,6 @@
exclude('android/service/media/**')
}
- artifacts.add('archives', javadocJarTask);
artifacts.add('archives', sourcesJarTask);
}
diff --git a/core-utils/Android.mk b/core-utils/Android.mk
index d3f113e..a65a2cd 100644
--- a/core-utils/Android.mk
+++ b/core-utils/Android.mk
@@ -37,6 +37,7 @@
$(call all-java-files-under,api24) \
$(call all-java-files-under,java)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+LOCAL_MANIFEST_FILE := AndroidManifest-make.xml
LOCAL_SHARED_ANDROID_LIBRARIES := \
android-support-compat \
android-support-annotations
diff --git a/core-utils/AndroidManifest-make.xml b/core-utils/AndroidManifest-make.xml
new file mode 100644
index 0000000..586a28e
--- /dev/null
+++ b/core-utils/AndroidManifest-make.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ package="android.support.coreutils">
+ <uses-sdk android:minSdkVersion="9" tools:overrideLibrary="android.support.coreutils"/>
+ <application />
+</manifest>
diff --git a/core-utils/AndroidManifest.xml b/core-utils/AndroidManifest.xml
index 586a28e..03ff3b4 100644
--- a/core-utils/AndroidManifest.xml
+++ b/core-utils/AndroidManifest.xml
@@ -17,5 +17,6 @@
xmlns:tools="http://schemas.android.com/tools"
package="android.support.coreutils">
<uses-sdk android:minSdkVersion="9" tools:overrideLibrary="android.support.coreutils"/>
+ <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
<application />
</manifest>
diff --git a/core-utils/build.gradle b/core-utils/build.gradle
index 750cf49..d40781d 100644
--- a/core-utils/build.gradle
+++ b/core-utils/build.gradle
@@ -48,11 +48,6 @@
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
-
- testOptions {
- unitTests.returnDefaultValues = true
- compileSdkVersion project.ext.currentSdk
- }
}
android.libraryVariants.all { variant ->
@@ -63,22 +58,6 @@
}
def suffix = name.capitalize()
- def jarTask = project.tasks.create(name: "jar${suffix}", type: Jar){
- dependsOn variant.javaCompile
- from variant.javaCompile.destinationDir
- from 'LICENSE.txt'
- }
- def javadocTask = project.tasks.create(name: "javadoc${suffix}", type: Javadoc) {
- source android.sourceSets.main.java
- classpath = files(variant.javaCompile.classpath.files) + files(
- "${android.sdkDirectory}/platforms/${android.compileSdkVersion}/android.jar")
- }
-
- def javadocJarTask = project.tasks.create(name: "javadocJar${suffix}", type: Jar) {
- classifier = 'javadoc'
- from 'build/docs/javadoc'
- }
-
def sourcesJarTask = project.tasks.create(name: "sourceJar${suffix}", type: Jar) {
classifier = 'sources'
from android.sourceSets.main.java.srcDirs
@@ -86,7 +65,6 @@
exclude('android/service/media/**')
}
- artifacts.add('archives', javadocJarTask);
artifacts.add('archives', sourcesJarTask);
}
diff --git a/customtabs/Android.mk b/customtabs/Android.mk
index cfd9971..e6f6ead 100644
--- a/customtabs/Android.mk
+++ b/customtabs/Android.mk
@@ -31,6 +31,7 @@
$(call all-java-files-under,src) \
$(call all-Iaidl-files-under,src)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+LOCAL_MANIFEST_FILE := AndroidManifest-make.xml
LOCAL_SHARED_ANDROID_LIBRARIES := \
android-support-annotations \
android-support-compat
diff --git a/customtabs/AndroidManifest-make.xml b/customtabs/AndroidManifest-make.xml
new file mode 100644
index 0000000..212fab9
--- /dev/null
+++ b/customtabs/AndroidManifest-make.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.support.customtabs">
+ <uses-sdk android:minSdkVersion="15"/>
+ <application />
+</manifest>
diff --git a/customtabs/AndroidManifest.xml b/customtabs/AndroidManifest.xml
index 212fab9..19a1d54 100644
--- a/customtabs/AndroidManifest.xml
+++ b/customtabs/AndroidManifest.xml
@@ -16,5 +16,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="android.support.customtabs">
<uses-sdk android:minSdkVersion="15"/>
+ <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
<application />
</manifest>
diff --git a/customtabs/build.gradle b/customtabs/build.gradle
index a409dba..e427d1e 100644
--- a/customtabs/build.gradle
+++ b/customtabs/build.gradle
@@ -1,5 +1,4 @@
apply plugin: 'com.android.library'
-
archivesBaseName = 'customtabs'
dependencies {
@@ -48,27 +47,10 @@
}
def suffix = name.capitalize()
- def jarTask = project.tasks.create(name: "jar${suffix}", type: Jar){
- dependsOn variant.javaCompile
- from variant.javaCompile.destinationDir
- from 'LICENSE.txt'
- }
- def javadocTask = project.tasks.create(name: "javadoc${suffix}", type: Javadoc) {
- source android.sourceSets.main.java
- classpath = files(variant.javaCompile.classpath.files) + files(
- "${android.sdkDirectory}/platforms/${android.compileSdkVersion}/android.jar")
- }
-
- def javadocJarTask = project.tasks.create(name: "javadocJar${suffix}", type: Jar) {
- classifier = 'javadoc'
- from 'build/docs/javadoc'
- }
-
def sourcesJarTask = project.tasks.create(name: "sourceJar${suffix}", type: Jar) {
classifier = 'sources'
from android.sourceSets.main.java.srcDirs
}
- artifacts.add('archives', javadocJarTask);
artifacts.add('archives', sourcesJarTask);
}
diff --git a/design/Android.mk b/design/Android.mk
index b3bc846..2e634eb 100644
--- a/design/Android.mk
+++ b/design/Android.mk
@@ -38,6 +38,7 @@
$(call all-java-files-under,lollipop) \
$(call all-java-files-under,src)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+LOCAL_MANIFEST_FILE := AndroidManifest-make.xml
LOCAL_SHARED_ANDROID_LIBRARIES := \
android-support-transition \
android-support-v7-appcompat \
diff --git a/design/AndroidManifest-make.xml b/design/AndroidManifest-make.xml
new file mode 100644
index 0000000..d51186d
--- /dev/null
+++ b/design/AndroidManifest-make.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ package="android.support.design">
+ <uses-sdk android:minSdkVersion="9"
+ tools:overrideLibrary="android.support.transition"/>
+ <application />
+</manifest>
diff --git a/design/AndroidManifest.xml b/design/AndroidManifest.xml
index d51186d..2d5fe0b 100644
--- a/design/AndroidManifest.xml
+++ b/design/AndroidManifest.xml
@@ -18,5 +18,6 @@
package="android.support.design">
<uses-sdk android:minSdkVersion="9"
tools:overrideLibrary="android.support.transition"/>
+ <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
<application />
</manifest>
diff --git a/design/build.gradle b/design/build.gradle
index abd99c0..37e6625 100644
--- a/design/build.gradle
+++ b/design/build.gradle
@@ -83,28 +83,11 @@
}
def suffix = name.capitalize()
- def jarTask = project.tasks.create(name: "jar${suffix}", type: Jar){
- dependsOn variant.javaCompile
- from variant.javaCompile.destinationDir
- from 'LICENSE.txt'
- }
- def javadocTask = project.tasks.create(name: "javadoc${suffix}", type: Javadoc) {
- source android.sourceSets.main.java
- classpath = files(variant.javaCompile.classpath.files) + files(
- "${android.sdkDirectory}/platforms/${android.compileSdkVersion}/android.jar")
- }
-
- def javadocJarTask = project.tasks.create(name: "javadocJar${suffix}", type: Jar) {
- classifier = 'javadoc'
- from 'build/docs/javadoc'
- }
-
def sourcesJarTask = project.tasks.create(name: "sourceJar${suffix}", type: Jar) {
classifier = 'sources'
from android.sourceSets.main.java.srcDirs
}
- artifacts.add('archives', javadocJarTask);
artifacts.add('archives', sourcesJarTask);
}
diff --git a/design/src/android/support/design/internal/BottomNavigationItemView.java b/design/src/android/support/design/internal/BottomNavigationItemView.java
index 44db0ea..ad05e76 100644
--- a/design/src/android/support/design/internal/BottomNavigationItemView.java
+++ b/design/src/android/support/design/internal/BottomNavigationItemView.java
@@ -122,6 +122,7 @@
public void setTitle(CharSequence title) {
mSmallLabel.setText(title);
mLargeLabel.setText(title);
+ setContentDescription(title);
}
@Override
diff --git a/design/src/android/support/design/internal/BottomNavigationMenuView.java b/design/src/android/support/design/internal/BottomNavigationMenuView.java
index 82d983e..92a9a84 100644
--- a/design/src/android/support/design/internal/BottomNavigationMenuView.java
+++ b/design/src/android/support/design/internal/BottomNavigationMenuView.java
@@ -31,6 +31,7 @@
import android.support.v7.view.menu.MenuItemImpl;
import android.support.v7.view.menu.MenuView;
import android.util.AttributeSet;
+import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
@@ -51,7 +52,8 @@
private boolean mShiftingMode = true;
private BottomNavigationItemView[] mButtons;
- private int mActiveButton = 0;
+ private int mSelectedItemId = 0;
+ private int mSelectedItemPosition = 0;
private ColorStateList mItemIconTint;
private ColorStateList mItemTextColor;
private int mItemBackgroundRes;
@@ -114,7 +116,7 @@
final int inactiveWidth = Math.min(inactiveMaxAvailable, mInactiveItemMaxWidth);
int extra = width - activeWidth - inactiveWidth * inactiveCount;
for (int i = 0; i < count; i++) {
- mTempChildWidths[i] = (i == mActiveButton) ? activeWidth : inactiveWidth;
+ mTempChildWidths[i] = (i == mSelectedItemPosition) ? activeWidth : inactiveWidth;
if (extra > 0) {
mTempChildWidths[i]++;
extra--;
@@ -275,8 +277,8 @@
child.setOnClickListener(mOnClickListener);
addView(child);
}
- mActiveButton = Math.min(mMenu.size() - 1, mActiveButton);
- mMenu.getItem(mActiveButton).setChecked(true);
+ mSelectedItemPosition = Math.min(mMenu.size() - 1, mSelectedItemPosition);
+ mMenu.getItem(mSelectedItemPosition).setChecked(true);
}
public void updateMenuView() {
@@ -288,22 +290,26 @@
}
for (int i = 0; i < menuSize; i++) {
mPresenter.setUpdateSuspended(true);
- if (mMenu.getItem(i).isChecked()) {
- mActiveButton = i;
+ MenuItem item = mMenu.getItem(i);
+ if (item.isChecked()) {
+ mSelectedItemId = item.getItemId();
+ mSelectedItemPosition = i;
}
- mButtons[i].initialize((MenuItemImpl) mMenu.getItem(i), 0);
+ mButtons[i].initialize((MenuItemImpl) item, 0);
mPresenter.setUpdateSuspended(false);
}
}
private void activateNewButton(int newButton) {
- if (mActiveButton == newButton) return;
+ if (mSelectedItemPosition == newButton) {
+ return;
+ }
mAnimationHelper.beginDelayedTransition(this);
mMenu.getItem(newButton).setChecked(true);
- mActiveButton = newButton;
+ mSelectedItemPosition = newButton;
}
private BottomNavigationItemView getNewItem() {
@@ -313,4 +319,21 @@
}
return item;
}
+
+ int getSelectedItemId() {
+ return mSelectedItemId;
+ }
+
+ void tryRestoreSelectedItemId(int itemId) {
+ final int size = mMenu.size();
+ for (int i = 0; i < size; i++) {
+ MenuItem item = mMenu.getItem(i);
+ if (itemId == item.getItemId()) {
+ mSelectedItemId = itemId;
+ mSelectedItemPosition = i;
+ item.setChecked(true);
+ break;
+ }
+ }
+ }
}
diff --git a/design/src/android/support/design/internal/BottomNavigationPresenter.java b/design/src/android/support/design/internal/BottomNavigationPresenter.java
index 832e936..1343a4b 100644
--- a/design/src/android/support/design/internal/BottomNavigationPresenter.java
+++ b/design/src/android/support/design/internal/BottomNavigationPresenter.java
@@ -19,7 +19,9 @@
import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
import android.content.Context;
+import android.os.Parcel;
import android.os.Parcelable;
+import android.support.annotation.NonNull;
import android.support.annotation.RestrictTo;
import android.support.v7.view.menu.MenuBuilder;
import android.support.v7.view.menu.MenuItemImpl;
@@ -36,6 +38,7 @@
private MenuBuilder mMenu;
private BottomNavigationMenuView mMenuView;
private boolean mUpdateSuspended = false;
+ private int mId;
public void setBottomNavigationMenuView(BottomNavigationMenuView menuView) {
mMenuView = menuView;
@@ -88,20 +91,62 @@
return false;
}
+ public void setId(int id) {
+ mId = id;
+ }
+
@Override
public int getId() {
- return -1;
+ return mId;
}
@Override
public Parcelable onSaveInstanceState() {
- return null;
+ SavedState savedState = new SavedState();
+ savedState.selectedItemId = mMenuView.getSelectedItemId();
+ return savedState;
}
@Override
- public void onRestoreInstanceState(Parcelable state) {}
+ public void onRestoreInstanceState(Parcelable state) {
+ if (state instanceof SavedState) {
+ mMenuView.tryRestoreSelectedItemId(((SavedState) state).selectedItemId);
+ }
+ }
public void setUpdateSuspended(boolean updateSuspended) {
mUpdateSuspended = updateSuspended;
}
+
+ static class SavedState implements Parcelable {
+ int selectedItemId;
+
+ SavedState() {}
+
+ SavedState(Parcel in) {
+ selectedItemId = in.readInt();
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel out, int flags) {
+ out.writeInt(selectedItemId);
+ }
+
+ public static final Creator<SavedState> CREATOR = new Creator<SavedState>() {
+ @Override
+ public SavedState createFromParcel(Parcel in) {
+ return new SavedState(in);
+ }
+
+ @Override
+ public SavedState[] newArray(int size) {
+ return new SavedState[size];
+ }
+ };
+ }
}
diff --git a/design/src/android/support/design/widget/AppBarLayout.java b/design/src/android/support/design/widget/AppBarLayout.java
index 4c7ef0a..ff41db8 100644
--- a/design/src/android/support/design/widget/AppBarLayout.java
+++ b/design/src/android/support/design/widget/AppBarLayout.java
@@ -111,6 +111,7 @@
static final int PENDING_ACTION_EXPANDED = 0x1;
static final int PENDING_ACTION_COLLAPSED = 0x2;
static final int PENDING_ACTION_ANIMATE_ENABLED = 0x4;
+ static final int PENDING_ACTION_FORCE = 0x8;
/**
* Interface definition for a callback to be invoked when an {@link AppBarLayout}'s vertical
@@ -172,7 +173,7 @@
0, R.style.Widget_Design_AppBarLayout);
ViewCompat.setBackground(this, a.getDrawable(R.styleable.AppBarLayout_android_background));
if (a.hasValue(R.styleable.AppBarLayout_expanded)) {
- setExpanded(a.getBoolean(R.styleable.AppBarLayout_expanded, false));
+ setExpanded(a.getBoolean(R.styleable.AppBarLayout_expanded, false), false, false);
}
if (Build.VERSION.SDK_INT >= 21 && a.hasValue(R.styleable.AppBarLayout_elevation)) {
ViewUtilsLollipop.setDefaultAppBarLayoutStateListAnimator(
@@ -299,8 +300,13 @@
* @attr ref android.support.design.R.styleable#AppBarLayout_expanded
*/
public void setExpanded(boolean expanded, boolean animate) {
+ setExpanded(expanded, animate, true);
+ }
+
+ private void setExpanded(boolean expanded, boolean animate, boolean force) {
mPendingAction = (expanded ? PENDING_ACTION_EXPANDED : PENDING_ACTION_COLLAPSED)
- | (animate ? PENDING_ACTION_ANIMATE_ENABLED : 0);
+ | (animate ? PENDING_ACTION_ANIMATE_ENABLED : 0)
+ | (force ? PENDING_ACTION_FORCE : 0);
requestLayout();
}
@@ -408,8 +414,8 @@
// Only enter by the amount of the collapsed height
range += childHeight - ViewCompat.getMinimumHeight(child);
} else {
- // Else use the full height
- range += childHeight;
+ // Else use the full height (minus the top inset)
+ range += childHeight - getTopInset();
}
} else if (range > 0) {
// If we've hit an non-quick return scrollable view, and we've already hit a
@@ -1048,8 +1054,21 @@
int layoutDirection) {
boolean handled = super.onLayoutChild(parent, abl, layoutDirection);
+ // The priority for for actions here is (first which is true wins):
+ // 1. forced pending actions
+ // 2. offsets for restorations
+ // 3. non-forced pending actions
final int pendingAction = abl.getPendingAction();
- if (pendingAction != PENDING_ACTION_NONE) {
+ if (mOffsetToChildIndexOnLayout >= 0 && (pendingAction & PENDING_ACTION_FORCE) == 0) {
+ View child = abl.getChildAt(mOffsetToChildIndexOnLayout);
+ int offset = -child.getBottom();
+ if (mOffsetToChildIndexOnLayoutIsMinHeight) {
+ offset += ViewCompat.getMinimumHeight(child) + abl.getTopInset();
+ } else {
+ offset += Math.round(child.getHeight() * mOffsetToChildIndexOnLayoutPerc);
+ }
+ setHeaderTopBottomOffset(parent, abl, offset);
+ } else if (pendingAction != PENDING_ACTION_NONE) {
final boolean animate = (pendingAction & PENDING_ACTION_ANIMATE_ENABLED) != 0;
if ((pendingAction & PENDING_ACTION_COLLAPSED) != 0) {
final int offset = -abl.getUpNestedPreScrollRange();
@@ -1065,15 +1084,6 @@
setHeaderTopBottomOffset(parent, abl, 0);
}
}
- } else if (mOffsetToChildIndexOnLayout >= 0) {
- View child = abl.getChildAt(mOffsetToChildIndexOnLayout);
- int offset = -child.getBottom();
- if (mOffsetToChildIndexOnLayoutIsMinHeight) {
- offset += ViewCompat.getMinimumHeight(child);
- } else {
- offset += Math.round(child.getHeight() * mOffsetToChildIndexOnLayoutPerc);
- }
- setTopAndBottomOffset(offset);
}
// Finally reset any pending states
@@ -1085,6 +1095,11 @@
setTopAndBottomOffset(
MathUtils.constrain(getTopAndBottomOffset(), -abl.getTotalScrollRange(), 0));
+ // Update the AppBarLayout's drawable state for any elevation changes.
+ // This is needed so that the elevation is set in the first layout, so that
+ // we don't get a visual elevation jump pre-N (due to the draw dispatch skip)
+ updateAppBarLayoutDrawableState(parent, abl, getTopAndBottomOffset(), 0, true);
+
// Make sure we dispatch the offset update
abl.dispatchOffsetUpdates(getTopAndBottomOffset());
@@ -1161,7 +1176,7 @@
// Update the AppBarLayout's drawable state (for any elevation changes)
updateAppBarLayoutDrawableState(coordinatorLayout, appBarLayout, newOffset,
- newOffset < curOffset ? -1 : 1);
+ newOffset < curOffset ? -1 : 1, false);
}
} else {
// Reset the offset delta
@@ -1224,7 +1239,8 @@
}
private void updateAppBarLayoutDrawableState(final CoordinatorLayout parent,
- final AppBarLayout layout, final int offset, final int direction) {
+ final AppBarLayout layout, final int offset, final int direction,
+ final boolean forceJump) {
final View child = getAppBarChildOnOffset(layout, offset);
if (child != null) {
final AppBarLayout.LayoutParams childLp = (LayoutParams) child.getLayoutParams();
@@ -1248,8 +1264,8 @@
final boolean changed = layout.setCollapsedState(collapsed);
- if (changed && Build.VERSION.SDK_INT >= 11
- && shouldJumpElevationState(parent, layout)) {
+ if (Build.VERSION.SDK_INT >= 11 && (forceJump
+ || (changed && shouldJumpElevationState(parent, layout)))) {
// If the collapsed state changed, we may need to
// jump to the current state if we have an overlapping view
layout.jumpDrawablesToCurrentState();
diff --git a/design/src/android/support/design/widget/BaseTransientBottomBar.java b/design/src/android/support/design/widget/BaseTransientBottomBar.java
index 864417d..9035f82 100644
--- a/design/src/android/support/design/widget/BaseTransientBottomBar.java
+++ b/design/src/android/support/design/widget/BaseTransientBottomBar.java
@@ -28,7 +28,6 @@
import android.support.annotation.IntDef;
import android.support.annotation.IntRange;
import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
import android.support.annotation.RestrictTo;
import android.support.design.R;
import android.support.v4.view.ViewCompat;
@@ -418,12 +417,13 @@
switch (state) {
case SwipeDismissBehavior.STATE_DRAGGING:
case SwipeDismissBehavior.STATE_SETTLING:
- // If the view is being dragged or settling, cancel the timeout
- SnackbarManager.getInstance().cancelTimeout(mManagerCallback);
+ // If the view is being dragged or settling, pause the timeout
+ SnackbarManager.getInstance().pauseTimeout(mManagerCallback);
break;
case SwipeDismissBehavior.STATE_IDLE:
// If the view has been released and is idle, restore the timeout
- SnackbarManager.getInstance().restoreTimeout(mManagerCallback);
+ SnackbarManager.getInstance()
+ .restoreTimeoutIfPaused(mManagerCallback);
break;
}
}
@@ -688,20 +688,20 @@
@Override
public boolean onInterceptTouchEvent(CoordinatorLayout parent, SnackbarBaseLayout child,
MotionEvent event) {
- // We want to make sure that we disable any Snackbar timeouts if the user is
- // currently touching the Snackbar. We restore the timeout when complete
- if (parent.isPointInChildBounds(child, (int) event.getX(), (int) event.getY())) {
- switch (event.getActionMasked()) {
- case MotionEvent.ACTION_DOWN:
- SnackbarManager.getInstance().cancelTimeout(mManagerCallback);
- break;
- case MotionEvent.ACTION_UP:
- case MotionEvent.ACTION_CANCEL:
- SnackbarManager.getInstance().restoreTimeout(mManagerCallback);
- break;
- }
+ switch (event.getActionMasked()) {
+ case MotionEvent.ACTION_DOWN:
+ // We want to make sure that we disable any Snackbar timeouts if the user is
+ // currently touching the Snackbar. We restore the timeout when complete
+ if (parent.isPointInChildBounds(child, (int) event.getX(),
+ (int) event.getY())) {
+ SnackbarManager.getInstance().pauseTimeout(mManagerCallback);
+ }
+ break;
+ case MotionEvent.ACTION_UP:
+ case MotionEvent.ACTION_CANCEL:
+ SnackbarManager.getInstance().restoreTimeoutIfPaused(mManagerCallback);
+ break;
}
-
return super.onInterceptTouchEvent(parent, child, event);
}
}
diff --git a/design/src/android/support/design/widget/BottomNavigationView.java b/design/src/android/support/design/widget/BottomNavigationView.java
index 3544d81..317ed3f 100644
--- a/design/src/android/support/design/widget/BottomNavigationView.java
+++ b/design/src/android/support/design/widget/BottomNavigationView.java
@@ -19,6 +19,9 @@
import android.content.Context;
import android.content.res.ColorStateList;
import android.os.Build;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
import android.support.annotation.DrawableRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
@@ -27,6 +30,9 @@
import android.support.design.internal.BottomNavigationMenuView;
import android.support.design.internal.BottomNavigationPresenter;
import android.support.v4.content.ContextCompat;
+import android.support.v4.os.ParcelableCompat;
+import android.support.v4.os.ParcelableCompatCreatorCallbacks;
+import android.support.v4.view.AbsSavedState;
import android.support.v4.view.ViewCompat;
import android.support.v7.content.res.AppCompatResources;
import android.support.v7.view.SupportMenuInflater;
@@ -91,6 +97,8 @@
private static final int[] CHECKED_STATE_SET = {android.R.attr.state_checked};
private static final int[] DISABLED_STATE_SET = {-android.R.attr.state_enabled};
+ private static final int MENU_PRESENTER_ID = 1;
+
private final MenuBuilder mMenu;
private final BottomNavigationMenuView mMenuView;
private final BottomNavigationPresenter mPresenter = new BottomNavigationPresenter();
@@ -121,6 +129,7 @@
mMenuView.setLayoutParams(params);
mPresenter.setBottomNavigationMenuView(mMenuView);
+ mPresenter.setId(MENU_PRESENTER_ID);
mMenuView.setPresenter(mPresenter);
mMenu.addMenuPresenter(mPresenter);
mPresenter.initForMenu(getContext(), mMenu);
@@ -344,4 +353,60 @@
defaultColor
});
}
+
+ @Override
+ protected Parcelable onSaveInstanceState() {
+ Parcelable superState = super.onSaveInstanceState();
+ SavedState savedState = new SavedState(superState);
+ savedState.menuPresenterState = new Bundle();
+ mMenu.savePresenterStates(savedState.menuPresenterState);
+ return savedState;
+ }
+
+ @Override
+ protected void onRestoreInstanceState(Parcelable state) {
+ if (!(state instanceof SavedState)) {
+ super.onRestoreInstanceState(state);
+ return;
+ }
+ SavedState savedState = (SavedState) state;
+ super.onRestoreInstanceState(savedState.getSuperState());
+ mMenu.restorePresenterStates(savedState.menuPresenterState);
+ }
+
+ static class SavedState extends AbsSavedState {
+ Bundle menuPresenterState;
+
+ public SavedState(Parcelable superState) {
+ super(superState);
+ }
+
+ public SavedState(Parcel source, ClassLoader loader) {
+ super(source, loader);
+ readFromParcel(source, loader);
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel out, int flags) {
+ super.writeToParcel(out, flags);
+ out.writeBundle(menuPresenterState);
+ }
+
+ private void readFromParcel(Parcel in, ClassLoader loader) {
+ menuPresenterState = in.readBundle(loader);
+ }
+
+ public static final Creator<SavedState> CREATOR =
+ ParcelableCompat.newCreator(new ParcelableCompatCreatorCallbacks<SavedState>() {
+ @Override
+ public SavedState createFromParcel(Parcel in, ClassLoader loader) {
+ return new SavedState(in, loader);
+ }
+
+ @Override
+ public SavedState[] newArray(int size) {
+ return new SavedState[size];
+ }
+ });
+ }
}
diff --git a/design/src/android/support/design/widget/BottomSheetDialog.java b/design/src/android/support/design/widget/BottomSheetDialog.java
index de48937..c5fccb0 100644
--- a/design/src/android/support/design/widget/BottomSheetDialog.java
+++ b/design/src/android/support/design/widget/BottomSheetDialog.java
@@ -97,6 +97,14 @@
}
@Override
+ protected void onStart() {
+ super.onStart();
+ if (mBehavior != null) {
+ mBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
+ }
+ }
+
+ @Override
public void setCanceledOnTouchOutside(boolean cancel) {
super.setCanceledOnTouchOutside(cancel);
if (cancel && !mCancelable) {
diff --git a/design/src/android/support/design/widget/CoordinatorLayout.java b/design/src/android/support/design/widget/CoordinatorLayout.java
index bac67f9..e0ec883 100644
--- a/design/src/android/support/design/widget/CoordinatorLayout.java
+++ b/design/src/android/support/design/widget/CoordinatorLayout.java
@@ -1171,11 +1171,18 @@
}
/**
- * Return the given gravity value or the default if the passed value is NO_GRAVITY.
- * This should be used for children that are not anchored to another view or a keyline.
+ * Return the given gravity value, but if either or both of the axes doesn't have any gravity
+ * specified, the default value (start or top) is specified. This should be used for children
+ * that are not anchored to another view or a keyline.
*/
private static int resolveGravity(int gravity) {
- return gravity == Gravity.NO_GRAVITY ? GravityCompat.START | Gravity.TOP : gravity;
+ if ((gravity & Gravity.HORIZONTAL_GRAVITY_MASK) == Gravity.NO_GRAVITY) {
+ gravity |= GravityCompat.START;
+ }
+ if ((gravity & Gravity.VERTICAL_GRAVITY_MASK) == Gravity.NO_GRAVITY) {
+ gravity |= Gravity.TOP;
+ }
+ return gravity;
}
/**
@@ -1293,7 +1300,7 @@
offsetChildByInset(child, inset, layoutDirection);
}
- if (type == EVENT_PRE_DRAW) {
+ if (type != EVENT_VIEW_REMOVED) {
// Did it change? if not continue
getLastChildRect(child, lastDrawRect);
if (lastDrawRect.equals(drawRect)) {
@@ -2560,8 +2567,10 @@
/**
* A {@link Gravity} value describing how this child view should lay out.
- * If an {@link #setAnchorId(int) anchor} is also specified, the gravity describes
- * how this child view should be positioned relative to its anchored position.
+ * If either or both of the axes are not specified, they are treated by CoordinatorLayout
+ * as {@link Gravity#TOP} or {@link GravityCompat#START}. If an
+ * {@link #setAnchorId(int) anchor} is also specified, the gravity describes how this child
+ * view should be positioned relative to its anchored position.
*/
public int gravity = Gravity.NO_GRAVITY;
diff --git a/design/src/android/support/design/widget/Snackbar.java b/design/src/android/support/design/widget/Snackbar.java
index a096a3d..bd5ffba 100644
--- a/design/src/android/support/design/widget/Snackbar.java
+++ b/design/src/android/support/design/widget/Snackbar.java
@@ -133,6 +133,11 @@
public static Snackbar make(@NonNull View view, @NonNull CharSequence text,
@Duration int duration) {
final ViewGroup parent = findSuitableParent(view);
+ if (parent == null) {
+ throw new IllegalArgumentException("No suitable parent found from the given view. "
+ + "Please provide a valid view.");
+ }
+
final LayoutInflater inflater = LayoutInflater.from(parent.getContext());
final SnackbarContentLayout content =
(SnackbarContentLayout) inflater.inflate(
@@ -324,6 +329,25 @@
public SnackbarLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ // Work around our backwards-compatible refactoring of Snackbar and inner content
+ // being inflated against snackbar's parent (instead of against the snackbar itself).
+ // Every child that is width=MATCH_PARENT is remeasured again and given the full width
+ // minus the paddings.
+ int childCount = getChildCount();
+ int availableWidth = getMeasuredWidth() - getPaddingLeft() - getPaddingRight();
+ for (int i = 0; i < childCount; i++) {
+ View child = getChildAt(i);
+ if (child.getLayoutParams().width == ViewGroup.LayoutParams.MATCH_PARENT) {
+ child.measure(MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.EXACTLY),
+ MeasureSpec.makeMeasureSpec(child.getMeasuredHeight(),
+ MeasureSpec.EXACTLY));
+ }
+ }
+ }
}
}
diff --git a/design/src/android/support/design/widget/SnackbarManager.java b/design/src/android/support/design/widget/SnackbarManager.java
index b391a3a..43892d3 100644
--- a/design/src/android/support/design/widget/SnackbarManager.java
+++ b/design/src/android/support/design/widget/SnackbarManager.java
@@ -137,17 +137,19 @@
}
}
- public void cancelTimeout(Callback callback) {
+ public void pauseTimeout(Callback callback) {
synchronized (mLock) {
- if (isCurrentSnackbarLocked(callback)) {
+ if (isCurrentSnackbarLocked(callback) && !mCurrentSnackbar.paused) {
+ mCurrentSnackbar.paused = true;
mHandler.removeCallbacksAndMessages(mCurrentSnackbar);
}
}
}
- public void restoreTimeout(Callback callback) {
+ public void restoreTimeoutIfPaused(Callback callback) {
synchronized (mLock) {
- if (isCurrentSnackbarLocked(callback)) {
+ if (isCurrentSnackbarLocked(callback) && mCurrentSnackbar.paused) {
+ mCurrentSnackbar.paused = false;
scheduleTimeoutLocked(mCurrentSnackbar);
}
}
@@ -168,6 +170,7 @@
private static class SnackbarRecord {
final WeakReference<Callback> callback;
int duration;
+ boolean paused;
SnackbarRecord(int duration, Callback callback) {
this.callback = new WeakReference<>(callback);
diff --git a/design/src/android/support/design/widget/TextInputLayout.java b/design/src/android/support/design/widget/TextInputLayout.java
index 22f4546..10da563 100644
--- a/design/src/android/support/design/widget/TextInputLayout.java
+++ b/design/src/android/support/design/widget/TextInputLayout.java
@@ -201,8 +201,6 @@
mCollapsingTextHelper.setPositionInterpolator(new AccelerateInterpolator());
mCollapsingTextHelper.setCollapsedTextGravity(Gravity.TOP | GravityCompat.START);
- mHintExpanded = mCollapsingTextHelper.getExpansionFraction() == 1f;
-
final TintTypedArray a = TintTypedArray.obtainStyledAttributes(context, attrs,
R.styleable.TextInputLayout, defStyleAttr, R.style.Widget_Design_TextInputLayout);
mHintEnabled = a.getBoolean(R.styleable.TextInputLayout_hintEnabled, true);
@@ -380,8 +378,8 @@
updatePasswordToggleView();
- // Update the label visibility with no animation
- updateLabelState(false);
+ // Update the label visibility with no animation, but force a state change
+ updateLabelState(false, true);
}
private void updateInputLayoutMargins() {
@@ -408,6 +406,10 @@
}
void updateLabelState(boolean animate) {
+ updateLabelState(animate, false);
+ }
+
+ void updateLabelState(final boolean animate, final boolean force) {
final boolean isEnabled = isEnabled();
final boolean hasText = mEditText != null && !TextUtils.isEmpty(mEditText.getText());
final boolean isFocused = arrayContains(getDrawableState(), android.R.attr.state_focused);
@@ -427,12 +429,12 @@
if (hasText || (isEnabled() && (isFocused || isErrorShowing))) {
// We should be showing the label so do so if it isn't already
- if (mHintExpanded) {
+ if (force || mHintExpanded) {
collapseHint(animate);
}
} else {
// We should not be showing the label so hide it
- if (!mHintExpanded) {
+ if (force || !mHintExpanded) {
expandHint(animate);
}
}
diff --git a/design/tests/AndroidManifest.xml b/design/tests/AndroidManifest.xml
index 29d46e0..886540d 100755
--- a/design/tests/AndroidManifest.xml
+++ b/design/tests/AndroidManifest.xml
@@ -88,6 +88,10 @@
<activity
android:name="android.support.v7.app.AppCompatActivity"/>
+ <activity
+ android:name="android.support.design.widget.AppBarLayoutCollapsePinTestActivity"
+ android:theme="@style/Theme.TranslucentStatus"/>
+
</application>
<instrumentation
diff --git a/design/tests/res/layout/design_appbar_toolbar_collapse_pin_restore_test.xml b/design/tests/res/layout/design_appbar_toolbar_collapse_pin_restore_test.xml
new file mode 100644
index 0000000..fbe031b
--- /dev/null
+++ b/design/tests/res/layout/design_appbar_toolbar_collapse_pin_restore_test.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2016 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.
+-->
+
+<android.support.design.widget.CoordinatorLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:id="@+id/coordinator_layout"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:fitsSystemWindows="true">
+
+ <android.support.design.widget.AppBarLayout
+ android:id="@+id/app_bar"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/appbar_height"
+ android:fitsSystemWindows="true"
+ app:expanded="true">
+
+ <android.support.design.widget.CollapsingToolbarLayout
+ android:id="@+id/collapsing_app_bar"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ app:layout_scrollFlags="scroll|exitUntilCollapsed">
+
+ <android.support.v7.widget.Toolbar
+ android:id="@+id/toolbar"
+ android:layout_height="?attr/actionBarSize"
+ android:layout_width="match_parent"
+ app:layout_collapseMode="pin"/>
+
+ </android.support.design.widget.CollapsingToolbarLayout>
+
+ </android.support.design.widget.AppBarLayout>
+
+ <include layout="@layout/include_appbar_scrollview" />
+
+</android.support.design.widget.CoordinatorLayout>
diff --git a/design/tests/res/layout/design_appbar_toolbar_collapse_scroll_enteralways.xml b/design/tests/res/layout/design_appbar_toolbar_collapse_scroll_enteralways.xml
new file mode 100644
index 0000000..43a8d51
--- /dev/null
+++ b/design/tests/res/layout/design_appbar_toolbar_collapse_scroll_enteralways.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2017 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.
+-->
+
+<android.support.design.widget.CoordinatorLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:fitsSystemWindows="true">
+
+ <android.support.design.widget.AppBarLayout
+ android:id="@+id/app_bar"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/appbar_height"
+ android:fitsSystemWindows="true">
+
+ <android.support.design.widget.CollapsingToolbarLayout
+ android:id="@+id/collapsing_app_bar"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ app:layout_scrollFlags="scroll|enterAlways">
+
+ <android.support.v7.widget.Toolbar
+ android:id="@+id/toolbar"
+ android:layout_height="?attr/actionBarSize"
+ android:layout_width="match_parent"
+ app:layout_collapseMode="pin"/>
+
+ </android.support.design.widget.CollapsingToolbarLayout>
+
+ </android.support.design.widget.AppBarLayout>
+
+ <include layout="@layout/include_appbar_scrollview" />
+
+</android.support.design.widget.CoordinatorLayout>
diff --git a/design/tests/res/layout/design_text_input.xml b/design/tests/res/layout/design_text_input.xml
index f4bd1d1..4dba825 100644
--- a/design/tests/res/layout/design_text_input.xml
+++ b/design/tests/res/layout/design_text_input.xml
@@ -58,4 +58,18 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
+ <android.support.design.widget.TextInputLayout
+ android:id="@+id/textinput_with_text"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <android.support.design.widget.TextInputEditText
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:imeOptions="flagNoExtractUi"
+ android:hint="@string/textinput_hint"
+ android:text="@string/snackbar_text"/>
+
+ </android.support.design.widget.TextInputLayout>
+
</LinearLayout>
\ No newline at end of file
diff --git a/design/tests/src/android/support/design/testutils/AppBarLayoutMatchers.java b/design/tests/src/android/support/design/testutils/AppBarLayoutMatchers.java
new file mode 100755
index 0000000..4d6fc63
--- /dev/null
+++ b/design/tests/src/android/support/design/testutils/AppBarLayoutMatchers.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+package android.support.design.testutils;
+
+import android.support.design.widget.AppBarLayout;
+
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeMatcher;
+
+public class AppBarLayoutMatchers {
+
+ /**
+ * Returns a matcher that matches AppBarLayouts which are collapsed.
+ */
+ public static Matcher isCollapsed() {
+ return new TypeSafeMatcher<AppBarLayout>() {
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("AppBarLayout is collapsed");
+ }
+
+ @Override
+ protected boolean matchesSafely(AppBarLayout item) {
+ return item.getBottom() == (item.getHeight() - item.getTotalScrollRange());
+ }
+ };
+ }
+
+}
diff --git a/design/tests/src/android/support/design/testutils/SwipeUtils.java b/design/tests/src/android/support/design/testutils/SwipeUtils.java
new file mode 100644
index 0000000..cf92883
--- /dev/null
+++ b/design/tests/src/android/support/design/testutils/SwipeUtils.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+package android.support.design.testutils;
+
+import android.support.test.espresso.action.CoordinatesProvider;
+import android.support.test.espresso.action.GeneralSwipeAction;
+import android.support.test.espresso.action.Press;
+import android.support.test.espresso.action.Swipe;
+import android.view.View;
+
+public class SwipeUtils {
+
+ public static GeneralSwipeAction swipeUp(final int swipeX,
+ final int swipeStartY, final int swipeAmountY) {
+ return new GeneralSwipeAction(
+ Swipe.SLOW,
+ new CoordinatesProvider() {
+ @Override
+ public float[] calculateCoordinates(View view) {
+ return new float[] { swipeX, swipeStartY };
+ }
+ },
+ new CoordinatesProvider() {
+ @Override
+ public float[] calculateCoordinates(View view) {
+ return new float[] { swipeX, swipeStartY - swipeAmountY };
+ }
+ },
+ Press.FINGER
+ );
+ }
+
+ public static GeneralSwipeAction swipeDown(final int swipeX,
+ final int swipeStartY, final int swipeAmountY) {
+ return new GeneralSwipeAction(
+ Swipe.SLOW,
+ new CoordinatesProvider() {
+ @Override
+ public float[] calculateCoordinates(View view) {
+ return new float[] { swipeX, swipeStartY };
+ }
+ },
+ new CoordinatesProvider() {
+ @Override
+ public float[] calculateCoordinates(View view) {
+ return new float[] { swipeX, swipeStartY + swipeAmountY };
+ }
+ },
+ Press.FINGER
+ );
+ }
+
+
+}
diff --git a/design/tests/src/android/support/design/testutils/TestUtils.java b/design/tests/src/android/support/design/testutils/TestUtils.java
index b9aae7a..2f9187d 100644
--- a/design/tests/src/android/support/design/testutils/TestUtils.java
+++ b/design/tests/src/android/support/design/testutils/TestUtils.java
@@ -16,7 +16,10 @@
package android.support.design.testutils;
+import android.app.Activity;
import android.content.Context;
+import android.content.pm.ActivityInfo;
+import android.content.res.Configuration;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
@@ -124,4 +127,20 @@
}
}
}
+
+ /**
+ * Rotates the given Activity to either portrait or landscape, depending on the current
+ * orientation.
+ */
+ public static void rotateOrientation(@NonNull Activity activity) {
+ switch (activity.getResources().getConfiguration().orientation) {
+ case Configuration.ORIENTATION_PORTRAIT:
+ activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
+ break;
+ case Configuration.ORIENTATION_LANDSCAPE:
+ default:
+ activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
+ break;
+ }
+ }
}
\ No newline at end of file
diff --git a/design/tests/src/android/support/design/testutils/TestUtilsMatchers.java b/design/tests/src/android/support/design/testutils/TestUtilsMatchers.java
index 2f1f30d..9d13ce7 100644
--- a/design/tests/src/android/support/design/testutils/TestUtilsMatchers.java
+++ b/design/tests/src/android/support/design/testutils/TestUtilsMatchers.java
@@ -22,6 +22,7 @@
import android.graphics.Rect;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
+import android.os.Build;
import android.support.annotation.ColorInt;
import android.support.annotation.NonNull;
import android.support.design.widget.FloatingActionButton;
@@ -461,6 +462,24 @@
}
/**
+ * Returns a matcher that matches views which have a z-value greater than 0. Also matches if
+ * the platform we're running on does not support z-values.
+ */
+ public static Matcher<View> hasZ() {
+ return new TypeSafeMatcher<View>() {
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("has a z value greater than 0");
+ }
+
+ @Override
+ public boolean matchesSafely(View view) {
+ return Build.VERSION.SDK_INT < 21 || ViewCompat.getZ(view) > 0f;
+ }
+ };
+ }
+
+ /**
* Returns a matcher that matches TextViews with the specified typeface.
*/
public static Matcher withTypeface(@NonNull final Typeface typeface) {
diff --git a/design/tests/src/android/support/design/widget/AppBarLayoutBaseTest.java b/design/tests/src/android/support/design/widget/AppBarLayoutBaseTest.java
index fc131a4..6fd4470 100644
--- a/design/tests/src/android/support/design/widget/AppBarLayoutBaseTest.java
+++ b/design/tests/src/android/support/design/widget/AppBarLayoutBaseTest.java
@@ -17,6 +17,8 @@
package android.support.design.widget;
import static android.support.design.testutils.CollapsingToolbarLayoutActions.setContentScrimColor;
+import static android.support.design.testutils.SwipeUtils.swipeDown;
+import static android.support.design.testutils.SwipeUtils.swipeUp;
import static android.support.design.testutils.TestUtilsActions.setText;
import static android.support.design.testutils.TestUtilsActions.setTitle;
import static android.support.test.espresso.Espresso.onView;
@@ -35,15 +37,10 @@
import android.support.annotation.StringRes;
import android.support.design.test.R;
import android.support.design.testutils.Shakespeare;
-import android.support.test.espresso.action.CoordinatesProvider;
-import android.support.test.espresso.action.GeneralSwipeAction;
-import android.support.test.espresso.action.Press;
-import android.support.test.espresso.action.Swipe;
import android.support.v4.view.ViewCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
-import android.view.View;
import android.widget.TextView;
import org.hamcrest.Description;
@@ -64,38 +61,12 @@
protected static void performVerticalSwipeUpGesture(@IdRes int containerId, final int swipeX,
final int swipeStartY, final int swipeAmountY) {
- onView(withId(containerId)).perform(new GeneralSwipeAction(
- Swipe.SLOW,
- new CoordinatesProvider() {
- @Override
- public float[] calculateCoordinates(View view) {
- return new float[] { swipeX, swipeStartY };
- }
- },
- new CoordinatesProvider() {
- @Override
- public float[] calculateCoordinates(View view) {
- return new float[] { swipeX, swipeStartY - swipeAmountY };
- }
- }, Press.FINGER));
+ onView(withId(containerId)).perform(swipeUp(swipeX, swipeStartY, swipeAmountY));
}
protected static void performVerticalSwipeDownGesture(@IdRes int containerId, final int swipeX,
final int swipeStartY, final int swipeAmountY) {
- onView(withId(containerId)).perform(new GeneralSwipeAction(
- Swipe.SLOW,
- new CoordinatesProvider() {
- @Override
- public float[] calculateCoordinates(View view) {
- return new float[] { swipeX, swipeStartY };
- }
- },
- new CoordinatesProvider() {
- @Override
- public float[] calculateCoordinates(View view) {
- return new float[] { swipeX, swipeStartY + swipeAmountY };
- }
- }, Press.FINGER));
+ onView(withId(containerId)).perform(swipeDown(swipeX, swipeStartY, swipeAmountY));
}
@CallSuper
diff --git a/design/tests/src/android/support/design/widget/AppBarLayoutCollapsePinTestActivity.java b/design/tests/src/android/support/design/widget/AppBarLayoutCollapsePinTestActivity.java
new file mode 100644
index 0000000..38ea4fc
--- /dev/null
+++ b/design/tests/src/android/support/design/widget/AppBarLayoutCollapsePinTestActivity.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+package android.support.design.widget;
+
+import android.support.design.test.R;
+import android.support.v7.widget.Toolbar;
+
+public class AppBarLayoutCollapsePinTestActivity extends BaseTestActivity {
+
+ @Override
+ protected int getContentViewLayoutResId() {
+ return R.layout.design_appbar_toolbar_collapse_pin_restore_test;
+ }
+
+ @Override
+ protected void onContentViewSet() {
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
+ }
+}
diff --git a/design/tests/src/android/support/design/widget/AppBarWithCollapsingToolbarStateRestoreTest.java b/design/tests/src/android/support/design/widget/AppBarWithCollapsingToolbarStateRestoreTest.java
new file mode 100644
index 0000000..52f4ab2
--- /dev/null
+++ b/design/tests/src/android/support/design/widget/AppBarWithCollapsingToolbarStateRestoreTest.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+package android.support.design.widget;
+
+import static android.support.design.testutils.AppBarLayoutMatchers.isCollapsed;
+import static android.support.design.testutils.SwipeUtils.swipeUp;
+import static android.support.design.testutils.TestUtils.rotateOrientation;
+import static android.support.design.testutils.TestUtilsMatchers.hasZ;
+import static android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.assertion.ViewAssertions.matches;
+import static android.support.test.espresso.matcher.ViewMatchers.withId;
+
+import android.app.Activity;
+import android.support.design.test.R;
+
+import org.junit.Test;
+
+public class AppBarWithCollapsingToolbarStateRestoreTest
+ extends BaseInstrumentationTestCase<AppBarLayoutCollapsePinTestActivity> {
+
+ public AppBarWithCollapsingToolbarStateRestoreTest() {
+ super(AppBarLayoutCollapsePinTestActivity.class);
+ }
+
+ @Test
+ public void testRotateAndRestore() {
+ Activity activity = mActivityTestRule.getActivity();
+ final AppBarLayout appBar = (AppBarLayout) activity.findViewById(R.id.app_bar);
+
+ // Swipe up and collapse the AppBarLayout
+ onView(withId(R.id.coordinator_layout))
+ .perform(swipeUp(
+ appBar.getLeft() + (appBar.getWidth() / 2),
+ appBar.getBottom() + 20,
+ appBar.getHeight()));
+ onView(withId(R.id.app_bar))
+ .check(matches(hasZ()))
+ .check(matches(isCollapsed()));
+
+ // Now rotate the Activity
+ rotateOrientation(activity);
+
+ // And check that the app bar still is restored correctly
+ onView(withId(R.id.app_bar))
+ .check(matches(hasZ()))
+ .check(matches(isCollapsed()));
+ }
+
+}
diff --git a/design/tests/src/android/support/design/widget/AppBarWithCollapsingToolbarTest.java b/design/tests/src/android/support/design/widget/AppBarWithCollapsingToolbarTest.java
index adcfee8..2db3471 100644
--- a/design/tests/src/android/support/design/widget/AppBarWithCollapsingToolbarTest.java
+++ b/design/tests/src/android/support/design/widget/AppBarWithCollapsingToolbarTest.java
@@ -16,7 +16,10 @@
package android.support.design.widget;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.Matchers.greaterThan;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
import android.os.Build;
import android.os.SystemClock;
@@ -245,6 +248,111 @@
}
@Test
+ public void testScrollingToolbarEnterAlways() throws Throwable {
+ configureContent(R.layout.design_appbar_toolbar_collapse_scroll_enteralways,
+ R.string.design_appbar_collapsing_toolbar_scroll);
+
+ final int[] appbarOnScreenXY = new int[2];
+ final int[] coordinatorLayoutOnScreenXY = new int[2];
+ mAppBar.getLocationOnScreen(appbarOnScreenXY);
+ mCoordinatorLayout.getLocationOnScreen(coordinatorLayoutOnScreenXY);
+
+ final int topInset = mAppBar.getTopInset();
+
+ final int originalAppbarTop = appbarOnScreenXY[1];
+ final int originalAppbarBottom = appbarOnScreenXY[1] + mAppBar.getHeight();
+ final int centerX = appbarOnScreenXY[0] + mAppBar.getWidth() / 2;
+
+ final int toolbarHeight = mToolbar.getHeight();
+ final int appbarHeight = mAppBar.getHeight();
+ final int longSwipeAmount = 3 * appbarHeight / 2;
+ final int reallyLongSwipeAmount = 2 * appbarHeight;
+ final int shortSwipeAmount = toolbarHeight;
+
+ assertAppBarElevation(mDefaultElevationValue);
+ assertScrimAlpha(0);
+
+ // Perform a swipe-up gesture across the horizontal center of the screen, starting from
+ // just below the AppBarLayout
+ performVerticalSwipeUpGesture(
+ R.id.coordinator_layout,
+ centerX,
+ originalAppbarBottom + 20,
+ longSwipeAmount);
+
+ mAppBar.getLocationOnScreen(appbarOnScreenXY);
+ // At this point the app bar should not be visually "present" on the screen, with its bottom
+ // edge aligned with the bottom of system status bar. If we're running on a device which
+ // supports a translucent status bar, we need to take the status bar height into account.
+ // Allow for off-by-a-pixel margin of error.
+ assertEquals(originalAppbarTop, appbarOnScreenXY[1] + appbarHeight - topInset, 1);
+ assertAppBarElevation(mDefaultElevationValue);
+ assertScrimAlpha(255);
+
+ // Perform another swipe-up gesture
+ performVerticalSwipeUpGesture(
+ R.id.coordinator_layout,
+ centerX,
+ originalAppbarBottom,
+ shortSwipeAmount);
+
+ mAppBar.getLocationOnScreen(appbarOnScreenXY);
+ // At this point the app bar should still be off the screen. Allow for off-by-a-pixel
+ // margin of error.
+ assertEquals(originalAppbarTop, appbarOnScreenXY[1] + appbarHeight - topInset, 1);
+ assertAppBarElevation(mDefaultElevationValue);
+ assertScrimAlpha(255);
+
+ // Perform a short swipe-down gesture across the horizontal center of the screen.
+ // Note that the swipe down is a bit longer than the swipe up to fully bring down
+ // the scrolled-away toolbar
+ performVerticalSwipeDownGesture(
+ R.id.coordinator_layout,
+ centerX,
+ originalAppbarBottom,
+ 3 * shortSwipeAmount / 2);
+
+ mAppBar.getLocationOnScreen(appbarOnScreenXY);
+
+ // At this point the app bar should be visually below the system status bar as it
+ // in scrolling mode and we've swiped down, not fully but more than collapsed
+ assertThat(appbarOnScreenXY[1] + appbarHeight,
+ is(greaterThan(originalAppbarTop + toolbarHeight + topInset)));
+ assertAppBarElevation(mDefaultElevationValue);
+ assertScrimAlpha(255);
+
+ // Perform another swipe-down gesture across the horizontal center of the screen.
+ performVerticalSwipeDownGesture(
+ R.id.coordinator_layout,
+ centerX,
+ originalAppbarBottom,
+ reallyLongSwipeAmount);
+
+ mAppBar.getLocationOnScreen(appbarOnScreenXY);
+ // At this point the app bar should be in its original position.
+ // Allow for off-by-a-pixel margin of error.
+ assertEquals(originalAppbarTop, appbarOnScreenXY[1]);
+ assertEquals(originalAppbarBottom, appbarOnScreenXY[1] + appbarHeight);
+ assertAppBarElevation(mDefaultElevationValue);
+ assertScrimAlpha(0);
+
+ // Perform yet another swipe-down gesture across the horizontal center of the screen.
+ performVerticalSwipeDownGesture(
+ R.id.coordinator_layout,
+ centerX,
+ originalAppbarBottom,
+ longSwipeAmount);
+
+ mAppBar.getLocationOnScreen(appbarOnScreenXY);
+ // At this point the app bar should still be in its original position.
+ // Allow for off-by-a-pixel margin of error.
+ assertEquals(originalAppbarTop, appbarOnScreenXY[1], 1);
+ assertEquals(originalAppbarBottom, appbarOnScreenXY[1] + appbarHeight, 1);
+ assertAppBarElevation(mDefaultElevationValue);
+ assertScrimAlpha(0);
+ }
+
+ @Test
public void testPinnedToolbarAndAnchoredFab() throws Throwable {
configureContent(R.layout.design_appbar_toolbar_collapse_pin_with_fab,
R.string.design_appbar_collapsing_toolbar_pin_fab);
diff --git a/design/tests/src/android/support/design/widget/BottomNavigationViewTest.java b/design/tests/src/android/support/design/widget/BottomNavigationViewTest.java
index f06a85a..dcbbfb3 100644
--- a/design/tests/src/android/support/design/widget/BottomNavigationViewTest.java
+++ b/design/tests/src/android/support/design/widget/BottomNavigationViewTest.java
@@ -38,6 +38,7 @@
import static org.mockito.Mockito.when;
import android.content.res.Resources;
+import android.os.Parcelable;
import android.support.annotation.ColorInt;
import android.support.design.test.R;
import android.support.design.testutils.TestDrawable;
@@ -233,6 +234,29 @@
assertEquals(3, mBottomNavigation.getMenu().size());
}
+ @Test
+ @SmallTest
+ public void testSavedState() throws Throwable {
+ // Select an item other than the first
+ onView(allOf(withText(mMenuStringContent.get(R.id.destination_profile)),
+ isDescendantOfA(withId(R.id.bottom_navigation)), isDisplayed())).perform(click());
+ assertTrue(mBottomNavigation.getMenu().findItem(R.id.destination_profile).isChecked());
+ // Save the state
+ final Parcelable state = mBottomNavigation.onSaveInstanceState();
+
+ // Restore the state into a fresh BottomNavigationView
+ mActivityTestRule.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ BottomNavigationView testView =
+ new BottomNavigationView(mActivityTestRule.getActivity());
+ testView.inflateMenu(R.menu.bottom_navigation_view_content);
+ testView.onRestoreInstanceState(state);
+ assertTrue(testView.getMenu().findItem(R.id.destination_profile).isChecked());
+ }
+ });
+ }
+
private void checkAndVerifyExclusiveItem(final Menu menu, final int id) throws Throwable {
menu.findItem(id).setChecked(true);
for (int i = 0; i < menu.size(); i++) {
diff --git a/design/tests/src/android/support/design/widget/BottomSheetDialogTest.java b/design/tests/src/android/support/design/widget/BottomSheetDialogTest.java
index 84c522c..4c6bbbf 100644
--- a/design/tests/src/android/support/design/widget/BottomSheetDialogTest.java
+++ b/design/tests/src/android/support/design/widget/BottomSheetDialogTest.java
@@ -21,6 +21,11 @@
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.lessThan;
import static org.junit.Assert.fail;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.verify;
import android.content.Context;
import android.content.DialogInterface;
@@ -171,6 +176,40 @@
}
}
+ @SuppressWarnings("WrongConstant")
+ @Test
+ @MediumTest
+ public void testHideThenShow() throws Throwable {
+ // Hide the bottom sheet and wait for the dialog to be canceled.
+ final DialogInterface.OnCancelListener onCancelListener = mock(
+ DialogInterface.OnCancelListener.class);
+ mActivityTestRule.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ showDialog();
+ mDialog.setOnCancelListener(onCancelListener);
+ }
+ });
+ Espresso.onView(ViewMatchers.withId(R.id.design_bottom_sheet))
+ .perform(setState(BottomSheetBehavior.STATE_HIDDEN));
+ verify(onCancelListener, timeout(3000)).onCancel(any(DialogInterface.class));
+ // Reshow the same dialog instance and wait for the bottom sheet to be collapsed.
+ final BottomSheetBehavior.BottomSheetCallback callback = mock(
+ BottomSheetBehavior.BottomSheetCallback.class);
+ mActivityTestRule.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ BottomSheetBehavior.from(mDialog.findViewById(R.id.design_bottom_sheet))
+ .setBottomSheetCallback(callback);
+ mDialog.show(); // Show the same dialog again.
+ }
+ });
+ verify(callback, timeout(3000)).onStateChanged(any(View.class),
+ eq(BottomSheetBehavior.STATE_SETTLING));
+ verify(callback, timeout(3000)).onStateChanged(any(View.class),
+ eq(BottomSheetBehavior.STATE_COLLAPSED));
+ }
+
private void showDialog() {
Context context = mActivityTestRule.getActivity();
mDialog = new BottomSheetDialog(context);
diff --git a/design/tests/src/android/support/design/widget/CoordinatorLayoutTest.java b/design/tests/src/android/support/design/widget/CoordinatorLayoutTest.java
index 1d4f0a7..73ad193 100644
--- a/design/tests/src/android/support/design/widget/CoordinatorLayoutTest.java
+++ b/design/tests/src/android/support/design/widget/CoordinatorLayoutTest.java
@@ -16,6 +16,7 @@
package android.support.design.widget;
+import static android.support.test.InstrumentationRegistry.getInstrumentation;
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.action.ViewActions.swipeUp;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
@@ -40,10 +41,11 @@
import android.graphics.Rect;
import android.support.design.test.R;
import android.support.design.testutils.CoordinatorLayoutUtils;
+import android.support.design.testutils.CoordinatorLayoutUtils.DependentBehavior;
import android.support.design.widget.CoordinatorLayout.Behavior;
-import android.support.test.InstrumentationRegistry;
import android.support.test.filters.MediumTest;
import android.support.test.filters.SdkSuppress;
+import android.support.v4.view.GravityCompat;
import android.support.v4.view.ViewCompat;
import android.support.v4.view.WindowInsetsCompat;
import android.view.Gravity;
@@ -69,13 +71,13 @@
@Before
public void setup() {
- mInstrumentation = InstrumentationRegistry.getInstrumentation();
+ mInstrumentation = getInstrumentation();
}
@Test
@SdkSuppress(minSdkVersion = 21)
public void testSetFitSystemWindows() throws Throwable {
- final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+ final Instrumentation instrumentation = getInstrumentation();
final CoordinatorLayout col = mActivityTestRule.getActivity().mCoordinatorLayout;
final View view = new View(col.getContext());
@@ -128,6 +130,58 @@
}
@Test
+ public void testLayoutChildren() throws Throwable {
+ final Instrumentation instrumentation = getInstrumentation();
+ final CoordinatorLayout col = mActivityTestRule.getActivity().mCoordinatorLayout;
+ final View view = new View(col.getContext());
+ mActivityTestRule.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ col.addView(view, 100, 100);
+ }
+ });
+ instrumentation.waitForIdleSync();
+ int horizontallyCentered = (col.getWidth() - view.getWidth()) / 2;
+ int end = col.getWidth() - view.getWidth();
+ int verticallyCentered = (col.getHeight() - view.getHeight()) / 2;
+ int bottom = col.getHeight() - view.getHeight();
+ final int[][] testCases = {
+ // gravity, expected left, expected top
+ {Gravity.NO_GRAVITY, 0, 0},
+ {Gravity.LEFT, 0, 0},
+ {GravityCompat.START, 0, 0},
+ {Gravity.TOP, 0, 0},
+ {Gravity.CENTER, horizontallyCentered, verticallyCentered},
+ {Gravity.CENTER_HORIZONTAL, horizontallyCentered, 0},
+ {Gravity.CENTER_VERTICAL, 0, verticallyCentered},
+ {Gravity.RIGHT, end, 0},
+ {GravityCompat.END, end, 0},
+ {Gravity.BOTTOM, 0, bottom},
+ {Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM, horizontallyCentered, bottom},
+ {Gravity.RIGHT | Gravity.CENTER_VERTICAL, end, verticallyCentered},
+ };
+ for (final int[] testCase : testCases) {
+ mActivityTestRule.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ final CoordinatorLayout.LayoutParams lp =
+ (CoordinatorLayout.LayoutParams) view.getLayoutParams();
+ lp.gravity = testCase[0];
+ view.setLayoutParams(lp);
+ }
+ });
+ instrumentation.waitForIdleSync();
+ mActivityTestRule.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ assertThat("Gravity: " + testCase[0], view.getLeft(), is(testCase[1]));
+ assertThat("Gravity: " + testCase[0], view.getTop(), is(testCase[2]));
+ }
+ });
+ }
+ }
+
+ @Test
public void testInsetDependency() {
final CoordinatorLayout col = mActivityTestRule.getActivity().mCoordinatorLayout;
@@ -183,7 +237,7 @@
@Test
public void testInsetEdge() throws Throwable {
- final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+ final Instrumentation instrumentation = getInstrumentation();
final CoordinatorLayout col = mActivityTestRule.getActivity().mCoordinatorLayout;
final View insetView = new View(col.getContext());
@@ -236,7 +290,7 @@
@Test
public void testDependentViewChanged() throws Throwable {
- final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+ final Instrumentation instrumentation = getInstrumentation();
final CoordinatorLayout col = mActivityTestRule.getActivity().mCoordinatorLayout;
// Add two views, A & B, where B depends on A
@@ -250,7 +304,7 @@
lpB.width = 100;
lpB.height = 100;
final CoordinatorLayout.Behavior behavior =
- spy(new CoordinatorLayoutUtils.DependentBehavior(viewA));
+ spy(new DependentBehavior(viewA));
lpB.setBehavior(behavior);
mActivityTestRule.runOnUiThread(new Runnable() {
@@ -282,7 +336,7 @@
@Test
public void testDependentViewRemoved() throws Throwable {
- final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+ final Instrumentation instrumentation = getInstrumentation();
final CoordinatorLayout col = mActivityTestRule.getActivity().mCoordinatorLayout;
// Add two views, A & B, where B depends on A
@@ -290,7 +344,7 @@
final View viewB = new View(col.getContext());
final CoordinatorLayout.LayoutParams lpB = col.generateDefaultLayoutParams();
final CoordinatorLayout.Behavior behavior =
- spy(new CoordinatorLayoutUtils.DependentBehavior(viewA));
+ spy(new DependentBehavior(viewA));
lpB.setBehavior(behavior);
mActivityTestRule.runOnUiThread(new Runnable() {
@@ -316,7 +370,7 @@
@Test
public void testGetDependenciesAfterDependentViewRemoved() throws Throwable {
- final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+ final Instrumentation instrumentation = getInstrumentation();
final CoordinatorLayout col = mActivityTestRule.getActivity().mCoordinatorLayout;
// Add two views, A & B, where B depends on A
@@ -572,6 +626,55 @@
}
@Test
+ public void testNestedScrollingTriggeringDependentViewChanged() throws Throwable {
+ final CoordinatorLayoutActivity activity = mActivityTestRule.getActivity();
+ final CoordinatorLayout col = activity.mCoordinatorLayout;
+
+ // First a NestedScrollView to trigger nested scrolling
+ final View scrollView = LayoutInflater.from(activity).inflate(
+ R.layout.include_nestedscrollview, col, false);
+
+ // Now create a View and Behavior which depend on the scrollview
+ final ImageView dependentView = new ImageView(activity);
+ final CoordinatorLayout.Behavior dependentBehavior = spy(new DependentBehavior(scrollView));
+
+ // Finally a view which accepts nested scrolling in the CoordinatorLayout
+ final ImageView nestedScrollAwareView = new ImageView(activity);
+
+ mActivityTestRule.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ // First add the ScrollView
+ col.addView(scrollView);
+
+ // Now add the view which depends on the scrollview
+ CoordinatorLayout.LayoutParams clp = new CoordinatorLayout.LayoutParams(200, 200);
+ clp.setBehavior(dependentBehavior);
+ col.addView(dependentView, clp);
+
+ // Now add the nested scrolling aware view
+ clp = new CoordinatorLayout.LayoutParams(200, 200);
+ clp.setBehavior(new NestedScrollingBehavior());
+ col.addView(nestedScrollAwareView, clp);
+ }
+ });
+
+ // Wait for any layouts, and reset the Behavior so that the call counts are 0
+ getInstrumentation().waitForIdleSync();
+ reset(dependentBehavior);
+
+ // Now vertically swipe up on the NSV, causing nested scrolling to occur
+ onView(withId(R.id.nested_scrollview)).perform(swipeUp());
+
+ // Verify that the Behavior's onDependentViewChanged is not called due to the
+ // nested scroll
+ verify(dependentBehavior, never()).onDependentViewChanged(
+ eq(col), // parent
+ eq(dependentView), // child
+ eq(scrollView)); // axes
+ }
+
+ @Test
public void testDodgeInsetViewWithEmptyBounds() throws Throwable {
final CoordinatorLayout col = mActivityTestRule.getActivity().mCoordinatorLayout;
@@ -614,9 +717,9 @@
.getInsetDodgeRect(same(col), same(view), any(Rect.class));
}
- public static class NestedScrollingBehavior extends CoordinatorLayout.Behavior<ImageView> {
+ public static class NestedScrollingBehavior extends CoordinatorLayout.Behavior<View> {
@Override
- public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, ImageView child,
+ public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, View child,
View directTargetChild, View target, int nestedScrollAxes) {
// Return true so that we always accept nested scroll events
return true;
diff --git a/design/tests/src/android/support/design/widget/FloatingActionButtonTest.java b/design/tests/src/android/support/design/widget/FloatingActionButtonTest.java
index 069055b..e8cc701 100644
--- a/design/tests/src/android/support/design/widget/FloatingActionButtonTest.java
+++ b/design/tests/src/android/support/design/widget/FloatingActionButtonTest.java
@@ -33,11 +33,15 @@
import static android.support.design.testutils.TestUtilsMatchers.withFabContentHeight;
import static android.support.design.widget.DesignViewActions.setVisibility;
import static android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.action.ViewActions.click;
import static android.support.test.espresso.assertion.ViewAssertions.matches;
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static org.hamcrest.Matchers.not;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
import android.app.Activity;
import android.content.res.ColorStateList;
@@ -229,6 +233,19 @@
}
@Test
+ public void testOnClickListener() {
+ final View.OnClickListener listener = mock(View.OnClickListener.class);
+ final View view = mActivityTestRule.getActivity().findViewById(R.id.fab_standard);
+ view.setOnClickListener(listener);
+
+ // Click on the fab
+ onView(withId(R.id.fab_standard)).perform(click());
+
+ // And verify that the listener was invoked once
+ verify(listener, times(1)).onClick(view);
+ }
+
+ @Test
public void testSetCompatElevation() {
onView(withId(R.id.fab_standard))
.perform(setEnabled(false))
diff --git a/design/tests/src/android/support/design/widget/SnackbarTest.java b/design/tests/src/android/support/design/widget/SnackbarTest.java
index 23092e8..5f5682c 100644
--- a/design/tests/src/android/support/design/widget/SnackbarTest.java
+++ b/design/tests/src/android/support/design/widget/SnackbarTest.java
@@ -46,6 +46,10 @@
import android.support.design.testutils.SnackbarUtils;
import android.support.test.espresso.ViewAction;
import android.support.test.espresso.ViewInteraction;
+import android.support.test.espresso.action.CoordinatesProvider;
+import android.support.test.espresso.action.GeneralSwipeAction;
+import android.support.test.espresso.action.Press;
+import android.support.test.espresso.action.Swipe;
import android.support.test.filters.MediumTest;
import android.support.v4.view.ViewCompat;
import android.text.TextUtils;
@@ -242,6 +246,41 @@
}
@Test
+ public void testSwipeUpDismissesViaTimeout() throws Throwable {
+ verifyDismissCallback(
+ onView(isAssignableFrom(Snackbar.SnackbarLayout.class)),
+ // This is a swipe up, from the middle center of the view, to above the view
+ // (outside the bounds)
+ new GeneralSwipeAction(
+ Swipe.SLOW,
+ new CoordinatesProvider() {
+ @Override
+ public float[] calculateCoordinates(View view) {
+ final int[] loc = new int[2];
+ view.getLocationOnScreen(loc);
+ return new float[]{
+ loc[0] + view.getWidth() / 2,
+ loc[1] + view.getHeight() / 2};
+ }
+ },
+ new CoordinatesProvider() {
+ @Override
+ public float[] calculateCoordinates(View view) {
+ final int[] loc = new int[2];
+ view.getLocationOnScreen(loc);
+ return new float[]{
+ loc[0] + view.getWidth() / 2,
+ loc[1] - view.getHeight()};
+ }
+ },
+ Press.FINGER
+ ),
+ null,
+ Snackbar.LENGTH_SHORT,
+ Snackbar.Callback.DISMISS_EVENT_TIMEOUT);
+ }
+
+ @Test
public void testDismissViaAnotherSnackbar() throws Throwable {
final Snackbar anotherSnackbar =
Snackbar.make(mCoordinatorLayout, "A different message", Snackbar.LENGTH_SHORT);
diff --git a/design/tests/src/android/support/design/widget/TextInputLayoutTest.java b/design/tests/src/android/support/design/widget/TextInputLayoutTest.java
index 4944170..2ba1e6e 100755
--- a/design/tests/src/android/support/design/widget/TextInputLayoutTest.java
+++ b/design/tests/src/android/support/design/widget/TextInputLayoutTest.java
@@ -460,6 +460,12 @@
}
@Test
+ public void testTextSetViaAttributeCollapsedHint() {
+ onView(withId(R.id.textinput_with_text))
+ .check(isHintExpanded(false));
+ }
+
+ @Test
public void testFocusMovesToEditTextWithPasswordEnabled() {
// Focus the preceding EditText
onView(withId(R.id.textinput_edittext))
diff --git a/exifinterface/Android.mk b/exifinterface/Android.mk
index 9da8bc5..4d5887c 100644
--- a/exifinterface/Android.mk
+++ b/exifinterface/Android.mk
@@ -25,6 +25,7 @@
LOCAL_SDK_VERSION := $(SUPPORT_CURRENT_SDK_VERSION)
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+LOCAL_MANIFEST_FILE := AndroidManifest-make.xml
LOCAL_SHARED_ANDROID_LIBRARIES := \
android-support-annotations
LOCAL_JAR_EXCLUDE_FILES := none
diff --git a/exifinterface/AndroidManifest-make.xml b/exifinterface/AndroidManifest-make.xml
new file mode 100644
index 0000000..4812a71
--- /dev/null
+++ b/exifinterface/AndroidManifest-make.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.support.exifinterface">
+ <uses-sdk android:minSdkVersion="9"/>
+ <application />
+</manifest>
diff --git a/exifinterface/AndroidManifest.xml b/exifinterface/AndroidManifest.xml
index 4812a71..bacbdbe 100644
--- a/exifinterface/AndroidManifest.xml
+++ b/exifinterface/AndroidManifest.xml
@@ -16,5 +16,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="android.support.exifinterface">
<uses-sdk android:minSdkVersion="9"/>
+ <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
<application />
</manifest>
diff --git a/exifinterface/build.gradle b/exifinterface/build.gradle
index 42f50c1..f6fd633 100644
--- a/exifinterface/build.gradle
+++ b/exifinterface/build.gradle
@@ -1,5 +1,4 @@
apply plugin: 'com.android.library'
-
archivesBaseName = 'exifinterface'
dependencies {
@@ -33,28 +32,11 @@
}
def suffix = name.capitalize()
- def jarTask = project.tasks.create(name: "jar${suffix}", type: Jar){
- dependsOn variant.javaCompile
- from variant.javaCompile.destinationDir
- from 'LICENSE.txt'
- }
- def javadocTask = project.tasks.create(name: "javadoc${suffix}", type: Javadoc) {
- source android.sourceSets.main.java
- classpath = files(variant.javaCompile.classpath.files) + files(
- "${android.sdkDirectory}/platforms/${android.compileSdkVersion}/android.jar")
- }
-
- def javadocJarTask = project.tasks.create(name: "javadocJar${suffix}", type: Jar) {
- classifier = 'javadoc'
- from 'build/docs/javadoc'
- }
-
def sourcesJarTask = project.tasks.create(name: "sourceJar${suffix}", type: Jar) {
classifier = 'sources'
from android.sourceSets.main.java.srcDirs
}
- artifacts.add('archives', javadocJarTask);
artifacts.add('archives', sourcesJarTask);
}
diff --git a/exifinterface/src/android/support/media/ExifInterface.java b/exifinterface/src/android/support/media/ExifInterface.java
index ae9d842..fccab43 100644
--- a/exifinterface/src/android/support/media/ExifInterface.java
+++ b/exifinterface/src/android/support/media/ExifInterface.java
@@ -658,9 +658,9 @@
}
private Object getValue(ByteOrder byteOrder) {
+ ByteOrderedDataInputStream inputStream = null;
try {
- ByteOrderedDataInputStream inputStream =
- new ByteOrderedDataInputStream(bytes);
+ inputStream = new ByteOrderedDataInputStream(bytes);
inputStream.setByteOrder(byteOrder);
switch (format) {
case IFD_FORMAT_BYTE:
@@ -768,6 +768,14 @@
} catch (IOException e) {
Log.w(TAG, "IOException occurred during reading a value", e);
return null;
+ } finally {
+ if (inputStream != null) {
+ try {
+ inputStream.close();
+ } catch (IOException e) {
+ Log.e(TAG, "IOException occurred while closing InputStream", e);
+ }
+ }
}
}
@@ -1517,8 +1525,8 @@
final Rational[] rationalArray = new Rational[values.length];
for (int j = 0; j < values.length; ++j) {
final String[] numbers = values[j].split("/");
- rationalArray[j] = new Rational(Long.parseLong(numbers[0]),
- Long.parseLong(numbers[1]));
+ rationalArray[j] = new Rational((long) Double.parseDouble(numbers[0]),
+ (long) Double.parseDouble(numbers[1]));
}
mAttributes[i].put(tag,
ExifAttribute.createURational(rationalArray, mExifByteOrder));
@@ -1529,8 +1537,8 @@
final Rational[] rationalArray = new Rational[values.length];
for (int j = 0; j < values.length; ++j) {
final String[] numbers = values[j].split("/");
- rationalArray[j] = new Rational(Long.parseLong(numbers[0]),
- Long.parseLong(numbers[1]));
+ rationalArray[j] = new Rational((long) Double.parseDouble(numbers[0]),
+ (long) Double.parseDouble(numbers[1]));
}
mAttributes[i].put(tag,
ExifAttribute.createSRational(rationalArray, mExifByteOrder));
@@ -2040,6 +2048,7 @@
signatureInputStream.setByteOrder(mExifByteOrder);
short orfSignature = signatureInputStream.readShort();
+ signatureInputStream.close();
return orfSignature == ORF_SIGNATURE_1 || orfSignature == ORF_SIGNATURE_2;
}
@@ -2056,6 +2065,7 @@
signatureInputStream.setByteOrder(mExifByteOrder);
short signatureByte = signatureInputStream.readShort();
+ signatureInputStream.close();
return signatureByte == RW2_SIGNATURE;
}
@@ -3341,8 +3351,8 @@
String[] rationalNumber = entryValue.split("/");
if (rationalNumber.length == 2) {
try {
- long numerator = Long.parseLong(rationalNumber[0]);
- long denominator = Long.parseLong(rationalNumber[1]);
+ long numerator = (long) Double.parseDouble(rationalNumber[0]);
+ long denominator = (long) Double.parseDouble(rationalNumber[1]);
if (numerator < 0L || denominator < 0L) {
return new Pair<>(IFD_FORMAT_SRATIONAL, -1);
}
diff --git a/fragment/Android.mk b/fragment/Android.mk
index a41b0c2..f55cfb7 100644
--- a/fragment/Android.mk
+++ b/fragment/Android.mk
@@ -36,6 +36,7 @@
$(call all-java-files-under, api21) \
$(call all-java-files-under, java)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+LOCAL_MANIFEST_FILE := AndroidManifest-make.xml
LOCAL_SHARED_ANDROID_LIBRARIES := \
android-support-compat \
android-support-core-ui \
diff --git a/fragment/AndroidManifest-make.xml b/fragment/AndroidManifest-make.xml
new file mode 100644
index 0000000..54e61d3
--- /dev/null
+++ b/fragment/AndroidManifest-make.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ package="android.support.fragment">
+ <uses-sdk android:minSdkVersion="9" tools:overrideLibrary="android.support.fragment"/>
+ <application />
+</manifest>
diff --git a/fragment/AndroidManifest.xml b/fragment/AndroidManifest.xml
index 54e61d3..9b34e14 100644
--- a/fragment/AndroidManifest.xml
+++ b/fragment/AndroidManifest.xml
@@ -17,5 +17,6 @@
xmlns:tools="http://schemas.android.com/tools"
package="android.support.fragment">
<uses-sdk android:minSdkVersion="9" tools:overrideLibrary="android.support.fragment"/>
+ <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
<application />
</manifest>
diff --git a/fragment/build.gradle b/fragment/build.gradle
index 26e9f1c..7c9098a 100644
--- a/fragment/build.gradle
+++ b/fragment/build.gradle
@@ -18,9 +18,6 @@
testCompile 'junit:junit:4.12'
}
-sourceCompatibility = JavaVersion.VERSION_1_7
-targetCompatibility = JavaVersion.VERSION_1_7
-
android {
compileSdkVersion project.ext.currentSdk
@@ -50,11 +47,6 @@
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
-
- testOptions {
- unitTests.returnDefaultValues = true
- compileSdkVersion project.ext.currentSdk
- }
}
android.libraryVariants.all { variant ->
@@ -65,22 +57,6 @@
}
def suffix = name.capitalize()
- def jarTask = project.tasks.create(name: "jar${suffix}", type: Jar){
- dependsOn variant.javaCompile
- from variant.javaCompile.destinationDir
- from 'LICENSE.txt'
- }
- def javadocTask = project.tasks.create(name: "javadoc${suffix}", type: Javadoc) {
- source android.sourceSets.main.java
- classpath = files(variant.javaCompile.classpath.files) + files(
- "${android.sdkDirectory}/platforms/${android.compileSdkVersion}/android.jar")
- }
-
- def javadocJarTask = project.tasks.create(name: "javadocJar${suffix}", type: Jar) {
- classifier = 'javadoc'
- from 'build/docs/javadoc'
- }
-
def sourcesJarTask = project.tasks.create(name: "sourceJar${suffix}", type: Jar) {
classifier = 'sources'
from android.sourceSets.main.java.srcDirs
@@ -88,7 +64,6 @@
exclude('android/service/media/**')
}
- artifacts.add('archives', javadocJarTask);
artifacts.add('archives', sourcesJarTask);
}
diff --git a/fragment/java/android/support/v4/app/BackStackRecord.java b/fragment/java/android/support/v4/app/BackStackRecord.java
index 3b41d60..326521a 100644
--- a/fragment/java/android/support/v4/app/BackStackRecord.java
+++ b/fragment/java/android/support/v4/app/BackStackRecord.java
@@ -639,6 +639,7 @@
LogWriter logw = new LogWriter(TAG);
PrintWriter pw = new PrintWriter(logw);
dump(" ", null, pw, null);
+ pw.close();
}
mCommitted = true;
if (mAddToBackStack) {
diff --git a/fragment/java/android/support/v4/app/Fragment.java b/fragment/java/android/support/v4/app/Fragment.java
index 881c2b4..06d0b1e 100644
--- a/fragment/java/android/support/v4/app/Fragment.java
+++ b/fragment/java/android/support/v4/app/Fragment.java
@@ -2150,6 +2150,9 @@
}
void instantiateChildFragmentManager() {
+ if (mHost == null) {
+ throw new IllegalStateException("Fragment has not been attached yet.");
+ }
mChildFragmentManager = new FragmentManagerImpl();
mChildFragmentManager.attachController(mHost, new FragmentContainer() {
@Override
diff --git a/fragment/java/android/support/v4/app/FragmentManager.java b/fragment/java/android/support/v4/app/FragmentManager.java
index 8aaf53f..b385461 100644
--- a/fragment/java/android/support/v4/app/FragmentManager.java
+++ b/fragment/java/android/support/v4/app/FragmentManager.java
@@ -2855,6 +2855,7 @@
LogWriter logw = new LogWriter(TAG);
PrintWriter pw = new PrintWriter(logw);
bse.dump(" ", pw, false);
+ pw.close();
}
mBackStack.add(bse);
if (bse.mIndex >= 0) {
diff --git a/fragment/tests/java/android/support/v4/app/FragmentOptimizationTest.java b/fragment/tests/java/android/support/v4/app/FragmentOptimizationTest.java
index 06abd69..13901c4 100644
--- a/fragment/tests/java/android/support/v4/app/FragmentOptimizationTest.java
+++ b/fragment/tests/java/android/support/v4/app/FragmentOptimizationTest.java
@@ -15,11 +15,14 @@
*/
package android.support.v4.app;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
import android.app.Instrumentation;
import android.support.fragment.test.R;
import android.support.test.InstrumentationRegistry;
+import android.support.test.annotation.UiThreadTest;
import android.support.test.filters.MediumTest;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
@@ -648,38 +651,30 @@
// Test that a fragment view that is created with focus has focus after the transaction
// completes.
+ @UiThreadTest
@Test
public void focusedView() throws Throwable {
- FragmentTestUtil.setContentView(mActivityRule, R.layout.double_container);
+ mActivityRule.getActivity().setContentView(R.layout.double_container);
mContainer = (ViewGroup) mActivityRule.getActivity().findViewById(R.id.fragmentContainer1);
- final EditText firstEditText = new EditText(mContainer.getContext());
- mInstrumentation.runOnMainSync(new Runnable() {
- @Override
- public void run() {
- mContainer.addView(firstEditText);
- firstEditText.requestFocus();
- }
- });
+ EditText firstEditText = new EditText(mContainer.getContext());
+ mContainer.addView(firstEditText);
+ firstEditText.requestFocus();
+
assertTrue(firstEditText.isFocused());
final CountCallsFragment fragment1 = new CountCallsFragment();
final CountCallsFragment fragment2 = new CountCallsFragment();
fragment2.setLayoutId(R.layout.with_edit_text);
- mInstrumentation.runOnMainSync(new Runnable() {
- @Override
- public void run() {
- mFM.beginTransaction()
- .add(R.id.fragmentContainer2, fragment1)
- .addToBackStack(null)
- .setAllowOptimization(true)
- .commit();
- mFM.beginTransaction()
- .replace(R.id.fragmentContainer2, fragment2)
- .addToBackStack(null)
- .setAllowOptimization(true)
- .commit();
- mFM.executePendingTransactions();
- }
- });
+ mFM.beginTransaction()
+ .add(R.id.fragmentContainer2, fragment1)
+ .addToBackStack(null)
+ .setAllowOptimization(true)
+ .commit();
+ mFM.beginTransaction()
+ .replace(R.id.fragmentContainer2, fragment2)
+ .addToBackStack(null)
+ .setAllowOptimization(true)
+ .commit();
+ mFM.executePendingTransactions();
final View editText = fragment2.getView().findViewById(R.id.editText);
assertTrue(editText.isFocused());
assertFalse(firstEditText.isFocused());
diff --git a/gradle.properties b/gradle.properties
index 34b3995..fb870a9 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,3 +1,4 @@
org.gradle.jvmargs=-Xmx3g
org.gradle.daemon=true
-org.gradle.configureondemand=true
\ No newline at end of file
+org.gradle.configureondemand=true
+org.gradle.parallel=true
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index ccfc973..84939b4 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -3,4 +3,4 @@
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=../../../../tools/external/gradle/gradle-3.2-bin.zip
+distributionUrl=../../../../tools/external/gradle/gradle-3.3-bin.zip
diff --git a/graphics/drawable/Android.mk b/graphics/drawable/Android.mk
index f58493b..78652aa 100644
--- a/graphics/drawable/Android.mk
+++ b/graphics/drawable/Android.mk
@@ -25,7 +25,7 @@
LOCAL_SDK_VERSION := $(SUPPORT_CURRENT_SDK_VERSION)
LOCAL_SRC_FILES := $(call all-java-files-under, static/src)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/static/res
-LOCAL_MANIFEST_FILE := static/AndroidManifest.xml
+LOCAL_MANIFEST_FILE := static/AndroidManifest-make.xml
LOCAL_SHARED_ANDROID_LIBRARIES := \
android-support-compat \
android-support-annotations
@@ -44,7 +44,7 @@
LOCAL_SDK_VERSION := $(SUPPORT_CURRENT_SDK_VERSION)
LOCAL_SRC_FILES := $(call all-java-files-under, animated/src)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/animated/res
-LOCAL_MANIFEST_FILE := animated/AndroidManifest.xml
+LOCAL_MANIFEST_FILE := animated/AndroidManifest-make.xml
LOCAL_SHARED_ANDROID_LIBRARIES := \
android-support-compat \
android-support-vectordrawable \
diff --git a/graphics/drawable/animated/AndroidManifest-make.xml b/graphics/drawable/animated/AndroidManifest-make.xml
new file mode 100644
index 0000000..98f9e17
--- /dev/null
+++ b/graphics/drawable/animated/AndroidManifest-make.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2015 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.
+ -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.support.graphics.drawable.animated">
+ <application/>
+</manifest>
diff --git a/graphics/drawable/animated/AndroidManifest.xml b/graphics/drawable/animated/AndroidManifest.xml
index 98f9e17..58017dc 100644
--- a/graphics/drawable/animated/AndroidManifest.xml
+++ b/graphics/drawable/animated/AndroidManifest.xml
@@ -16,5 +16,6 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="android.support.graphics.drawable.animated">
+ <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
<application/>
</manifest>
diff --git a/graphics/drawable/animated/build.gradle b/graphics/drawable/animated/build.gradle
index bb110a1..10d112a 100644
--- a/graphics/drawable/animated/build.gradle
+++ b/graphics/drawable/animated/build.gradle
@@ -1,5 +1,4 @@
apply plugin: 'com.android.library'
-
archivesBaseName = 'animated-vector-drawable'
dependencies {
@@ -41,14 +40,6 @@
additionalParameters "--no-version-vectors"
}
- packagingOptions {
- exclude 'LICENSE.txt'
- }
-
- testOptions {
- unitTests.returnDefaultValues = true
- }
-
buildTypes.all {
consumerProguardFiles 'proguard-rules.pro'
}
@@ -62,28 +53,11 @@
}
def suffix = name.capitalize()
- def jarTask = project.tasks.create(name: "jar${suffix}", type: Jar) {
- dependsOn variant.javaCompile
- from variant.javaCompile.destinationDir
- from 'LICENSE.txt'
- }
- def javadocTask = project.tasks.create(name: "javadoc${suffix}", type: Javadoc) {
- source android.sourceSets.main.java
- classpath = files(variant.javaCompile.classpath.files) + files(
- "${android.sdkDirectory}/platforms/${android.compileSdkVersion}/android.jar")
- }
-
- def javadocJarTask = project.tasks.create(name: "javadocJar${suffix}", type: Jar) {
- classifier = 'javadoc'
- from 'build/docs/javadoc'
- }
-
def sourcesJarTask = project.tasks.create(name: "sourceJar${suffix}", type: Jar) {
classifier = 'sources'
from android.sourceSets.main.java.srcDirs
}
- artifacts.add('archives', javadocJarTask);
artifacts.add('archives', sourcesJarTask);
}
diff --git a/graphics/drawable/animated/src/android/support/graphics/drawable/AnimatedVectorDrawableCompat.java b/graphics/drawable/animated/src/android/support/graphics/drawable/AnimatedVectorDrawableCompat.java
index 8c0a7be..fe60272 100644
--- a/graphics/drawable/animated/src/android/support/graphics/drawable/AnimatedVectorDrawableCompat.java
+++ b/graphics/drawable/animated/src/android/support/graphics/drawable/AnimatedVectorDrawableCompat.java
@@ -397,6 +397,7 @@
Animator objectAnimator = AnimatorInflater.loadAnimator(mContext, id);
setupAnimatorsForTarget(target, objectAnimator);
} else {
+ a.recycle();
throw new IllegalStateException("Context can't be null when inflating" +
" animators");
}
diff --git a/graphics/drawable/static/AndroidManifest-make.xml b/graphics/drawable/static/AndroidManifest-make.xml
new file mode 100644
index 0000000..8674cb4
--- /dev/null
+++ b/graphics/drawable/static/AndroidManifest-make.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2015 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.
+ -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.support.graphics.drawable">
+ <application/>
+</manifest>
diff --git a/graphics/drawable/static/AndroidManifest.xml b/graphics/drawable/static/AndroidManifest.xml
index e91290d..0383e4c 100644
--- a/graphics/drawable/static/AndroidManifest.xml
+++ b/graphics/drawable/static/AndroidManifest.xml
@@ -14,6 +14,8 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<manifest package="android.support.graphics.drawable">
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.support.graphics.drawable">
<application/>
+ <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
</manifest>
diff --git a/graphics/drawable/static/build.gradle b/graphics/drawable/static/build.gradle
index 2c72f9f..fdb306c 100644
--- a/graphics/drawable/static/build.gradle
+++ b/graphics/drawable/static/build.gradle
@@ -42,14 +42,6 @@
aaptOptions {
additionalParameters "--no-version-vectors"
}
-
- packagingOptions {
- exclude 'LICENSE.txt'
- }
-
- testOptions {
- unitTests.returnDefaultValues = true
- }
}
android.libraryVariants.all { variant ->
@@ -60,28 +52,11 @@
}
def suffix = name.capitalize()
- def jarTask = project.tasks.create(name: "jar${suffix}", type: Jar) {
- dependsOn variant.javaCompile
- from variant.javaCompile.destinationDir
- from 'LICENSE.txt'
- }
- def javadocTask = project.tasks.create(name: "javadoc${suffix}", type: Javadoc) {
- source android.sourceSets.main.java
- classpath = files(variant.javaCompile.classpath.files) + files(
- "${android.sdkDirectory}/platforms/${android.compileSdkVersion}/android.jar")
- }
-
- def javadocJarTask = project.tasks.create(name: "javadocJar${suffix}", type: Jar) {
- classifier = 'javadoc'
- from 'build/docs/javadoc'
- }
-
def sourcesJarTask = project.tasks.create(name: "sourceJar${suffix}", type: Jar) {
classifier = 'sources'
from android.sourceSets.main.java.srcDirs
}
- artifacts.add('archives', javadocJarTask);
artifacts.add('archives', sourcesJarTask);
}
diff --git a/media-compat/Android.mk b/media-compat/Android.mk
index 52dc3d8..0050ea4 100644
--- a/media-compat/Android.mk
+++ b/media-compat/Android.mk
@@ -38,6 +38,7 @@
$(call all-java-files-under,java) \
$(call all-Iaidl-files-under,java)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+LOCAL_MANIFEST_FILE := AndroidManifest-make.xml
LOCAL_SHARED_ANDROID_LIBRARIES := \
android-support-compat \
android-support-annotations
diff --git a/media-compat/AndroidManifest-make.xml b/media-compat/AndroidManifest-make.xml
new file mode 100644
index 0000000..c971549
--- /dev/null
+++ b/media-compat/AndroidManifest-make.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ package="android.support.mediacompat">
+ <uses-sdk android:minSdkVersion="9" tools:overrideLibrary="android.support.mediacompat"/>
+ <application />
+</manifest>
diff --git a/media-compat/AndroidManifest.xml b/media-compat/AndroidManifest.xml
index c971549..5f7b051 100644
--- a/media-compat/AndroidManifest.xml
+++ b/media-compat/AndroidManifest.xml
@@ -17,5 +17,6 @@
xmlns:tools="http://schemas.android.com/tools"
package="android.support.mediacompat">
<uses-sdk android:minSdkVersion="9" tools:overrideLibrary="android.support.mediacompat"/>
+ <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
<application />
</manifest>
diff --git a/media-compat/build.gradle b/media-compat/build.gradle
index 9bec2a3..8dd44bf 100644
--- a/media-compat/build.gradle
+++ b/media-compat/build.gradle
@@ -15,9 +15,6 @@
androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.2'
}
-sourceCompatibility = JavaVersion.VERSION_1_7
-targetCompatibility = JavaVersion.VERSION_1_7
-
android {
compileSdkVersion project.ext.currentSdk
@@ -61,22 +58,6 @@
}
def suffix = name.capitalize()
- def jarTask = project.tasks.create(name: "jar${suffix}", type: Jar){
- dependsOn variant.javaCompile
- from variant.javaCompile.destinationDir
- from 'LICENSE.txt'
- }
- def javadocTask = project.tasks.create(name: "javadoc${suffix}", type: Javadoc) {
- source android.sourceSets.main.java
- classpath = files(variant.javaCompile.classpath.files) + files(
- "${android.sdkDirectory}/platforms/${android.compileSdkVersion}/android.jar")
- }
-
- def javadocJarTask = project.tasks.create(name: "javadocJar${suffix}", type: Jar) {
- classifier = 'javadoc'
- from 'build/docs/javadoc'
- }
-
def sourcesJarTask = project.tasks.create(name: "sourceJar${suffix}", type: Jar) {
classifier = 'sources'
from android.sourceSets.main.java.srcDirs
@@ -84,7 +65,6 @@
exclude('android/service/media/**')
}
- artifacts.add('archives', javadocJarTask);
artifacts.add('archives', sourcesJarTask);
}
diff --git a/percent/Android.mk b/percent/Android.mk
index b569224..aaeb65a 100644
--- a/percent/Android.mk
+++ b/percent/Android.mk
@@ -27,6 +27,7 @@
LOCAL_SDK_VERSION := $(SUPPORT_CURRENT_SDK_VERSION)
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+LOCAL_MANIFEST_FILE := AndroidManifest-make.xml
LOCAL_SHARED_ANDROID_LIBRARIES := android-support-v4
LOCAL_JAR_EXCLUDE_FILES := none
LOCAL_JAVA_LANGUAGE_VERSION := 1.7
diff --git a/percent/AndroidManifest-make.xml b/percent/AndroidManifest-make.xml
new file mode 100644
index 0000000..e979013
--- /dev/null
+++ b/percent/AndroidManifest-make.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.support.percent">
+ <uses-sdk android:minSdkVersion="9"/>
+ <application />
+</manifest>
diff --git a/percent/AndroidManifest.xml b/percent/AndroidManifest.xml
index e979013..0d55165 100644
--- a/percent/AndroidManifest.xml
+++ b/percent/AndroidManifest.xml
@@ -16,5 +16,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="android.support.percent">
<uses-sdk android:minSdkVersion="9"/>
+ <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
<application />
</manifest>
diff --git a/percent/build.gradle b/percent/build.gradle
index c3f386e..b120075 100644
--- a/percent/build.gradle
+++ b/percent/build.gradle
@@ -1,5 +1,4 @@
apply plugin: 'com.android.library'
-
archivesBaseName = 'percent'
dependencies {
@@ -53,28 +52,11 @@
}
def suffix = name.capitalize()
- def jarTask = project.tasks.create(name: "jar${suffix}", type: Jar){
- dependsOn variant.javaCompile
- from variant.javaCompile.destinationDir
- from 'LICENSE.txt'
- }
- def javadocTask = project.tasks.create(name: "javadoc${suffix}", type: Javadoc) {
- source android.sourceSets.main.java
- classpath = files(variant.javaCompile.classpath.files) + files(
- "${android.sdkDirectory}/platforms/${android.compileSdkVersion}/android.jar")
- }
-
- def javadocJarTask = project.tasks.create(name: "javadocJar${suffix}", type: Jar) {
- classifier = 'javadoc'
- from 'build/docs/javadoc'
- }
-
def sourcesJarTask = project.tasks.create(name: "sourceJar${suffix}", type: Jar) {
classifier = 'sources'
from android.sourceSets.main.java.srcDirs
}
- artifacts.add('archives', javadocJarTask);
artifacts.add('archives', sourcesJarTask);
}
diff --git a/recommendation/Android.mk b/recommendation/Android.mk
index 0e0a9d7..67721bb 100644
--- a/recommendation/Android.mk
+++ b/recommendation/Android.mk
@@ -27,6 +27,7 @@
LOCAL_SDK_VERSION := 21
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+LOCAL_MANIFEST_FILE := AndroidManifest-make.xml
LOCAL_SHARED_ANDROID_LIBRARIES := \
android-support-v4 \
android-support-annotations
diff --git a/recommendation/AndroidManifest-make.xml b/recommendation/AndroidManifest-make.xml
new file mode 100644
index 0000000..ef1223e
--- /dev/null
+++ b/recommendation/AndroidManifest-make.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.support.recommendation">
+ <uses-sdk android:minSdkVersion="21"/>
+ <application />
+</manifest>
diff --git a/recommendation/AndroidManifest.xml b/recommendation/AndroidManifest.xml
index ef1223e..e36c822 100644
--- a/recommendation/AndroidManifest.xml
+++ b/recommendation/AndroidManifest.xml
@@ -16,5 +16,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="android.support.recommendation">
<uses-sdk android:minSdkVersion="21"/>
+ <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
<application />
</manifest>
diff --git a/recommendation/build.gradle b/recommendation/build.gradle
index 75d68d1..dadad58 100644
--- a/recommendation/build.gradle
+++ b/recommendation/build.gradle
@@ -1,5 +1,4 @@
apply plugin: 'com.android.library'
-
archivesBaseName = 'recommendation'
dependencies {
@@ -41,27 +40,10 @@
}
def suffix = name.capitalize()
- def jarTask = project.tasks.create(name: "jar${suffix}", type: Jar){
- dependsOn variant.javaCompile
- from variant.javaCompile.destinationDir
- from 'LICENSE.txt'
- }
- def javadocTask = project.tasks.create(name: "javadoc${suffix}", type: Javadoc) {
- source android.sourceSets.main.java
- classpath = files(variant.javaCompile.classpath.files) + files(
- "${android.sdkDirectory}/platforms/${android.compileSdkVersion}/android.jar")
- }
-
- def javadocJarTask = project.tasks.create(name: "javadocJar${suffix}", type: Jar) {
- classifier = 'javadoc'
- from 'build/docs/javadoc'
- }
-
def sourcesJarTask = project.tasks.create(name: "sourceJar${suffix}", type: Jar) {
classifier = 'sources'
from android.sourceSets.main.java.srcDirs
}
- artifacts.add('archives', javadocJarTask);
artifacts.add('archives', sourcesJarTask);
}
diff --git a/transition/Android.mk b/transition/Android.mk
index c468ef1..aefedd7 100644
--- a/transition/Android.mk
+++ b/transition/Android.mk
@@ -34,6 +34,7 @@
$(call all-java-files-under,api23) \
$(call all-java-files-under,src)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+LOCAL_MANIFEST_FILE := AndroidManifest-make.xml
LOCAL_SHARED_ANDROID_LIBRARIES := \
android-support-annotations \
android-support-v4
diff --git a/transition/AndroidManifest-make.xml b/transition/AndroidManifest-make.xml
new file mode 100644
index 0000000..672e1b1
--- /dev/null
+++ b/transition/AndroidManifest-make.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.support.transition">
+ <uses-sdk android:minSdkVersion="14"/>
+ <application />
+</manifest>
diff --git a/transition/AndroidManifest.xml b/transition/AndroidManifest.xml
index 672e1b1..1059f63 100644
--- a/transition/AndroidManifest.xml
+++ b/transition/AndroidManifest.xml
@@ -16,5 +16,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="android.support.transition">
<uses-sdk android:minSdkVersion="14"/>
+ <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
<application />
</manifest>
diff --git a/transition/build.gradle b/transition/build.gradle
index 05675f9..2f47f83 100644
--- a/transition/build.gradle
+++ b/transition/build.gradle
@@ -61,28 +61,11 @@
}
def suffix = name.capitalize()
- def jarTask = project.tasks.create(name: "jar${suffix}", type: Jar){
- dependsOn variant.javaCompile
- from variant.javaCompile.destinationDir
- from 'LICENSE.txt'
- }
- def javadocTask = project.tasks.create(name: "javadoc${suffix}", type: Javadoc) {
- source android.sourceSets.main.java
- classpath = files(variant.javaCompile.classpath.files) + files(
- "${android.sdkDirectory}/platforms/${android.compileSdkVersion}/android.jar")
- }
-
- def javadocJarTask = project.tasks.create(name: "javadocJar${suffix}", type: Jar) {
- classifier = 'javadoc'
- from 'build/docs/javadoc'
- }
-
def sourcesJarTask = project.tasks.create(name: "sourceJar${suffix}", type: Jar) {
classifier = 'sources'
from android.sourceSets.main.java.srcDirs
}
- artifacts.add('archives', javadocJarTask);
artifacts.add('archives', sourcesJarTask);
}
diff --git a/v13/Android.mk b/v13/Android.mk
index 1b30d99..9411930 100644
--- a/v13/Android.mk
+++ b/v13/Android.mk
@@ -34,6 +34,7 @@
$(call all-java-files-under, api25) \
$(call all-java-files-under, java)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+LOCAL_MANIFEST_FILE := AndroidManifest-make.xml
# Some projects expect to inherit android-support-v4 from
# android-support-v13, so we need to keep it static until they can be fixed.
LOCAL_STATIC_ANDROID_LIBRARIES := \
diff --git a/v13/AndroidManifest-make.xml b/v13/AndroidManifest-make.xml
new file mode 100644
index 0000000..ea25a74
--- /dev/null
+++ b/v13/AndroidManifest-make.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ package="android.support.v13">
+ <uses-sdk android:minSdkVersion="13" tools:overrideLibrary="android.support.v13"/>
+ <application />
+</manifest>
diff --git a/v13/AndroidManifest.xml b/v13/AndroidManifest.xml
index ea25a74..7449688 100644
--- a/v13/AndroidManifest.xml
+++ b/v13/AndroidManifest.xml
@@ -17,5 +17,6 @@
xmlns:tools="http://schemas.android.com/tools"
package="android.support.v13">
<uses-sdk android:minSdkVersion="13" tools:overrideLibrary="android.support.v13"/>
+ <meta-data android:name="android.support.VERSION" android:value="${support-version}"/>
<application />
</manifest>
diff --git a/v13/build.gradle b/v13/build.gradle
index 85aa8a8..fb1c25d 100644
--- a/v13/build.gradle
+++ b/v13/build.gradle
@@ -55,28 +55,11 @@
}
def suffix = name.capitalize()
- def jarTask = project.tasks.create(name: "jar${suffix}", type: Jar){
- dependsOn variant.javaCompile
- from variant.javaCompile.destinationDir
- from 'LICENSE.txt'
- }
- def javadocTask = project.tasks.create(name: "javadoc${suffix}", type: Javadoc) {
- source android.sourceSets.main.java
- classpath = files(variant.javaCompile.classpath.files) + files(
- "${android.sdkDirectory}/platforms/${android.compileSdkVersion}/android.jar")
- }
-
- def javadocJarTask = project.tasks.create(name: "javadocJar${suffix}", type: Jar) {
- classifier = 'javadoc'
- from 'build/docs/javadoc'
- }
-
def sourcesJarTask = project.tasks.create(name: "sourceJar${suffix}", type: Jar) {
classifier = 'sources'
from android.sourceSets.main.java.srcDirs
}
- artifacts.add('archives', javadocJarTask);
artifacts.add('archives', sourcesJarTask);
}
diff --git a/v14/preference/Android.mk b/v14/preference/Android.mk
index 7a0b846..195e8a3 100644
--- a/v14/preference/Android.mk
+++ b/v14/preference/Android.mk
@@ -31,6 +31,7 @@
LOCAL_SDK_VERSION := $(SUPPORT_CURRENT_SDK_VERSION)
LOCAL_SRC_FILES := $(call all-java-files-under,src)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+LOCAL_MANIFEST_FILE := AndroidManifest-make.xml
LOCAL_SHARED_ANDROID_LIBRARIES := \
android-support-v7-preference \
android-support-v7-appcompat \
diff --git a/v14/preference/AndroidManifest-make.xml b/v14/preference/AndroidManifest-make.xml
new file mode 100644
index 0000000..b917bb4
--- /dev/null
+++ b/v14/preference/AndroidManifest-make.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.support.v14.preference">
+ <uses-sdk android:minSdkVersion="14" />
+ <application />
+</manifest>
diff --git a/v14/preference/AndroidManifest.xml b/v14/preference/AndroidManifest.xml
index 8b502c9..74cff2e 100644
--- a/v14/preference/AndroidManifest.xml
+++ b/v14/preference/AndroidManifest.xml
@@ -1,8 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 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.
+-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.support.v14.preference"
- android:versionCode="1"
- android:versionName="1.0">
+ package="android.support.v14.preference">
<uses-sdk android:minSdkVersion="14" />
+ <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
<application />
</manifest>
diff --git a/v14/preference/build.gradle b/v14/preference/build.gradle
index a7e63d5..5583e93 100644
--- a/v14/preference/build.gradle
+++ b/v14/preference/build.gradle
@@ -14,10 +14,7 @@
* limitations under the License
*/
-
-
apply plugin: 'com.android.library'
-
archivesBaseName = 'preference-v14'
dependencies {
@@ -62,28 +59,11 @@
}
def suffix = name.capitalize()
- def jarTask = project.tasks.create(name: "jar${suffix}", type: Jar){
- dependsOn variant.javaCompile
- from variant.javaCompile.destinationDir
- from 'LICENSE.txt'
- }
- def javadocTask = project.tasks.create(name: "javadoc${suffix}", type: Javadoc) {
- source android.sourceSets.main.java
- classpath = files(variant.javaCompile.classpath.files) + files(
- "${android.sdkDirectory}/platforms/${android.compileSdkVersion}/android.jar")
- }
-
- def javadocJarTask = project.tasks.create(name: "javadocJar${suffix}", type: Jar) {
- classifier = 'javadoc'
- from 'build/docs/javadoc'
- }
-
def sourcesJarTask = project.tasks.create(name: "sourceJar${suffix}", type: Jar) {
classifier = 'sources'
from android.sourceSets.main.java.srcDirs
}
- artifacts.add('archives', javadocJarTask);
artifacts.add('archives', sourcesJarTask);
}
diff --git a/v17/leanback/Android.mk b/v17/leanback/Android.mk
index c6a50b4..d91436e 100644
--- a/v17/leanback/Android.mk
+++ b/v17/leanback/Android.mk
@@ -35,6 +35,7 @@
$(call all-java-files-under, api23) \
$(call all-java-files-under, src)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+LOCAL_MANIFEST_FILE := AndroidManifest-make.xml
LOCAL_SHARED_ANDROID_LIBRARIES := \
android-support-v7-recyclerview \
android-support-compat \
diff --git a/v17/leanback/AndroidManifest-make.xml b/v17/leanback/AndroidManifest-make.xml
new file mode 100644
index 0000000..20ef094
--- /dev/null
+++ b/v17/leanback/AndroidManifest-make.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.support.v17.leanback">
+ <uses-sdk android:minSdkVersion="17"/>
+ <application />
+</manifest>
diff --git a/v17/leanback/AndroidManifest.xml b/v17/leanback/AndroidManifest.xml
index 20ef094..ded4ce8 100644
--- a/v17/leanback/AndroidManifest.xml
+++ b/v17/leanback/AndroidManifest.xml
@@ -16,5 +16,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="android.support.v17.leanback">
<uses-sdk android:minSdkVersion="17"/>
+ <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
<application />
</manifest>
diff --git a/v17/leanback/build.gradle b/v17/leanback/build.gradle
index f5befa7..9ed65a8 100644
--- a/v17/leanback/build.gradle
+++ b/v17/leanback/build.gradle
@@ -64,28 +64,11 @@
}
def suffix = name.capitalize()
- def jarTask = project.tasks.create(name: "jar${suffix}", type: Jar){
- dependsOn variant.javaCompile
- from variant.javaCompile.destinationDir
- from 'LICENSE.txt'
- }
- def javadocTask = project.tasks.create(name: "javadoc${suffix}", type: Javadoc) {
- source android.sourceSets.main.java
- classpath = files(variant.javaCompile.classpath.files) + files(
- "${android.sdkDirectory}/platforms/${android.compileSdkVersion}/android.jar")
- }
-
- def javadocJarTask = project.tasks.create(name: "javadocJar${suffix}", type: Jar) {
- classifier = 'javadoc'
- from 'build/docs/javadoc'
- }
-
def sourcesJarTask = project.tasks.create(name: "sourceJar${suffix}", type: Jar) {
classifier = 'sources'
from android.sourceSets.main.java.srcDirs
}
- artifacts.add('archives', javadocJarTask);
artifacts.add('archives', sourcesJarTask);
}
diff --git a/v17/leanback/generatev4.py b/v17/leanback/generatev4.py
index 2e1eaeb..9eb5932 100755
--- a/v17/leanback/generatev4.py
+++ b/v17/leanback/generatev4.py
@@ -16,6 +16,7 @@
import os
import sys
+import re
print "Generate v4 fragment related code for leanback"
@@ -41,6 +42,7 @@
line = line.replace('activity.getFragmentManager()', 'activity.getSupportFragmentManager()')
line = line.replace('Activity activity', 'FragmentActivity activity')
line = line.replace('(Activity', '(FragmentActivity')
+ line = re.sub(r'FragmentUtil.getContext\(.*this\)', 'getContext()', line);
outfile.write(line)
file.close()
outfile.close()
diff --git a/v17/leanback/src/android/support/v17/leanback/app/BaseFragment.java b/v17/leanback/src/android/support/v17/leanback/app/BaseFragment.java
index 3b4c851..8ab731f 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/BaseFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/BaseFragment.java
@@ -219,7 +219,7 @@
@Override
public boolean onPreDraw() {
view.getViewTreeObserver().removeOnPreDrawListener(this);
- if (getActivity() == null || getView() == null) {
+ if (FragmentUtil.getContext(BaseFragment.this) == null || getView() == null) {
// bail out if fragment is destroyed immediately after startEntranceTransition
return true;
}
diff --git a/v17/leanback/src/android/support/v17/leanback/app/BaseSupportFragment.java b/v17/leanback/src/android/support/v17/leanback/app/BaseSupportFragment.java
index 8de54a7..7d08738 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/BaseSupportFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/BaseSupportFragment.java
@@ -222,7 +222,7 @@
@Override
public boolean onPreDraw() {
view.getViewTreeObserver().removeOnPreDrawListener(this);
- if (getActivity() == null || getView() == null) {
+ if (getContext() == null || getView() == null) {
// bail out if fragment is destroyed immediately after startEntranceTransition
return true;
}
diff --git a/v17/leanback/src/android/support/v17/leanback/app/BrowseFragment.java b/v17/leanback/src/android/support/v17/leanback/app/BrowseFragment.java
index fc6561e..24b1a85 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/BrowseFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/BrowseFragment.java
@@ -19,6 +19,7 @@
import android.app.FragmentManager;
import android.app.FragmentManager.BackStackEntry;
import android.app.FragmentTransaction;
+import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.Rect;
@@ -1056,12 +1057,13 @@
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- TypedArray ta = getActivity().obtainStyledAttributes(R.styleable.LeanbackTheme);
+ final Context context = FragmentUtil.getContext(this);
+ TypedArray ta = context.obtainStyledAttributes(R.styleable.LeanbackTheme);
mContainerListMarginStart = (int) ta.getDimension(
- R.styleable.LeanbackTheme_browseRowsMarginStart, getActivity().getResources()
+ R.styleable.LeanbackTheme_browseRowsMarginStart, context.getResources()
.getDimensionPixelSize(R.dimen.lb_browse_rows_margin_start));
mContainerListAlignTop = (int) ta.getDimension(
- R.styleable.LeanbackTheme_browseRowsMarginTop, getActivity().getResources()
+ R.styleable.LeanbackTheme_browseRowsMarginTop, context.getResources()
.getDimensionPixelSize(R.dimen.lb_browse_rows_margin_top));
ta.recycle();
@@ -1223,7 +1225,7 @@
}
void createHeadersTransition() {
- mHeadersTransition = TransitionHelper.loadTransition(getActivity(),
+ mHeadersTransition = TransitionHelper.loadTransition(FragmentUtil.getContext(this),
mShowingHeaders
? R.transition.lb_browse_headers_in : R.transition.lb_browse_headers_out);
@@ -1657,7 +1659,7 @@
@Override
protected Object createEntranceTransition() {
- return TransitionHelper.loadTransition(getActivity(),
+ return TransitionHelper.loadTransition(FragmentUtil.getContext(this),
R.transition.lb_browse_entrance_transition);
}
@@ -1740,7 +1742,7 @@
@Override
public boolean onPreDraw() {
- if (getView() == null || getActivity() == null) {
+ if (getView() == null || FragmentUtil.getContext(BrowseFragment.this) == null) {
mView.getViewTreeObserver().removeOnPreDrawListener(this);
return true;
}
diff --git a/v17/leanback/src/android/support/v17/leanback/app/BrowseSupportFragment.java b/v17/leanback/src/android/support/v17/leanback/app/BrowseSupportFragment.java
index 7bcc43d..b73d23d 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/BrowseSupportFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/BrowseSupportFragment.java
@@ -22,6 +22,7 @@
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentManager.BackStackEntry;
import android.support.v4.app.FragmentTransaction;
+import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.Rect;
@@ -1059,12 +1060,13 @@
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- TypedArray ta = getActivity().obtainStyledAttributes(R.styleable.LeanbackTheme);
+ final Context context = getContext();
+ TypedArray ta = context.obtainStyledAttributes(R.styleable.LeanbackTheme);
mContainerListMarginStart = (int) ta.getDimension(
- R.styleable.LeanbackTheme_browseRowsMarginStart, getActivity().getResources()
+ R.styleable.LeanbackTheme_browseRowsMarginStart, context.getResources()
.getDimensionPixelSize(R.dimen.lb_browse_rows_margin_start));
mContainerListAlignTop = (int) ta.getDimension(
- R.styleable.LeanbackTheme_browseRowsMarginTop, getActivity().getResources()
+ R.styleable.LeanbackTheme_browseRowsMarginTop, context.getResources()
.getDimensionPixelSize(R.dimen.lb_browse_rows_margin_top));
ta.recycle();
@@ -1226,7 +1228,7 @@
}
void createHeadersTransition() {
- mHeadersTransition = TransitionHelper.loadTransition(getActivity(),
+ mHeadersTransition = TransitionHelper.loadTransition(getContext(),
mShowingHeaders
? R.transition.lb_browse_headers_in : R.transition.lb_browse_headers_out);
@@ -1660,7 +1662,7 @@
@Override
protected Object createEntranceTransition() {
- return TransitionHelper.loadTransition(getActivity(),
+ return TransitionHelper.loadTransition(getContext(),
R.transition.lb_browse_entrance_transition);
}
@@ -1743,7 +1745,7 @@
@Override
public boolean onPreDraw() {
- if (getView() == null || getActivity() == null) {
+ if (getView() == null || getContext() == null) {
mView.getViewTreeObserver().removeOnPreDrawListener(this);
return true;
}
diff --git a/v17/leanback/src/android/support/v17/leanback/app/DetailsFragment.java b/v17/leanback/src/android/support/v17/leanback/app/DetailsFragment.java
index fcb3fa9..f73cee6 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/DetailsFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/DetailsFragment.java
@@ -473,7 +473,7 @@
@Override
protected Object createEntranceTransition() {
- return TransitionHelper.loadTransition(getActivity(),
+ return TransitionHelper.loadTransition(FragmentUtil.getContext(this),
R.transition.lb_details_enter_transition);
}
diff --git a/v17/leanback/src/android/support/v17/leanback/app/DetailsSupportFragment.java b/v17/leanback/src/android/support/v17/leanback/app/DetailsSupportFragment.java
index a9bbf28..ee63156 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/DetailsSupportFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/DetailsSupportFragment.java
@@ -476,7 +476,7 @@
@Override
protected Object createEntranceTransition() {
- return TransitionHelper.loadTransition(getActivity(),
+ return TransitionHelper.loadTransition(getContext(),
R.transition.lb_details_enter_transition);
}
diff --git a/v17/leanback/src/android/support/v17/leanback/app/FragmentUtil.java b/v17/leanback/src/android/support/v17/leanback/app/FragmentUtil.java
new file mode 100644
index 0000000..23c6039
--- /dev/null
+++ b/v17/leanback/src/android/support/v17/leanback/app/FragmentUtil.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+package android.support.v17.leanback.app;
+
+import android.annotation.TargetApi;
+import android.app.Fragment;
+import android.content.Context;
+import android.os.Build;
+
+class FragmentUtil {
+
+ @TargetApi(23)
+ private static Context getContextNew(Fragment fragment) {
+ return fragment.getContext();
+ }
+
+ public static Context getContext(Fragment fragment) {
+ if (Build.VERSION.SDK_INT >= 23) {
+ return getContextNew(fragment);
+ } else {
+ return fragment.getActivity();
+ }
+ }
+}
diff --git a/v17/leanback/src/android/support/v17/leanback/app/GuidedStepFragment.java b/v17/leanback/src/android/support/v17/leanback/app/GuidedStepFragment.java
index da44fde..bab48bd 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/GuidedStepFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/GuidedStepFragment.java
@@ -1129,7 +1129,7 @@
} else {
// when there are two actions panel, we need adjust the weight of action to
// guidedActionContentWidthWeightTwoPanels.
- Context ctx = mThemeWrapper != null ? mThemeWrapper : getActivity();
+ Context ctx = mThemeWrapper != null ? mThemeWrapper : FragmentUtil.getContext(this);
TypedValue typedValue = new TypedValue();
if (ctx.getTheme().resolveAttribute(R.attr.guidedActionContentWidthWeightTwoPanels,
typedValue, true)) {
@@ -1327,18 +1327,18 @@
private void resolveTheme() {
// Look up the guidedStepTheme in the currently specified theme. If it exists,
// replace the theme with its value.
- Activity activity = getActivity();
+ Context context = FragmentUtil.getContext(this);
int theme = onProvideTheme();
- if (theme == -1 && !isGuidedStepTheme(activity)) {
+ if (theme == -1 && !isGuidedStepTheme(context)) {
// Look up the guidedStepTheme in the activity's currently specified theme. If it
// exists, replace the theme with its value.
int resId = R.attr.guidedStepTheme;
TypedValue typedValue = new TypedValue();
- boolean found = activity.getTheme().resolveAttribute(resId, typedValue, true);
+ boolean found = context.getTheme().resolveAttribute(resId, typedValue, true);
if (DEBUG) Log.v(TAG, "Found guided step theme reference? " + found);
if (found) {
ContextThemeWrapper themeWrapper =
- new ContextThemeWrapper(activity, typedValue.resourceId);
+ new ContextThemeWrapper(context, typedValue.resourceId);
if (isGuidedStepTheme(themeWrapper)) {
mThemeWrapper = themeWrapper;
} else {
@@ -1350,7 +1350,7 @@
Log.e(TAG, "GuidedStepFragment does not have an appropriate theme set.");
}
} else if (theme != -1) {
- mThemeWrapper = new ContextThemeWrapper(activity, theme);
+ mThemeWrapper = new ContextThemeWrapper(context, theme);
}
}
diff --git a/v17/leanback/src/android/support/v17/leanback/app/GuidedStepSupportFragment.java b/v17/leanback/src/android/support/v17/leanback/app/GuidedStepSupportFragment.java
index 32de1fd..f68366c 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/GuidedStepSupportFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/GuidedStepSupportFragment.java
@@ -1132,7 +1132,7 @@
} else {
// when there are two actions panel, we need adjust the weight of action to
// guidedActionContentWidthWeightTwoPanels.
- Context ctx = mThemeWrapper != null ? mThemeWrapper : getActivity();
+ Context ctx = mThemeWrapper != null ? mThemeWrapper : getContext();
TypedValue typedValue = new TypedValue();
if (ctx.getTheme().resolveAttribute(R.attr.guidedActionContentWidthWeightTwoPanels,
typedValue, true)) {
@@ -1330,18 +1330,18 @@
private void resolveTheme() {
// Look up the guidedStepTheme in the currently specified theme. If it exists,
// replace the theme with its value.
- FragmentActivity activity = getActivity();
+ Context context = getContext();
int theme = onProvideTheme();
- if (theme == -1 && !isGuidedStepTheme(activity)) {
+ if (theme == -1 && !isGuidedStepTheme(context)) {
// Look up the guidedStepTheme in the activity's currently specified theme. If it
// exists, replace the theme with its value.
int resId = R.attr.guidedStepTheme;
TypedValue typedValue = new TypedValue();
- boolean found = activity.getTheme().resolveAttribute(resId, typedValue, true);
+ boolean found = context.getTheme().resolveAttribute(resId, typedValue, true);
if (DEBUG) Log.v(TAG, "Found guided step theme reference? " + found);
if (found) {
ContextThemeWrapper themeWrapper =
- new ContextThemeWrapper(activity, typedValue.resourceId);
+ new ContextThemeWrapper(context, typedValue.resourceId);
if (isGuidedStepTheme(themeWrapper)) {
mThemeWrapper = themeWrapper;
} else {
@@ -1353,7 +1353,7 @@
Log.e(TAG, "GuidedStepSupportFragment does not have an appropriate theme set.");
}
} else if (theme != -1) {
- mThemeWrapper = new ContextThemeWrapper(activity, theme);
+ mThemeWrapper = new ContextThemeWrapper(context, theme);
}
}
diff --git a/v17/leanback/src/android/support/v17/leanback/app/ListRowDataAdapter.java b/v17/leanback/src/android/support/v17/leanback/app/ListRowDataAdapter.java
index 1f2788f..f9af12f 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/ListRowDataAdapter.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/ListRowDataAdapter.java
@@ -41,6 +41,7 @@
}
void initialize() {
+ mLastVisibleRowIndex = -1;
int i = mAdapter.size() - 1;
while (i >= 0) {
Row item = (Row) mAdapter.get(i);
@@ -123,7 +124,7 @@
int totalItems = lastVisibleRowIndex - mLastVisibleRowIndex;
if (totalItems > 0) {
onEventFired(ON_ITEM_RANGE_REMOVED,
- Math.min(lastVisibleRowIndex + 1, positionStart),
+ Math.min(mLastVisibleRowIndex + 1, positionStart),
totalItems);
}
}
diff --git a/v17/leanback/src/android/support/v17/leanback/app/OnboardingFragment.java b/v17/leanback/src/android/support/v17/leanback/app/OnboardingFragment.java
index 0459ab6..1baffb4 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/OnboardingFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/OnboardingFragment.java
@@ -22,8 +22,8 @@
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.TimeInterpolator;
-import android.app.Activity;
import android.app.Fragment;
+import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v17.leanback.R;
@@ -267,8 +267,9 @@
mLogoView = (ImageView) view.findViewById(R.id.logo);
mTitleView = (TextView) view.findViewById(R.id.title);
mDescriptionView = (TextView) view.findViewById(R.id.description);
+ final Context context = FragmentUtil.getContext(this);
if (sSlideDistance == 0) {
- sSlideDistance = (int) (SLIDE_DISTANCE * getActivity().getResources()
+ sSlideDistance = (int) (SLIDE_DISTANCE * context.getResources()
.getDisplayMetrics().scaledDensity);
}
if (savedInstanceState == null) {
@@ -312,20 +313,20 @@
}
private void resolveTheme() {
- Activity activity = getActivity();
+ final Context context = FragmentUtil.getContext(this);
int theme = onProvideTheme();
if (theme == -1) {
// Look up the onboardingTheme in the activity's currently specified theme. If it
// exists, wrap the theme with its value.
int resId = R.attr.onboardingTheme;
TypedValue typedValue = new TypedValue();
- boolean found = activity.getTheme().resolveAttribute(resId, typedValue, true);
+ boolean found = context.getTheme().resolveAttribute(resId, typedValue, true);
if (DEBUG) Log.v(TAG, "Found onboarding theme reference? " + found);
if (found) {
- mThemeWrapper = new ContextThemeWrapper(activity, typedValue.resourceId);
+ mThemeWrapper = new ContextThemeWrapper(context, typedValue.resourceId);
}
} else {
- mThemeWrapper = new ContextThemeWrapper(activity, theme);
+ mThemeWrapper = new ContextThemeWrapper(context, theme);
}
}
@@ -366,13 +367,14 @@
}
boolean startLogoAnimation() {
+ final Context context = FragmentUtil.getContext(this);
Animator animator = null;
if (mLogoResourceId != 0) {
mLogoView.setVisibility(View.VISIBLE);
mLogoView.setImageResource(mLogoResourceId);
- Animator inAnimator = AnimatorInflater.loadAnimator(getActivity(),
+ Animator inAnimator = AnimatorInflater.loadAnimator(context,
R.animator.lb_onboarding_logo_enter);
- Animator outAnimator = AnimatorInflater.loadAnimator(getActivity(),
+ Animator outAnimator = AnimatorInflater.loadAnimator(context,
R.animator.lb_onboarding_logo_exit);
outAnimator.setStartDelay(LOGO_SPLASH_PAUSE_DURATION_MS);
AnimatorSet logoAnimator = new AnimatorSet();
@@ -386,7 +388,7 @@
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
- if (getActivity() != null) {
+ if (context != null) {
startEnterAnimation();
}
}
@@ -411,7 +413,8 @@
private void initializeViews(View container) {
mLogoView.setVisibility(View.GONE);
// Create custom views.
- LayoutInflater inflater = getThemeInflater(LayoutInflater.from(getActivity()));
+ LayoutInflater inflater = getThemeInflater(LayoutInflater.from(
+ FragmentUtil.getContext(this)));
ViewGroup backgroundContainer = (ViewGroup) container.findViewById(
R.id.background_container);
View background = onCreateBackgroundView(inflater, backgroundContainer);
@@ -453,22 +456,23 @@
mEnterTransitionFinished = true;
initializeViews(getView());
List<Animator> animators = new ArrayList<>();
- Animator animator = AnimatorInflater.loadAnimator(getActivity(),
+ final Context context = FragmentUtil.getContext(this);
+ Animator animator = AnimatorInflater.loadAnimator(context,
R.animator.lb_onboarding_page_indicator_enter);
animator.setTarget(getPageCount() <= 1 ? mStartButton : mPageIndicator);
animators.add(animator);
// Header title
- View view = getActivity().findViewById(R.id.title);
+ View view = getView().findViewById(R.id.title);
view.setAlpha(0);
- animator = AnimatorInflater.loadAnimator(getActivity(),
+ animator = AnimatorInflater.loadAnimator(context,
R.animator.lb_onboarding_title_enter);
animator.setStartDelay(START_DELAY_TITLE_MS);
animator.setTarget(view);
animators.add(animator);
// Header description
- view = getActivity().findViewById(R.id.description);
+ view = getView().findViewById(R.id.description);
view.setAlpha(0);
- animator = AnimatorInflater.loadAnimator(getActivity(),
+ animator = AnimatorInflater.loadAnimator(context,
R.animator.lb_onboarding_description_enter);
animator.setStartDelay(START_DELAY_DESCRIPTION_MS);
animator.setTarget(view);
@@ -610,10 +614,11 @@
}
});
+ final Context context = FragmentUtil.getContext(this);
// Animator for switching between page indicator and button.
if (getCurrentPageIndex() == getPageCount() - 1) {
mStartButton.setVisibility(View.VISIBLE);
- Animator navigatorFadeOutAnimator = AnimatorInflater.loadAnimator(getActivity(),
+ Animator navigatorFadeOutAnimator = AnimatorInflater.loadAnimator(context,
R.animator.lb_onboarding_page_indicator_fade_out);
navigatorFadeOutAnimator.setTarget(mPageIndicator);
navigatorFadeOutAnimator.addListener(new AnimatorListenerAdapter() {
@@ -623,17 +628,17 @@
}
});
animators.add(navigatorFadeOutAnimator);
- Animator buttonFadeInAnimator = AnimatorInflater.loadAnimator(getActivity(),
+ Animator buttonFadeInAnimator = AnimatorInflater.loadAnimator(context,
R.animator.lb_onboarding_start_button_fade_in);
buttonFadeInAnimator.setTarget(mStartButton);
animators.add(buttonFadeInAnimator);
} else if (previousPage == getPageCount() - 1) {
mPageIndicator.setVisibility(View.VISIBLE);
- Animator navigatorFadeInAnimator = AnimatorInflater.loadAnimator(getActivity(),
+ Animator navigatorFadeInAnimator = AnimatorInflater.loadAnimator(context,
R.animator.lb_onboarding_page_indicator_fade_in);
navigatorFadeInAnimator.setTarget(mPageIndicator);
animators.add(navigatorFadeInAnimator);
- Animator buttonFadeOutAnimator = AnimatorInflater.loadAnimator(getActivity(),
+ Animator buttonFadeOutAnimator = AnimatorInflater.loadAnimator(context,
R.animator.lb_onboarding_start_button_fade_out);
buttonFadeOutAnimator.setTarget(mStartButton);
buttonFadeOutAnimator.addListener(new AnimatorListenerAdapter() {
diff --git a/v17/leanback/src/android/support/v17/leanback/app/OnboardingSupportFragment.java b/v17/leanback/src/android/support/v17/leanback/app/OnboardingSupportFragment.java
index 32163b0..8523a27 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/OnboardingSupportFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/OnboardingSupportFragment.java
@@ -25,8 +25,8 @@
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.TimeInterpolator;
-import android.support.v4.app.FragmentActivity;
import android.support.v4.app.Fragment;
+import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v17.leanback.R;
@@ -270,8 +270,9 @@
mLogoView = (ImageView) view.findViewById(R.id.logo);
mTitleView = (TextView) view.findViewById(R.id.title);
mDescriptionView = (TextView) view.findViewById(R.id.description);
+ final Context context = getContext();
if (sSlideDistance == 0) {
- sSlideDistance = (int) (SLIDE_DISTANCE * getActivity().getResources()
+ sSlideDistance = (int) (SLIDE_DISTANCE * context.getResources()
.getDisplayMetrics().scaledDensity);
}
if (savedInstanceState == null) {
@@ -315,20 +316,20 @@
}
private void resolveTheme() {
- FragmentActivity activity = getActivity();
+ final Context context = getContext();
int theme = onProvideTheme();
if (theme == -1) {
// Look up the onboardingTheme in the activity's currently specified theme. If it
// exists, wrap the theme with its value.
int resId = R.attr.onboardingTheme;
TypedValue typedValue = new TypedValue();
- boolean found = activity.getTheme().resolveAttribute(resId, typedValue, true);
+ boolean found = context.getTheme().resolveAttribute(resId, typedValue, true);
if (DEBUG) Log.v(TAG, "Found onboarding theme reference? " + found);
if (found) {
- mThemeWrapper = new ContextThemeWrapper(activity, typedValue.resourceId);
+ mThemeWrapper = new ContextThemeWrapper(context, typedValue.resourceId);
}
} else {
- mThemeWrapper = new ContextThemeWrapper(activity, theme);
+ mThemeWrapper = new ContextThemeWrapper(context, theme);
}
}
@@ -369,13 +370,14 @@
}
boolean startLogoAnimation() {
+ final Context context = getContext();
Animator animator = null;
if (mLogoResourceId != 0) {
mLogoView.setVisibility(View.VISIBLE);
mLogoView.setImageResource(mLogoResourceId);
- Animator inAnimator = AnimatorInflater.loadAnimator(getActivity(),
+ Animator inAnimator = AnimatorInflater.loadAnimator(context,
R.animator.lb_onboarding_logo_enter);
- Animator outAnimator = AnimatorInflater.loadAnimator(getActivity(),
+ Animator outAnimator = AnimatorInflater.loadAnimator(context,
R.animator.lb_onboarding_logo_exit);
outAnimator.setStartDelay(LOGO_SPLASH_PAUSE_DURATION_MS);
AnimatorSet logoAnimator = new AnimatorSet();
@@ -389,7 +391,7 @@
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
- if (getActivity() != null) {
+ if (context != null) {
startEnterAnimation();
}
}
@@ -414,7 +416,8 @@
private void initializeViews(View container) {
mLogoView.setVisibility(View.GONE);
// Create custom views.
- LayoutInflater inflater = getThemeInflater(LayoutInflater.from(getActivity()));
+ LayoutInflater inflater = getThemeInflater(LayoutInflater.from(
+ getContext()));
ViewGroup backgroundContainer = (ViewGroup) container.findViewById(
R.id.background_container);
View background = onCreateBackgroundView(inflater, backgroundContainer);
@@ -456,22 +459,23 @@
mEnterTransitionFinished = true;
initializeViews(getView());
List<Animator> animators = new ArrayList<>();
- Animator animator = AnimatorInflater.loadAnimator(getActivity(),
+ final Context context = getContext();
+ Animator animator = AnimatorInflater.loadAnimator(context,
R.animator.lb_onboarding_page_indicator_enter);
animator.setTarget(getPageCount() <= 1 ? mStartButton : mPageIndicator);
animators.add(animator);
// Header title
- View view = getActivity().findViewById(R.id.title);
+ View view = getView().findViewById(R.id.title);
view.setAlpha(0);
- animator = AnimatorInflater.loadAnimator(getActivity(),
+ animator = AnimatorInflater.loadAnimator(context,
R.animator.lb_onboarding_title_enter);
animator.setStartDelay(START_DELAY_TITLE_MS);
animator.setTarget(view);
animators.add(animator);
// Header description
- view = getActivity().findViewById(R.id.description);
+ view = getView().findViewById(R.id.description);
view.setAlpha(0);
- animator = AnimatorInflater.loadAnimator(getActivity(),
+ animator = AnimatorInflater.loadAnimator(context,
R.animator.lb_onboarding_description_enter);
animator.setStartDelay(START_DELAY_DESCRIPTION_MS);
animator.setTarget(view);
@@ -613,10 +617,11 @@
}
});
+ final Context context = getContext();
// Animator for switching between page indicator and button.
if (getCurrentPageIndex() == getPageCount() - 1) {
mStartButton.setVisibility(View.VISIBLE);
- Animator navigatorFadeOutAnimator = AnimatorInflater.loadAnimator(getActivity(),
+ Animator navigatorFadeOutAnimator = AnimatorInflater.loadAnimator(context,
R.animator.lb_onboarding_page_indicator_fade_out);
navigatorFadeOutAnimator.setTarget(mPageIndicator);
navigatorFadeOutAnimator.addListener(new AnimatorListenerAdapter() {
@@ -626,17 +631,17 @@
}
});
animators.add(navigatorFadeOutAnimator);
- Animator buttonFadeInAnimator = AnimatorInflater.loadAnimator(getActivity(),
+ Animator buttonFadeInAnimator = AnimatorInflater.loadAnimator(context,
R.animator.lb_onboarding_start_button_fade_in);
buttonFadeInAnimator.setTarget(mStartButton);
animators.add(buttonFadeInAnimator);
} else if (previousPage == getPageCount() - 1) {
mPageIndicator.setVisibility(View.VISIBLE);
- Animator navigatorFadeInAnimator = AnimatorInflater.loadAnimator(getActivity(),
+ Animator navigatorFadeInAnimator = AnimatorInflater.loadAnimator(context,
R.animator.lb_onboarding_page_indicator_fade_in);
navigatorFadeInAnimator.setTarget(mPageIndicator);
animators.add(navigatorFadeInAnimator);
- Animator buttonFadeOutAnimator = AnimatorInflater.loadAnimator(getActivity(),
+ Animator buttonFadeOutAnimator = AnimatorInflater.loadAnimator(context,
R.animator.lb_onboarding_start_button_fade_out);
buttonFadeOutAnimator.setTarget(mStartButton);
buttonFadeOutAnimator.addListener(new AnimatorListenerAdapter() {
diff --git a/v17/leanback/src/android/support/v17/leanback/app/PlaybackFragment.java b/v17/leanback/src/android/support/v17/leanback/app/PlaybackFragment.java
index 02a0257..1058ab1 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/PlaybackFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/PlaybackFragment.java
@@ -452,11 +452,12 @@
}
};
- mBgFadeInAnimator = loadAnimator(getActivity(), R.animator.lb_playback_bg_fade_in);
+ Context context = FragmentUtil.getContext(this);
+ mBgFadeInAnimator = loadAnimator(context, R.animator.lb_playback_bg_fade_in);
mBgFadeInAnimator.addUpdateListener(listener);
mBgFadeInAnimator.addListener(mFadeListener);
- mBgFadeOutAnimator = loadAnimator(getActivity(), R.animator.lb_playback_bg_fade_out);
+ mBgFadeOutAnimator = loadAnimator(context, R.animator.lb_playback_bg_fade_out);
mBgFadeOutAnimator.addUpdateListener(listener);
mBgFadeOutAnimator.addListener(mFadeListener);
}
@@ -498,14 +499,14 @@
}
};
- mControlRowFadeInAnimator = loadAnimator(
- getActivity(), R.animator.lb_playback_controls_fade_in);
+ Context context = FragmentUtil.getContext(this);
+ mControlRowFadeInAnimator = loadAnimator(context, R.animator.lb_playback_controls_fade_in);
mControlRowFadeInAnimator.addUpdateListener(updateListener);
mControlRowFadeInAnimator.addListener(listener);
mControlRowFadeInAnimator.setInterpolator(mLogDecelerateInterpolator);
- mControlRowFadeOutAnimator = loadAnimator(
- getActivity(), R.animator.lb_playback_controls_fade_out);
+ mControlRowFadeOutAnimator = loadAnimator(context,
+ R.animator.lb_playback_controls_fade_out);
mControlRowFadeOutAnimator.addUpdateListener(updateListener);
mControlRowFadeOutAnimator.addListener(listener);
mControlRowFadeOutAnimator.setInterpolator(mLogAccelerateInterpolator);
@@ -543,14 +544,13 @@
}
};
- mOtherRowFadeInAnimator = loadAnimator(
- getActivity(), R.animator.lb_playback_controls_fade_in);
+ Context context = FragmentUtil.getContext(this);
+ mOtherRowFadeInAnimator = loadAnimator(context, R.animator.lb_playback_controls_fade_in);
mOtherRowFadeInAnimator.addListener(listener);
mOtherRowFadeInAnimator.addUpdateListener(updateListener);
mOtherRowFadeInAnimator.setInterpolator(mLogDecelerateInterpolator);
- mOtherRowFadeOutAnimator = loadAnimator(
- getActivity(), R.animator.lb_playback_controls_fade_out);
+ mOtherRowFadeOutAnimator = loadAnimator(context, R.animator.lb_playback_controls_fade_out);
mOtherRowFadeOutAnimator.addListener(listener);
mOtherRowFadeOutAnimator.addUpdateListener(updateListener);
mOtherRowFadeOutAnimator.setInterpolator(new AccelerateInterpolator());
@@ -808,7 +808,6 @@
/**
* This listener is called every time there is a selection in {@link RowsFragment}. This can
* be used by users to take additional actions such as animations.
- * @hide
*/
public void setOnItemViewSelectedListener(final BaseOnItemViewSelectedListener listener) {
mExternalItemSelectedListener = listener;
diff --git a/v17/leanback/src/android/support/v17/leanback/app/PlaybackOverlayFragment.java b/v17/leanback/src/android/support/v17/leanback/app/PlaybackOverlayFragment.java
index 33e35eb..3b8cfd3 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/PlaybackOverlayFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/PlaybackOverlayFragment.java
@@ -433,11 +433,12 @@
}
};
- mBgFadeInAnimator = loadAnimator(getActivity(), R.animator.lb_playback_bg_fade_in);
+ Context context = FragmentUtil.getContext(this);
+ mBgFadeInAnimator = loadAnimator(context, R.animator.lb_playback_bg_fade_in);
mBgFadeInAnimator.addUpdateListener(listener);
mBgFadeInAnimator.addListener(mFadeListener);
- mBgFadeOutAnimator = loadAnimator(getActivity(), R.animator.lb_playback_bg_fade_out);
+ mBgFadeOutAnimator = loadAnimator(context, R.animator.lb_playback_bg_fade_out);
mBgFadeOutAnimator.addUpdateListener(listener);
mBgFadeOutAnimator.addListener(mFadeListener);
}
@@ -479,14 +480,14 @@
}
};
- mControlRowFadeInAnimator = loadAnimator(
- getActivity(), R.animator.lb_playback_controls_fade_in);
+ Context context = FragmentUtil.getContext(this);
+ mControlRowFadeInAnimator = loadAnimator(context, R.animator.lb_playback_controls_fade_in);
mControlRowFadeInAnimator.addUpdateListener(updateListener);
mControlRowFadeInAnimator.addListener(listener);
mControlRowFadeInAnimator.setInterpolator(mLogDecelerateInterpolator);
- mControlRowFadeOutAnimator = loadAnimator(
- getActivity(), R.animator.lb_playback_controls_fade_out);
+ mControlRowFadeOutAnimator = loadAnimator(context,
+ R.animator.lb_playback_controls_fade_out);
mControlRowFadeOutAnimator.addUpdateListener(updateListener);
mControlRowFadeOutAnimator.addListener(listener);
mControlRowFadeOutAnimator.setInterpolator(mLogAccelerateInterpolator);
@@ -524,14 +525,13 @@
}
};
- mOtherRowFadeInAnimator = loadAnimator(
- getActivity(), R.animator.lb_playback_controls_fade_in);
+ Context context = FragmentUtil.getContext(this);
+ mOtherRowFadeInAnimator = loadAnimator(context, R.animator.lb_playback_controls_fade_in);
mOtherRowFadeInAnimator.addListener(listener);
mOtherRowFadeInAnimator.addUpdateListener(updateListener);
mOtherRowFadeInAnimator.setInterpolator(mLogDecelerateInterpolator);
- mOtherRowFadeOutAnimator = loadAnimator(
- getActivity(), R.animator.lb_playback_controls_fade_out);
+ mOtherRowFadeOutAnimator = loadAnimator(context, R.animator.lb_playback_controls_fade_out);
mOtherRowFadeOutAnimator.addListener(listener);
mOtherRowFadeOutAnimator.addUpdateListener(updateListener);
mOtherRowFadeOutAnimator.setInterpolator(new AccelerateInterpolator());
@@ -557,13 +557,14 @@
}
};
- mDescriptionFadeInAnimator = loadAnimator(
- getActivity(), R.animator.lb_playback_description_fade_in);
+ Context context = FragmentUtil.getContext(this);
+ mDescriptionFadeInAnimator = loadAnimator(context,
+ R.animator.lb_playback_description_fade_in);
mDescriptionFadeInAnimator.addUpdateListener(listener);
mDescriptionFadeInAnimator.setInterpolator(mLogDecelerateInterpolator);
- mDescriptionFadeOutAnimator = loadAnimator(
- getActivity(), R.animator.lb_playback_description_fade_out);
+ mDescriptionFadeOutAnimator = loadAnimator(context,
+ R.animator.lb_playback_description_fade_out);
mDescriptionFadeOutAnimator.addUpdateListener(listener);
}
diff --git a/v17/leanback/src/android/support/v17/leanback/app/PlaybackOverlaySupportFragment.java b/v17/leanback/src/android/support/v17/leanback/app/PlaybackOverlaySupportFragment.java
index d41d65f..b58a2ad 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/PlaybackOverlaySupportFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/PlaybackOverlaySupportFragment.java
@@ -436,11 +436,12 @@
}
};
- mBgFadeInAnimator = loadAnimator(getActivity(), R.animator.lb_playback_bg_fade_in);
+ Context context = getContext();
+ mBgFadeInAnimator = loadAnimator(context, R.animator.lb_playback_bg_fade_in);
mBgFadeInAnimator.addUpdateListener(listener);
mBgFadeInAnimator.addListener(mFadeListener);
- mBgFadeOutAnimator = loadAnimator(getActivity(), R.animator.lb_playback_bg_fade_out);
+ mBgFadeOutAnimator = loadAnimator(context, R.animator.lb_playback_bg_fade_out);
mBgFadeOutAnimator.addUpdateListener(listener);
mBgFadeOutAnimator.addListener(mFadeListener);
}
@@ -482,14 +483,14 @@
}
};
- mControlRowFadeInAnimator = loadAnimator(
- getActivity(), R.animator.lb_playback_controls_fade_in);
+ Context context = getContext();
+ mControlRowFadeInAnimator = loadAnimator(context, R.animator.lb_playback_controls_fade_in);
mControlRowFadeInAnimator.addUpdateListener(updateListener);
mControlRowFadeInAnimator.addListener(listener);
mControlRowFadeInAnimator.setInterpolator(mLogDecelerateInterpolator);
- mControlRowFadeOutAnimator = loadAnimator(
- getActivity(), R.animator.lb_playback_controls_fade_out);
+ mControlRowFadeOutAnimator = loadAnimator(context,
+ R.animator.lb_playback_controls_fade_out);
mControlRowFadeOutAnimator.addUpdateListener(updateListener);
mControlRowFadeOutAnimator.addListener(listener);
mControlRowFadeOutAnimator.setInterpolator(mLogAccelerateInterpolator);
@@ -527,14 +528,13 @@
}
};
- mOtherRowFadeInAnimator = loadAnimator(
- getActivity(), R.animator.lb_playback_controls_fade_in);
+ Context context = getContext();
+ mOtherRowFadeInAnimator = loadAnimator(context, R.animator.lb_playback_controls_fade_in);
mOtherRowFadeInAnimator.addListener(listener);
mOtherRowFadeInAnimator.addUpdateListener(updateListener);
mOtherRowFadeInAnimator.setInterpolator(mLogDecelerateInterpolator);
- mOtherRowFadeOutAnimator = loadAnimator(
- getActivity(), R.animator.lb_playback_controls_fade_out);
+ mOtherRowFadeOutAnimator = loadAnimator(context, R.animator.lb_playback_controls_fade_out);
mOtherRowFadeOutAnimator.addListener(listener);
mOtherRowFadeOutAnimator.addUpdateListener(updateListener);
mOtherRowFadeOutAnimator.setInterpolator(new AccelerateInterpolator());
@@ -560,13 +560,14 @@
}
};
- mDescriptionFadeInAnimator = loadAnimator(
- getActivity(), R.animator.lb_playback_description_fade_in);
+ Context context = getContext();
+ mDescriptionFadeInAnimator = loadAnimator(context,
+ R.animator.lb_playback_description_fade_in);
mDescriptionFadeInAnimator.addUpdateListener(listener);
mDescriptionFadeInAnimator.setInterpolator(mLogDecelerateInterpolator);
- mDescriptionFadeOutAnimator = loadAnimator(
- getActivity(), R.animator.lb_playback_description_fade_out);
+ mDescriptionFadeOutAnimator = loadAnimator(context,
+ R.animator.lb_playback_description_fade_out);
mDescriptionFadeOutAnimator.addUpdateListener(listener);
}
diff --git a/v17/leanback/src/android/support/v17/leanback/app/PlaybackSupportFragment.java b/v17/leanback/src/android/support/v17/leanback/app/PlaybackSupportFragment.java
index 07701f9..b812004 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/PlaybackSupportFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/PlaybackSupportFragment.java
@@ -455,11 +455,12 @@
}
};
- mBgFadeInAnimator = loadAnimator(getActivity(), R.animator.lb_playback_bg_fade_in);
+ Context context = getContext();
+ mBgFadeInAnimator = loadAnimator(context, R.animator.lb_playback_bg_fade_in);
mBgFadeInAnimator.addUpdateListener(listener);
mBgFadeInAnimator.addListener(mFadeListener);
- mBgFadeOutAnimator = loadAnimator(getActivity(), R.animator.lb_playback_bg_fade_out);
+ mBgFadeOutAnimator = loadAnimator(context, R.animator.lb_playback_bg_fade_out);
mBgFadeOutAnimator.addUpdateListener(listener);
mBgFadeOutAnimator.addListener(mFadeListener);
}
@@ -501,14 +502,14 @@
}
};
- mControlRowFadeInAnimator = loadAnimator(
- getActivity(), R.animator.lb_playback_controls_fade_in);
+ Context context = getContext();
+ mControlRowFadeInAnimator = loadAnimator(context, R.animator.lb_playback_controls_fade_in);
mControlRowFadeInAnimator.addUpdateListener(updateListener);
mControlRowFadeInAnimator.addListener(listener);
mControlRowFadeInAnimator.setInterpolator(mLogDecelerateInterpolator);
- mControlRowFadeOutAnimator = loadAnimator(
- getActivity(), R.animator.lb_playback_controls_fade_out);
+ mControlRowFadeOutAnimator = loadAnimator(context,
+ R.animator.lb_playback_controls_fade_out);
mControlRowFadeOutAnimator.addUpdateListener(updateListener);
mControlRowFadeOutAnimator.addListener(listener);
mControlRowFadeOutAnimator.setInterpolator(mLogAccelerateInterpolator);
@@ -546,14 +547,13 @@
}
};
- mOtherRowFadeInAnimator = loadAnimator(
- getActivity(), R.animator.lb_playback_controls_fade_in);
+ Context context = getContext();
+ mOtherRowFadeInAnimator = loadAnimator(context, R.animator.lb_playback_controls_fade_in);
mOtherRowFadeInAnimator.addListener(listener);
mOtherRowFadeInAnimator.addUpdateListener(updateListener);
mOtherRowFadeInAnimator.setInterpolator(mLogDecelerateInterpolator);
- mOtherRowFadeOutAnimator = loadAnimator(
- getActivity(), R.animator.lb_playback_controls_fade_out);
+ mOtherRowFadeOutAnimator = loadAnimator(context, R.animator.lb_playback_controls_fade_out);
mOtherRowFadeOutAnimator.addListener(listener);
mOtherRowFadeOutAnimator.addUpdateListener(updateListener);
mOtherRowFadeOutAnimator.setInterpolator(new AccelerateInterpolator());
@@ -811,7 +811,6 @@
/**
* This listener is called every time there is a selection in {@link RowsSupportFragment}. This can
* be used by users to take additional actions such as animations.
- * @hide
*/
public void setOnItemViewSelectedListener(final BaseOnItemViewSelectedListener listener) {
mExternalItemSelectedListener = listener;
diff --git a/v17/leanback/src/android/support/v17/leanback/app/SearchFragment.java b/v17/leanback/src/android/support/v17/leanback/app/SearchFragment.java
index 93886f9..d2b9bb1 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/SearchFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/SearchFragment.java
@@ -391,7 +391,8 @@
super.onResume();
mIsPaused = false;
if (mSpeechRecognitionCallback == null && null == mSpeechRecognizer) {
- mSpeechRecognizer = SpeechRecognizer.createSpeechRecognizer(getActivity());
+ mSpeechRecognizer = SpeechRecognizer.createSpeechRecognizer(
+ FragmentUtil.getContext(this));
mSearchBar.setSpeechRecognizer(mSpeechRecognizer);
}
if (mPendingStartRecognitionWhenPaused) {
diff --git a/v17/leanback/src/android/support/v17/leanback/app/SearchSupportFragment.java b/v17/leanback/src/android/support/v17/leanback/app/SearchSupportFragment.java
index c8a058d..b870d79 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/SearchSupportFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/SearchSupportFragment.java
@@ -394,7 +394,8 @@
super.onResume();
mIsPaused = false;
if (mSpeechRecognitionCallback == null && null == mSpeechRecognizer) {
- mSpeechRecognizer = SpeechRecognizer.createSpeechRecognizer(getActivity());
+ mSpeechRecognizer = SpeechRecognizer.createSpeechRecognizer(
+ getContext());
mSearchBar.setSpeechRecognizer(mSpeechRecognizer);
}
if (mPendingStartRecognitionWhenPaused) {
diff --git a/v17/leanback/src/android/support/v17/leanback/app/VerticalGridFragment.java b/v17/leanback/src/android/support/v17/leanback/app/VerticalGridFragment.java
index b8f3df2..cfa27df 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/VerticalGridFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/VerticalGridFragment.java
@@ -13,9 +13,11 @@
*/
package android.support.v17.leanback.app;
+import android.os.Bundle;
import android.support.v17.leanback.R;
import android.support.v17.leanback.transition.TransitionHelper;
import android.support.v17.leanback.widget.BrowseFrameLayout;
+import android.support.v17.leanback.widget.ObjectAdapter;
import android.support.v17.leanback.widget.OnChildLaidOutListener;
import android.support.v17.leanback.widget.OnItemViewClickedListener;
import android.support.v17.leanback.widget.OnItemViewSelectedListener;
@@ -23,8 +25,6 @@
import android.support.v17.leanback.widget.Row;
import android.support.v17.leanback.widget.RowPresenter;
import android.support.v17.leanback.widget.VerticalGridPresenter;
-import android.support.v17.leanback.widget.ObjectAdapter;
-import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
@@ -223,7 +223,7 @@
@Override
protected Object createEntranceTransition() {
- return TransitionHelper.loadTransition(getActivity(),
+ return TransitionHelper.loadTransition(FragmentUtil.getContext(this),
R.transition.lb_vertical_grid_entrance_transition);
}
diff --git a/v17/leanback/src/android/support/v17/leanback/app/VerticalGridSupportFragment.java b/v17/leanback/src/android/support/v17/leanback/app/VerticalGridSupportFragment.java
index 2a87f10..55e079d 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/VerticalGridSupportFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/VerticalGridSupportFragment.java
@@ -16,9 +16,11 @@
*/
package android.support.v17.leanback.app;
+import android.os.Bundle;
import android.support.v17.leanback.R;
import android.support.v17.leanback.transition.TransitionHelper;
import android.support.v17.leanback.widget.BrowseFrameLayout;
+import android.support.v17.leanback.widget.ObjectAdapter;
import android.support.v17.leanback.widget.OnChildLaidOutListener;
import android.support.v17.leanback.widget.OnItemViewClickedListener;
import android.support.v17.leanback.widget.OnItemViewSelectedListener;
@@ -26,8 +28,6 @@
import android.support.v17.leanback.widget.Row;
import android.support.v17.leanback.widget.RowPresenter;
import android.support.v17.leanback.widget.VerticalGridPresenter;
-import android.support.v17.leanback.widget.ObjectAdapter;
-import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
@@ -226,7 +226,7 @@
@Override
protected Object createEntranceTransition() {
- return TransitionHelper.loadTransition(getActivity(),
+ return TransitionHelper.loadTransition(getContext(),
R.transition.lb_vertical_grid_entrance_transition);
}
diff --git a/v17/leanback/src/android/support/v17/leanback/app/VideoFragment.java b/v17/leanback/src/android/support/v17/leanback/app/VideoFragment.java
index fa9989e..9906813 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/VideoFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/VideoFragment.java
@@ -39,7 +39,7 @@
public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
ViewGroup root = (ViewGroup) super.onCreateView(inflater, container, savedInstanceState);
- mVideoSurface = (SurfaceView) getActivity().getLayoutInflater().inflate(
+ mVideoSurface = (SurfaceView) LayoutInflater.from(FragmentUtil.getContext(this)).inflate(
R.layout.lb_video_surface, root, false);
root.addView(mVideoSurface, 0);
mVideoSurface.getHolder().addCallback(new SurfaceHolder.Callback() {
diff --git a/v17/leanback/src/android/support/v17/leanback/app/VideoSupportFragment.java b/v17/leanback/src/android/support/v17/leanback/app/VideoSupportFragment.java
index 0f76e6e..29f1faf 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/VideoSupportFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/VideoSupportFragment.java
@@ -42,7 +42,7 @@
public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
ViewGroup root = (ViewGroup) super.onCreateView(inflater, container, savedInstanceState);
- mVideoSurface = (SurfaceView) getActivity().getLayoutInflater().inflate(
+ mVideoSurface = (SurfaceView) LayoutInflater.from(getContext()).inflate(
R.layout.lb_video_surface, root, false);
root.addView(mVideoSurface, 0);
mVideoSurface.getHolder().addCallback(new SurfaceHolder.Callback() {
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/Grid.java b/v17/leanback/src/android/support/v17/leanback/widget/Grid.java
index 64d151f..eb09225 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/Grid.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/Grid.java
@@ -13,7 +13,10 @@
*/
package android.support.v17.leanback.widget;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
import android.support.v4.util.CircularIntArray;
+import android.support.v7.widget.RecyclerView;
import java.io.PrintWriter;
@@ -259,7 +262,7 @@
* Finds the largest or smallest row min edge of visible items,
* the row index is returned in indices[0], the item index is returned in indices[1].
*/
- public final int findRowMin(boolean findLarge, int[] indices) {
+ public final int findRowMin(boolean findLarge, @Nullable int[] indices) {
return findRowMin(findLarge, mReversedFlow ? mLastVisibleIndex : mFirstVisibleIndex,
indices);
}
@@ -274,7 +277,7 @@
* Finds the largest or smallest row max edge of visible items, the row index is returned in
* indices[0], the item index is returned in indices[1].
*/
- public final int findRowMax(boolean findLarge, int[] indices) {
+ public final int findRowMax(boolean findLarge, @Nullable int[] indices) {
return findRowMax(findLarge, mReversedFlow ? mFirstVisibleIndex : mLastVisibleIndex,
indices);
}
@@ -422,5 +425,12 @@
}
}
+ /**
+ * Queries items adjacent to the viewport (in the direction of da) into the prefetch registry.
+ */
+ public void collectAdjacentPrefetchPositions(int fromLimit, int da,
+ @NonNull RecyclerView.LayoutManager.LayoutPrefetchRegistry layoutPrefetchRegistry) {
+ }
+
public abstract void debugPrint(PrintWriter pw);
}
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/GridLayoutManager.java b/v17/leanback/src/android/support/v17/leanback/widget/GridLayoutManager.java
index 580f01b..a2f99e2 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/GridLayoutManager.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/GridLayoutManager.java
@@ -2154,6 +2154,26 @@
return dy;
}
+ @Override
+ public void collectAdjacentPrefetchPositions(int dx, int dy, State state,
+ LayoutPrefetchRegistry layoutPrefetchRegistry) {
+ try {
+ saveContext(null, state);
+ int da = (mOrientation == HORIZONTAL) ? dx : dy;
+ if (getChildCount() == 0 || da == 0) {
+ // can't support this scroll, so don't bother prefetching
+ return;
+ }
+
+ int fromLimit = da < 0
+ ? -mExtraLayoutSpace
+ : mSizePrimary + mExtraLayoutSpace;
+ mGrid.collectAdjacentPrefetchPositions(fromLimit, da, layoutPrefetchRegistry);
+ } finally {
+ leaveContext();
+ }
+ }
+
void updateScrollMax() {
int highVisiblePos = (!mReverseFlowPrimary) ? mGrid.getLastVisibleIndex()
: mGrid.getFirstVisibleIndex();
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/SingleRow.java b/v17/leanback/src/android/support/v17/leanback/widget/SingleRow.java
index 0300c6f..04a384a 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/SingleRow.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/SingleRow.java
@@ -13,7 +13,9 @@
*/
package android.support.v17.leanback.widget;
+import android.support.annotation.NonNull;
import android.support.v4.util.CircularIntArray;
+import android.support.v7.widget.RecyclerView;
import java.io.PrintWriter;
@@ -131,6 +133,36 @@
}
@Override
+ public void collectAdjacentPrefetchPositions(int fromLimit, int da,
+ @NonNull RecyclerView.LayoutManager.LayoutPrefetchRegistry layoutPrefetchRegistry) {
+ int indexToPrefetch;
+ int nearestEdge;
+ if (mReversedFlow ? da > 0 : da < 0) {
+ // prefetch next prepend, lower index number
+ if (getFirstVisibleIndex() == 0) {
+ return; // no remaining items to prefetch
+ }
+
+ indexToPrefetch = getStartIndexForPrepend();
+ nearestEdge = mProvider.getEdge(mFirstVisibleIndex)
+ + (mReversedFlow ? mSpacing : -mSpacing);
+ } else {
+ // prefetch next append, higher index number
+ if (getLastVisibleIndex() == mProvider.getCount() - 1) {
+ return; // no remaining items to prefetch
+ }
+
+ indexToPrefetch = getStartIndexForAppend();
+ int itemSizeWithSpace = mProvider.getSize(mLastVisibleIndex) + mSpacing;
+ nearestEdge = mProvider.getEdge(mLastVisibleIndex)
+ + (mReversedFlow ? -itemSizeWithSpace : itemSizeWithSpace);
+ }
+
+ int distance = Math.abs(nearestEdge - fromLimit);
+ layoutPrefetchRegistry.addPosition(indexToPrefetch, distance);
+ }
+
+ @Override
public final CircularIntArray[] getItemPositionsInRows(int startPos, int endPos) {
// all items are on the same row:
mTmpItemPositionsInRows[0].clear();
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/ListRowDataAdapterTest.java b/v17/leanback/tests/java/android/support/v17/leanback/app/ListRowDataAdapterTest.java
index b7cb4e8..0b40920 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/ListRowDataAdapterTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/ListRowDataAdapterTest.java
@@ -197,6 +197,48 @@
}
@Test
+ public void adapterSize_rowsRemoveAll() {
+ ArrayObjectAdapter adapter = new ArrayObjectAdapter(presenterSelector);
+ adapter.add(new SectionRow("section 1"));
+ for (int i = 0; i < 4; i++) {
+ HeaderItem headerItem = new HeaderItem(i, "header "+i);
+ adapter.add(new ListRow(headerItem, createListRowAdapter()));
+ }
+
+ ListRowDataAdapter listRowDataAdapter = new ListRowDataAdapter(adapter);
+ assertEquals(5, listRowDataAdapter.size());
+
+ adapter.clear();
+ assertEquals(0, listRowDataAdapter.size());
+
+ HeaderItem headerItem = new HeaderItem(10, "header "+10);
+ adapter.add(new ListRow(headerItem, createListRowAdapter()));
+ assertEquals(1, listRowDataAdapter.size());
+ }
+
+ @Test
+ public void changeRemove_revealInvisibleItems() {
+ ArrayObjectAdapter adapter = new ArrayObjectAdapter(presenterSelector);
+ for (int i = 0; i < 4; i++) {
+ HeaderItem headerItem = new HeaderItem(i, "header "+i);
+ adapter.add(new ListRow(headerItem, createListRowAdapter()));
+ }
+ adapter.add(new SectionRow("section"));
+ for (int i = 4; i < 8; i++) {
+ HeaderItem headerItem = new HeaderItem(i, "header "+i);
+ adapter.add(new ListRow(headerItem, createListRowAdapter()));
+ }
+
+ ListRowDataAdapter listRowDataAdapter = new ListRowDataAdapter(adapter);
+ assertEquals(9, listRowDataAdapter.size());
+
+ listRowDataAdapter.registerObserver(dataObserver);
+ adapter.removeItems(5, 4);
+ verify(dataObserver, times(1)).onItemRangeRemoved(4, 5);
+ assertEquals(4, listRowDataAdapter.size());
+ }
+
+ @Test
public void adapterSize_rowsRemoved() {
int itemCount = 4;
ArrayObjectAdapter adapter = new ArrayObjectAdapter(presenterSelector);
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/widget/GridWidgetPrefetchTest.java b/v17/leanback/tests/java/android/support/v17/leanback/widget/GridWidgetPrefetchTest.java
new file mode 100644
index 0000000..c50aa67
--- /dev/null
+++ b/v17/leanback/tests/java/android/support/v17/leanback/widget/GridWidgetPrefetchTest.java
@@ -0,0 +1,177 @@
+package android.support.v17.leanback.widget;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.v7.widget.RecyclerView;
+import android.view.View;
+import android.view.ViewGroup;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class GridWidgetPrefetchTest {
+
+ private Context getContext() {
+ return InstrumentationRegistry.getContext();
+ }
+
+ private void layout(View view, int width, int height) {
+ view.measure(
+ View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY),
+ View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY));
+ view.layout(0, 0, width, height);
+ }
+
+ public void validatePrefetch(BaseGridView gridView, int scrollX, int scrollY,
+ Integer[]... positionData) {
+ // duplicates logic in support.v7.widget.CacheUtils#verifyPositionsPrefetched
+ RecyclerView.State state = mock(RecyclerView.State.class);
+ when(state.getItemCount()).thenReturn(gridView.getAdapter().getItemCount());
+ RecyclerView.LayoutManager.LayoutPrefetchRegistry registry
+ = mock(RecyclerView.LayoutManager.LayoutPrefetchRegistry.class);
+
+ gridView.getLayoutManager().collectAdjacentPrefetchPositions(scrollX, scrollY,
+ state, registry);
+
+ verify(registry, times(positionData.length)).addPosition(anyInt(), anyInt());
+ for (Integer[] aPositionData : positionData) {
+ verify(registry).addPosition(aPositionData[0], aPositionData[1]);
+ }
+ }
+
+ private RecyclerView.Adapter createBoxAdapter() {
+ return new RecyclerView.Adapter() {
+ @Override
+ public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ View view = new View(getContext());
+ view.setMinimumWidth(100);
+ view.setMinimumHeight(100);
+ return new RecyclerView.ViewHolder(view) {};
+ }
+
+ @Override
+ public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
+ // noop
+ }
+
+ @Override
+ public int getItemCount() {
+ return 100;
+ }
+ };
+ }
+
+ @Test
+ public void prefetch() {
+ HorizontalGridView gridView = new HorizontalGridView(getContext());
+ gridView.setNumRows(1);
+ gridView.setRowHeight(100);
+ gridView.setAdapter(createBoxAdapter());
+
+ layout(gridView, 150, 100);
+
+ // validate 2 children in viewport
+ assertEquals(2, gridView.getChildCount());
+ assertEquals(0, gridView.getLayoutManager().findViewByPosition(0).getLeft());
+ assertEquals(100, gridView.getLayoutManager().findViewByPosition(1).getLeft());
+
+ validatePrefetch(gridView, -50, 0); // no view to left
+ validatePrefetch(gridView, 50, 0, new Integer[] {2, 50}); // next view 50 pixels to right
+
+ // scroll to position 5, and layout
+ gridView.scrollToPosition(5);
+ layout(gridView, 150, 100);
+
+ /* Visual representation, each number column represents 25 pixels:
+ * | |
+ * ... 3 3 4 4 4|4 5 5 5 5 6|6 6 6 7 7 ...
+ * | |
+ */
+
+ // validate the 3 children in the viewport, and their positions
+ assertEquals(3, gridView.getChildCount());
+ assertNotNull(gridView.getLayoutManager().findViewByPosition(4));
+ assertNotNull(gridView.getLayoutManager().findViewByPosition(5));
+ assertNotNull(gridView.getLayoutManager().findViewByPosition(6));
+ assertEquals(-75, gridView.getLayoutManager().findViewByPosition(4).getLeft());
+ assertEquals(25, gridView.getLayoutManager().findViewByPosition(5).getLeft());
+ assertEquals(125, gridView.getLayoutManager().findViewByPosition(6).getLeft());
+
+ // next views are 75 pixels to right and left:
+ validatePrefetch(gridView, -50, 0, new Integer[] {3, 75});
+ validatePrefetch(gridView, 50, 0, new Integer[] {7, 75});
+
+ // no views returned for vertical prefetch:
+ validatePrefetch(gridView, 0, 10);
+ validatePrefetch(gridView, 0, -10);
+
+ // test minor offset
+ gridView.scrollBy(5, 0);
+ validatePrefetch(gridView, -50, 0, new Integer[] {3, 80});
+ validatePrefetch(gridView, 50, 0, new Integer[] {7, 70});
+ }
+
+ @Test
+ public void prefetchRtl() {
+ HorizontalGridView gridView = new HorizontalGridView(getContext());
+ gridView.setNumRows(1);
+ gridView.setRowHeight(100);
+ gridView.setAdapter(createBoxAdapter());
+ gridView.setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
+
+ layout(gridView, 150, 100);
+
+ // validate 2 children in viewport
+ assertEquals(2, gridView.getChildCount());
+ assertEquals(50, gridView.getLayoutManager().findViewByPosition(0).getLeft());
+ assertEquals(-50, gridView.getLayoutManager().findViewByPosition(1).getLeft());
+
+ validatePrefetch(gridView, 50, 0); // no view to right
+ validatePrefetch(gridView, -10, 0, new Integer[] {2, 50}); // next view 50 pixels to right
+
+
+ // scroll to position 5, and layout
+ gridView.scrollToPosition(5);
+ layout(gridView, 150, 100);
+
+
+ /* Visual representation, each number column represents 25 pixels:
+ * | |
+ * ... 7 7 6 6 6|6 5 5 5 5 4|4 4 4 3 3 ...
+ * | |
+ */
+ // validate 3 children in the viewport
+ assertEquals(3, gridView.getChildCount());
+ assertNotNull(gridView.getLayoutManager().findViewByPosition(6));
+ assertNotNull(gridView.getLayoutManager().findViewByPosition(5));
+ assertNotNull(gridView.getLayoutManager().findViewByPosition(4));
+ assertEquals(-75, gridView.getLayoutManager().findViewByPosition(6).getLeft());
+ assertEquals(25, gridView.getLayoutManager().findViewByPosition(5).getLeft());
+ assertEquals(125, gridView.getLayoutManager().findViewByPosition(4).getLeft());
+
+ // next views are 75 pixels to right and left:
+ validatePrefetch(gridView, 50, 0, new Integer[] {3, 75});
+ validatePrefetch(gridView, -50, 0, new Integer[] {7, 75});
+
+ // no views returned for vertical prefetch:
+ validatePrefetch(gridView, 0, 10);
+ validatePrefetch(gridView, 0, -10);
+
+ // test minor offset
+ gridView.scrollBy(-5, 0);
+ validatePrefetch(gridView, 50, 0, new Integer[] {3, 80});
+ validatePrefetch(gridView, -50, 0, new Integer[] {7, 70});
+ }
+}
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/widget/SingleRowTest.java b/v17/leanback/tests/java/android/support/v17/leanback/widget/SingleRowTest.java
index 82261d1..373cb81 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/widget/SingleRowTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/widget/SingleRowTest.java
@@ -16,9 +16,14 @@
package android.support.v17.leanback.widget;
import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
+import android.support.v7.widget.RecyclerView;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -30,7 +35,7 @@
@RunWith(AndroidJUnit4.class)
public class SingleRowTest extends GridTest {
- SingleRow mSingleRow;
+ private SingleRow mSingleRow;
@Test
public void testAppendPrependRemove() {
@@ -161,4 +166,97 @@
mSingleRow.prependVisibleItems(0);
assertEquals(dump(mSingleRow) + " Should not prepend 0", 1, mSingleRow.mFirstVisibleIndex);
}
+
+ public void validatePrefetch(int fromLimit, int delta, Integer[]... positionData) {
+ // duplicates logic in support.v7.widget.CacheUtils#verifyPositionsPrefetched
+ RecyclerView.LayoutManager.LayoutPrefetchRegistry registry
+ = mock(RecyclerView.LayoutManager.LayoutPrefetchRegistry.class);
+ mSingleRow.collectAdjacentPrefetchPositions(fromLimit, delta, registry);
+
+ verify(registry, times(positionData.length)).addPosition(anyInt(), anyInt());
+ for (Integer[] aPositionData : positionData) {
+ verify(registry).addPosition(aPositionData[0], aPositionData[1]);
+ }
+ }
+
+ @Test
+ public void testPrefetchBounds() {
+ mProvider = new Provider(new int[]{100, 100});
+
+ mSingleRow = new SingleRow();
+ mSingleRow.setSpacing(20);
+ mSingleRow.setProvider(mProvider);
+ mSingleRow.appendVisibleItems(150);
+
+ validatePrefetch(0, -10);
+ validatePrefetch(-150, 10);
+ }
+
+ @Test
+ public void testPrefetchBoundsReversed() {
+ mProvider = new Provider(new int[]{100, 100});
+
+ mSingleRow = new SingleRow();
+ mSingleRow.setSpacing(20);
+ mSingleRow.setProvider(mProvider);
+ mSingleRow.setReversedFlow(true);
+ mSingleRow.appendVisibleItems(-150);
+
+ validatePrefetch(0, -10);
+ validatePrefetch(150, 10);
+ }
+
+ @Test
+ public void testPrefetchItems() {
+ mProvider = new Provider(new int[]{80, 80, 30, 100, 40, 10});
+
+ mSingleRow = new SingleRow();
+ mSingleRow.setSpacing(20);
+ mSingleRow.setProvider(mProvider);
+ mSingleRow.appendVisibleItems(200);
+
+ // next item, 2, is 0 pixels away
+ validatePrefetch(200, 10, new Integer[] {2, 0});
+
+ // nothing above
+ validatePrefetch(0, -10);
+
+ mProvider.scroll(90);
+ mSingleRow.removeInvisibleItemsAtFront(Integer.MAX_VALUE, 0);
+ mSingleRow.appendVisibleItems(200);
+
+ // next item, 4, is 80 pixels away
+ validatePrefetch(200, 10, new Integer[] {4, 80});
+
+ // next item, 0, is 10 pixels away
+ validatePrefetch(0, -10, new Integer[] {0, 10});
+ }
+
+ @Test
+ public void testPrefetchItemsReversed() {
+ mProvider = new Provider(new int[]{80, 80, 30, 100, 40, 10});
+
+ mSingleRow = new SingleRow();
+ mSingleRow.setSpacing(20);
+ mSingleRow.setProvider(mProvider);
+ mSingleRow.setReversedFlow(true);
+ mSingleRow.appendVisibleItems(-200);
+
+ // next item, 2, is 0 pixels away
+ validatePrefetch(-200, -10, new Integer[] {2, 0});
+
+ // nothing above
+ validatePrefetch(0, 10);
+
+ mProvider.scroll(-90);
+ mSingleRow.removeInvisibleItemsAtFront(Integer.MAX_VALUE, 0);
+ mSingleRow.appendVisibleItems(-200);
+
+ // next item, 4, is 80 pixels away
+ validatePrefetch(-200, -10, new Integer[] {4, 80});
+
+ // one above, 0, is 10 pixels away
+ validatePrefetch(0, 10, new Integer[] {0, 10});
+
+ }
}
\ No newline at end of file
diff --git a/v17/preference-leanback/Android.mk b/v17/preference-leanback/Android.mk
index 263d334..8c0488f 100644
--- a/v17/preference-leanback/Android.mk
+++ b/v17/preference-leanback/Android.mk
@@ -35,6 +35,7 @@
$(call all-java-files-under,api21) \
$(call all-java-files-under,src)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+LOCAL_MANIFEST_FILE := AndroidManifest-make.xml
LOCAL_SHARED_ANDROID_LIBRARIES := \
android-support-v17-leanback \
android-support-v14-preference \
diff --git a/v17/preference-leanback/AndroidManifest-make.xml b/v17/preference-leanback/AndroidManifest-make.xml
new file mode 100644
index 0000000..e2cfe35
--- /dev/null
+++ b/v17/preference-leanback/AndroidManifest-make.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2015 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
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.support.v17.preference"
+ android:versionCode="1"
+ android:versionName="1.0">
+ <uses-sdk android:minSdkVersion="17" />
+ <application />
+</manifest>
diff --git a/v17/preference-leanback/build.gradle b/v17/preference-leanback/build.gradle
index 9bfd0f3..e58fa8b 100644
--- a/v17/preference-leanback/build.gradle
+++ b/v17/preference-leanback/build.gradle
@@ -36,28 +36,11 @@
}
def suffix = name.capitalize()
- def jarTask = project.tasks.create(name: "jar${suffix}", type: Jar){
- dependsOn variant.javaCompile
- from variant.javaCompile.destinationDir
- from 'LICENSE.txt'
- }
- def javadocTask = project.tasks.create(name: "javadoc${suffix}", type: Javadoc) {
- source android.sourceSets.main.java
- classpath = files(variant.javaCompile.classpath.files) + files(
- "${android.sdkDirectory}/platforms/${android.compileSdkVersion}/android.jar")
- }
-
- def javadocJarTask = project.tasks.create(name: "javadocJar${suffix}", type: Jar) {
- classifier = 'javadoc'
- from 'build/docs/javadoc'
- }
-
def sourcesJarTask = project.tasks.create(name: "sourceJar${suffix}", type: Jar) {
classifier = 'sources'
from android.sourceSets.main.java.srcDirs
}
- artifacts.add('archives', javadocJarTask);
artifacts.add('archives', sourcesJarTask);
}
diff --git a/v4/Android.mk b/v4/Android.mk
index a9c9145..c7e35aa 100644
--- a/v4/Android.mk
+++ b/v4/Android.mk
@@ -35,6 +35,7 @@
android-support-fragment \
android-support-annotations
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+LOCAL_MANIFEST_FILE := AndroidManifest-make.xml
LOCAL_JAR_EXCLUDE_FILES := none
LOCAL_JAVA_LANGUAGE_VERSION := 1.7
LOCAL_AAPT_FLAGS := --add-javadoc-annotation doconly
diff --git a/v4/AndroidManifest-make.xml b/v4/AndroidManifest-make.xml
new file mode 100644
index 0000000..d76c581
--- /dev/null
+++ b/v4/AndroidManifest-make.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ package="android.support.v4">
+ <uses-sdk android:minSdkVersion="9" tools:overrideLibrary="android.support.v4"/>
+ <application />
+</manifest>
diff --git a/v4/AndroidManifest.xml b/v4/AndroidManifest.xml
index d76c581..cecc743 100644
--- a/v4/AndroidManifest.xml
+++ b/v4/AndroidManifest.xml
@@ -17,5 +17,6 @@
xmlns:tools="http://schemas.android.com/tools"
package="android.support.v4">
<uses-sdk android:minSdkVersion="9" tools:overrideLibrary="android.support.v4"/>
+ <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
<application />
</manifest>
diff --git a/v4/build.gradle b/v4/build.gradle
index f0226e3..f226a87 100644
--- a/v4/build.gradle
+++ b/v4/build.gradle
@@ -1,6 +1,6 @@
apply plugin: 'com.android.library'
-
archivesBaseName = 'support-v4'
+
dependencies {
compile project(':support-compat')
compile project(':support-media-compat')
diff --git a/v7/appcompat/Android.mk b/v7/appcompat/Android.mk
index 93baa95..3c5b44c 100644
--- a/v7/appcompat/Android.mk
+++ b/v7/appcompat/Android.mk
@@ -28,6 +28,7 @@
LOCAL_SDK_VERSION := $(SUPPORT_CURRENT_SDK_VERSION)
LOCAL_SRC_FILES := $(call all-java-files-under,src)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+LOCAL_MANIFEST_FILE := AndroidManifest-make.xml
LOCAL_STATIC_JAVA_LIBRARIES := \
android-support-vectordrawable \
android-support-animatedvectordrawable
diff --git a/v7/appcompat/AndroidManifest-make.xml b/v7/appcompat/AndroidManifest-make.xml
new file mode 100644
index 0000000..99b77ee
--- /dev/null
+++ b/v7/appcompat/AndroidManifest-make.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ package="android.support.v7.appcompat">
+ <uses-sdk android:minSdkVersion="9"
+ tools:overrideLibrary="android.support.graphics.drawable.animated"/>
+ <application/>
+</manifest>
diff --git a/v7/appcompat/AndroidManifest.xml b/v7/appcompat/AndroidManifest.xml
index 99b77ee..d5858d1 100644
--- a/v7/appcompat/AndroidManifest.xml
+++ b/v7/appcompat/AndroidManifest.xml
@@ -18,5 +18,6 @@
package="android.support.v7.appcompat">
<uses-sdk android:minSdkVersion="9"
tools:overrideLibrary="android.support.graphics.drawable.animated"/>
+ <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
<application/>
</manifest>
diff --git a/v7/appcompat/build.gradle b/v7/appcompat/build.gradle
index aa62632..4935085 100644
--- a/v7/appcompat/build.gradle
+++ b/v7/appcompat/build.gradle
@@ -1,5 +1,4 @@
apply plugin: 'com.android.library'
-
archivesBaseName = 'appcompat-v7'
dependencies {
@@ -61,28 +60,11 @@
}
def suffix = name.capitalize()
- def jarTask = project.tasks.create(name: "jar${suffix}", type: Jar){
- dependsOn variant.javaCompile
- from variant.javaCompile.destinationDir
- from 'LICENSE.txt'
- }
- def javadocTask = project.tasks.create(name: "javadoc${suffix}", type: Javadoc) {
- source android.sourceSets.main.java
- classpath = files(variant.javaCompile.classpath.files) + files(
- "${android.sdkDirectory}/platforms/${android.compileSdkVersion}/android.jar")
- }
-
- def javadocJarTask = project.tasks.create(name: "javadocJar${suffix}", type: Jar) {
- classifier = 'javadoc'
- from 'build/docs/javadoc'
- }
-
def sourcesJarTask = project.tasks.create(name: "sourceJar${suffix}", type: Jar) {
classifier = 'sources'
from android.sourceSets.main.java.srcDirs
}
- artifacts.add('archives', javadocJarTask);
artifacts.add('archives', sourcesJarTask);
}
diff --git a/v7/appcompat/res/layout/abc_action_mode_close_item_material.xml b/v7/appcompat/res/layout/abc_action_mode_close_item_material.xml
index b3babb2..118ce2b 100644
--- a/v7/appcompat/res/layout/abc_action_mode_close_item_material.xml
+++ b/v7/appcompat/res/layout/abc_action_mode_close_item_material.xml
@@ -14,14 +14,17 @@
limitations under the License.
-->
-<ImageView
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:id="@+id/action_mode_close_button"
- android:contentDescription="@string/abc_action_mode_done"
- android:focusable="true"
- android:clickable="true"
- app:srcCompat="?attr/actionModeCloseDrawable"
- style="?attr/actionModeCloseButtonStyle"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"/>
\ No newline at end of file
+<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:id="@+id/action_mode_close_button"
+ style="?attr/actionModeCloseButtonStyle"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:layout_marginEnd="16dip"
+ android:layout_marginRight="16dip"
+ android:clickable="true"
+ android:contentDescription="@string/abc_action_mode_done"
+ android:focusable="true"
+ android:paddingLeft="8dp"
+ android:paddingStart="8dp"
+ app:srcCompat="?attr/actionModeCloseDrawable" />
\ No newline at end of file
diff --git a/v7/appcompat/res/values-v11/themes_base.xml b/v7/appcompat/res/values-v11/themes_base.xml
index d38ef32..11ef632 100644
--- a/v7/appcompat/res/values-v11/themes_base.xml
+++ b/v7/appcompat/res/values-v11/themes_base.xml
@@ -32,6 +32,7 @@
<item name="android:buttonBarStyle">?attr/buttonBarStyle</item>
<item name="android:buttonBarButtonStyle">?attr/buttonBarButtonStyle</item>
+ <item name="android:borderlessButtonStyle">?attr/borderlessButtonStyle</item>
<!-- Window colors -->
<item name="android:colorForeground">@color/foreground_material_dark</item>
@@ -86,6 +87,7 @@
<item name="android:buttonBarStyle">?attr/buttonBarStyle</item>
<item name="android:buttonBarButtonStyle">?attr/buttonBarButtonStyle</item>
+ <item name="android:borderlessButtonStyle">?attr/borderlessButtonStyle</item>
<!-- Window colors -->
<item name="android:colorForeground">@color/foreground_material_light</item>
diff --git a/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV9.java b/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV9.java
index b52c0ba..c5839f9 100644
--- a/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV9.java
+++ b/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV9.java
@@ -92,11 +92,15 @@
import android.widget.PopupWindow;
import android.widget.TextView;
+import org.xmlpull.v1.XmlPullParser;
+
@RequiresApi(9)
@TargetApi(9)
class AppCompatDelegateImplV9 extends AppCompatDelegateImplBase
implements MenuBuilder.Callback, LayoutInflaterFactory {
+ private static final boolean IS_PRE_LOLLIPOP = Build.VERSION.SDK_INT < 21;
+
private DecorContentParent mDecorContentParent;
private ActionMenuPresenterCallback mActionMenuPresenterCallback;
private PanelMenuPresenterCallback mPanelMenuPresenterCallback;
@@ -1009,17 +1013,21 @@
@Override
public View createView(View parent, final String name, @NonNull Context context,
@NonNull AttributeSet attrs) {
- final boolean isPre21 = Build.VERSION.SDK_INT < 21;
-
if (mAppCompatViewInflater == null) {
mAppCompatViewInflater = new AppCompatViewInflater();
}
- // We only want the View to inherit its context if we're running pre-v21
- final boolean inheritContext = isPre21 && shouldInheritContext((ViewParent) parent);
+ boolean inheritContext = false;
+ if (IS_PRE_LOLLIPOP) {
+ inheritContext = (attrs instanceof XmlPullParser)
+ // If we have a XmlPullParser, we can detect where we are in the layout
+ ? ((XmlPullParser) attrs).getDepth() > 1
+ // Otherwise we have to use the old heuristic
+ : shouldInheritContext((ViewParent) parent);
+ }
return mAppCompatViewInflater.createView(parent, name, context, attrs, inheritContext,
- isPre21, /* Only read android:theme pre-L (L+ handles this anyway) */
+ IS_PRE_LOLLIPOP, /* Only read android:theme pre-L (L+ handles this anyway) */
true, /* Read read app:theme as a fallback at all times for legacy reasons */
VectorEnabledTintResources.shouldBeUsed() /* Only tint wrap the context if enabled */
);
@@ -1068,8 +1076,7 @@
* From {@link android.support.v4.view.LayoutInflaterFactory}
*/
@Override
- public final View onCreateView(View parent, String name,
- Context context, AttributeSet attrs) {
+ public final View onCreateView(View parent, String name, Context context, AttributeSet attrs) {
// First let the Activity's Factory try and inflate the view
final View view = callActivityOnCreateView(parent, name, context, attrs);
if (view != null) {
diff --git a/v7/appcompat/tests/res/layout/layout_children.xml b/v7/appcompat/tests/res/layout/layout_children.xml
new file mode 100644
index 0000000..a61175a
--- /dev/null
+++ b/v7/appcompat/tests/res/layout/layout_children.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <TextView android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="Test"/>
+
+ <TextView android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="Test"/>
+
+ <TextView android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="Test"/>
+
+ <TextView android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="Test"/>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/v7/appcompat/tests/src/android/support/v7/app/LayoutInflaterFactoryTestCase.java b/v7/appcompat/tests/src/android/support/v7/app/LayoutInflaterFactoryTestCase.java
index f7004b3..0502ad4 100644
--- a/v7/appcompat/tests/src/android/support/v7/app/LayoutInflaterFactoryTestCase.java
+++ b/v7/appcompat/tests/src/android/support/v7/app/LayoutInflaterFactoryTestCase.java
@@ -37,9 +37,11 @@
import android.support.v7.widget.AppCompatRatingBar;
import android.support.v7.widget.AppCompatSpinner;
import android.util.TypedValue;
+import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.LinearLayout;
import org.junit.Before;
import org.junit.Test;
@@ -82,13 +84,28 @@
LayoutInflater inflater = LayoutInflater.from(getActivity());
final ViewGroup root = (ViewGroup) inflater.inflate(
R.layout.layout_android_theme_children, null);
-
assertThemedContext(root);
+ }
- for (int i = 0; i < root.getChildCount(); i++) {
- final View child = root.getChildAt(i);
- assertThemedContext(child);
- }
+ @UiThreadTest
+ @Test
+ @SmallTest
+ public void testThemedInflationWithUnattachedParent() {
+ final Context activity = getActivity();
+
+ // Create a parent but not attached
+ final LinearLayout parent = new LinearLayout(activity);
+
+ // Now create a LayoutInflater with a themed context
+ LayoutInflater inflater = LayoutInflater.from(activity)
+ .cloneInContext(new ContextThemeWrapper(activity, R.style.MagentaThemeOverlay));
+
+ // Now inflate a layout with children
+ final ViewGroup root = (ViewGroup) inflater.inflate(
+ R.layout.layout_children, parent, false);
+
+ // And assert that the layout is themed correctly
+ assertThemedContext(root);
}
@UiThreadTest
@@ -190,7 +207,7 @@
view.getClass());
}
- private static void assertThemedContext(View view) {
+ private static void assertThemedContext(final View view) {
final Context viewContext = view.getContext();
final int expectedColor = view.getResources().getColor(R.color.test_magenta);
@@ -199,6 +216,14 @@
&& colorAccentValue.type <= TypedValue.TYPE_LAST_COLOR_INT);
assertEquals("View does not have ContextThemeWrapper context",
expectedColor, colorAccentValue.data);
+
+ if (view instanceof ViewGroup) {
+ ViewGroup vg = (ViewGroup) view;
+ for (int i = 0; i < vg.getChildCount(); i++) {
+ final View child = vg.getChildAt(i);
+ assertThemedContext(child);
+ }
+ }
}
private static TypedValue getColorAccentValue(final Resources.Theme theme) {
diff --git a/v7/cardview/Android.mk b/v7/cardview/Android.mk
index cd3b407..40f6b23 100644
--- a/v7/cardview/Android.mk
+++ b/v7/cardview/Android.mk
@@ -31,6 +31,7 @@
$(call all-java-files-under,api21) \
$(call all-java-files-under,src)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+LOCAL_MANIFEST_FILE := AndroidManifest-make.xml
LOCAL_SHARED_ANDROID_LIBRARIES := \
android-support-annotations
LOCAL_JAR_EXCLUDE_FILES := none
diff --git a/v7/cardview/AndroidManifest-make.xml b/v7/cardview/AndroidManifest-make.xml
new file mode 100644
index 0000000..c35e369
--- /dev/null
+++ b/v7/cardview/AndroidManifest-make.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.support.v7.cardview">
+ <uses-sdk android:minSdkVersion="9"/>
+ <application />
+</manifest>
diff --git a/v7/cardview/AndroidManifest.xml b/v7/cardview/AndroidManifest.xml
index c35e369..e85003c 100644
--- a/v7/cardview/AndroidManifest.xml
+++ b/v7/cardview/AndroidManifest.xml
@@ -16,5 +16,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="android.support.v7.cardview">
<uses-sdk android:minSdkVersion="9"/>
+ <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
<application />
</manifest>
diff --git a/v7/cardview/build.gradle b/v7/cardview/build.gradle
index b88aad7..ce3f28d 100644
--- a/v7/cardview/build.gradle
+++ b/v7/cardview/build.gradle
@@ -38,28 +38,11 @@
}
def suffix = name.capitalize()
- def jarTask = project.tasks.create(name: "jar${suffix}", type: Jar){
- dependsOn variant.javaCompile
- from variant.javaCompile.destinationDir
- from 'LICENSE.txt'
- }
- def javadocTask = project.tasks.create(name: "javadoc${suffix}", type: Javadoc) {
- source android.sourceSets.main.java
- classpath = files(variant.javaCompile.classpath.files) + files(
- "${android.sdkDirectory}/platforms/${android.compileSdkVersion}/android.jar")
- }
-
- def javadocJarTask = project.tasks.create(name: "javadocJar${suffix}", type: Jar) {
- classifier = 'javadoc'
- from 'build/docs/javadoc'
- }
-
def sourcesJarTask = project.tasks.create(name: "sourceJar${suffix}", type: Jar) {
classifier = 'sources'
from android.sourceSets.main.java.srcDirs
}
- artifacts.add('archives', javadocJarTask);
artifacts.add('archives', sourcesJarTask);
}
diff --git a/v7/gridlayout/Android.mk b/v7/gridlayout/Android.mk
index 6eac23b4..c584dbe 100644
--- a/v7/gridlayout/Android.mk
+++ b/v7/gridlayout/Android.mk
@@ -29,6 +29,7 @@
LOCAL_SDK_VERSION := $(SUPPORT_CURRENT_SDK_VERSION)
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+LOCAL_MANIFEST_FILE := AndroidManifest-make.xml
LOCAL_SHARED_ANDROID_LIBRARIES := \
android-support-compat \
android-support-core-ui \
diff --git a/v7/gridlayout/AndroidManifest-make.xml b/v7/gridlayout/AndroidManifest-make.xml
new file mode 100644
index 0000000..d2cc627
--- /dev/null
+++ b/v7/gridlayout/AndroidManifest-make.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.support.v7.gridlayout">
+ <uses-sdk android:minSdkVersion="9"/>
+ <application />
+</manifest>
diff --git a/v7/gridlayout/AndroidManifest.xml b/v7/gridlayout/AndroidManifest.xml
index d2cc627..dfcc942 100644
--- a/v7/gridlayout/AndroidManifest.xml
+++ b/v7/gridlayout/AndroidManifest.xml
@@ -16,5 +16,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="android.support.v7.gridlayout">
<uses-sdk android:minSdkVersion="9"/>
+ <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
<application />
</manifest>
diff --git a/v7/gridlayout/build.gradle b/v7/gridlayout/build.gradle
index 542d5a7..56f320f 100644
--- a/v7/gridlayout/build.gradle
+++ b/v7/gridlayout/build.gradle
@@ -1,5 +1,4 @@
apply plugin: 'com.android.library'
-
archivesBaseName = 'gridlayout-v7'
dependencies {
@@ -53,28 +52,11 @@
}
def suffix = name.capitalize()
- def jarTask = project.tasks.create(name: "jar${suffix}", type: Jar){
- dependsOn variant.javaCompile
- from variant.javaCompile.destinationDir
- from 'LICENSE.txt'
- }
- def javadocTask = project.tasks.create(name: "javadoc${suffix}", type: Javadoc) {
- source android.sourceSets.main.java
- classpath = files(variant.javaCompile.classpath.files) + files(
- "${android.sdkDirectory}/platforms/${android.compileSdkVersion}/android.jar")
- }
-
- def javadocJarTask = project.tasks.create(name: "javadocJar${suffix}", type: Jar) {
- classifier = 'javadoc'
- from 'build/docs/javadoc'
- }
-
def sourcesJarTask = project.tasks.create(name: "sourceJar${suffix}", type: Jar) {
classifier = 'sources'
from android.sourceSets.main.java.srcDirs
}
- artifacts.add('archives', javadocJarTask);
artifacts.add('archives', sourcesJarTask);
}
diff --git a/v7/mediarouter/Android.mk b/v7/mediarouter/Android.mk
index 21b4a62..6162f87 100644
--- a/v7/mediarouter/Android.mk
+++ b/v7/mediarouter/Android.mk
@@ -35,6 +35,7 @@
$(call all-java-files-under,api24) \
$(call all-java-files-under,src)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+LOCAL_MANIFEST_FILE := AndroidManifest-make.xml
LOCAL_SHARED_ANDROID_LIBRARIES := \
android-support-v7-appcompat \
android-support-v7-palette \
diff --git a/v7/mediarouter/AndroidManifest-make.xml b/v7/mediarouter/AndroidManifest-make.xml
new file mode 100644
index 0000000..59d9f99
--- /dev/null
+++ b/v7/mediarouter/AndroidManifest-make.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.support.v7.mediarouter">
+ <uses-sdk android:minSdkVersion="9"/>
+ <application />
+</manifest>
diff --git a/v7/mediarouter/AndroidManifest.xml b/v7/mediarouter/AndroidManifest.xml
index 59d9f99..bbebdfe 100644
--- a/v7/mediarouter/AndroidManifest.xml
+++ b/v7/mediarouter/AndroidManifest.xml
@@ -16,5 +16,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="android.support.v7.mediarouter">
<uses-sdk android:minSdkVersion="9"/>
+ <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
<application />
</manifest>
diff --git a/v7/mediarouter/build.gradle b/v7/mediarouter/build.gradle
index 3e51602..7796565 100644
--- a/v7/mediarouter/build.gradle
+++ b/v7/mediarouter/build.gradle
@@ -49,28 +49,11 @@
}
def suffix = name.capitalize()
- def jarTask = project.tasks.create(name: "jar${suffix}", type: Jar){
- dependsOn variant.javaCompile
- from variant.javaCompile.destinationDir
- from 'LICENSE.txt'
- }
- def javadocTask = project.tasks.create(name: "javadoc${suffix}", type: Javadoc) {
- source android.sourceSets.main.java
- classpath = files(variant.javaCompile.classpath.files) + files(
- "${android.sdkDirectory}/platforms/${android.compileSdkVersion}/android.jar")
- }
-
- def javadocJarTask = project.tasks.create(name: "javadocJar${suffix}", type: Jar) {
- classifier = 'javadoc'
- from 'build/docs/javadoc'
- }
-
def sourcesJarTask = project.tasks.create(name: "sourceJar${suffix}", type: Jar) {
classifier = 'sources'
from android.sourceSets.main.java.srcDirs
}
- artifacts.add('archives', javadocJarTask);
artifacts.add('archives', sourcesJarTask);
}
diff --git a/v7/palette/Android.mk b/v7/palette/Android.mk
index c21dad3..a9f9a75 100644
--- a/v7/palette/Android.mk
+++ b/v7/palette/Android.mk
@@ -29,7 +29,7 @@
LOCAL_SDK_VERSION := $(SUPPORT_CURRENT_SDK_VERSION)
LOCAL_SRC_FILES := $(call all-java-files-under, src/main)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/src/main/res
-LOCAL_MANIFEST_FILE := src/main/AndroidManifest.xml
+LOCAL_MANIFEST_FILE := src/main/AndroidManifest-make.xml
LOCAL_SHARED_ANDROID_LIBRARIES := \
android-support-compat \
android-support-core-utils \
diff --git a/v7/palette/build.gradle b/v7/palette/build.gradle
index 2494370..686fe71 100644
--- a/v7/palette/build.gradle
+++ b/v7/palette/build.gradle
@@ -1,5 +1,4 @@
apply plugin: 'com.android.library'
-
archivesBaseName = 'palette-v7'
dependencies {
@@ -34,28 +33,11 @@
}
def suffix = name.capitalize()
- def jarTask = project.tasks.create(name: "jar${suffix}", type: Jar){
- dependsOn variant.javaCompile
- from variant.javaCompile.destinationDir
- from 'LICENSE.txt'
- }
- def javadocTask = project.tasks.create(name: "javadoc${suffix}", type: Javadoc) {
- source android.sourceSets.main.java
- classpath = files(variant.javaCompile.classpath.files) + files(
- "${android.sdkDirectory}/platforms/${android.compileSdkVersion}/android.jar")
- }
-
- def javadocJarTask = project.tasks.create(name: "javadocJar${suffix}", type: Jar) {
- classifier = 'javadoc'
- from 'build/docs/javadoc'
- }
-
def sourcesJarTask = project.tasks.create(name: "sourceJar${suffix}", type: Jar) {
classifier = 'sources'
from android.sourceSets.main.java.srcDirs
}
- artifacts.add('archives', javadocJarTask);
artifacts.add('archives', sourcesJarTask);
}
diff --git a/v7/palette/src/main/AndroidManifest-make.xml b/v7/palette/src/main/AndroidManifest-make.xml
new file mode 100644
index 0000000..5124bc5
--- /dev/null
+++ b/v7/palette/src/main/AndroidManifest-make.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.support.v7.palette">
+ <uses-sdk android:minSdkVersion="9"/>
+ <application />
+</manifest>
diff --git a/v7/palette/src/main/AndroidManifest.xml b/v7/palette/src/main/AndroidManifest.xml
index c44818a..52e90a2 100644
--- a/v7/palette/src/main/AndroidManifest.xml
+++ b/v7/palette/src/main/AndroidManifest.xml
@@ -16,6 +16,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="android.support.v7.palette">
<uses-sdk android:minSdkVersion="9"/>
- <application>
- </application>
+ <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
+ <application />
</manifest>
diff --git a/v7/preference/Android.mk b/v7/preference/Android.mk
index e751e1c..110aed2 100644
--- a/v7/preference/Android.mk
+++ b/v7/preference/Android.mk
@@ -32,6 +32,7 @@
$(call all-java-files-under,constants) \
$(call all-java-files-under,src)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+LOCAL_MANIFEST_FILE := AndroidManifest-make.xml
LOCAL_SHARED_ANDROID_LIBRARIES := \
android-support-v7-appcompat \
android-support-v7-recyclerview \
diff --git a/v7/preference/AndroidManifest-make.xml b/v7/preference/AndroidManifest-make.xml
new file mode 100644
index 0000000..9231775
--- /dev/null
+++ b/v7/preference/AndroidManifest-make.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.support.v7.preference">
+ <uses-sdk android:minSdkVersion="9" />
+ <application />
+</manifest>
diff --git a/v7/preference/AndroidManifest.xml b/v7/preference/AndroidManifest.xml
index da9c80e..19e6215 100644
--- a/v7/preference/AndroidManifest.xml
+++ b/v7/preference/AndroidManifest.xml
@@ -1,8 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 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.
+-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.support.v7.preference"
- android:versionCode="1"
- android:versionName="1.0">
+ package="android.support.v7.preference">
<uses-sdk android:minSdkVersion="9" />
+ <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
<application />
</manifest>
diff --git a/v7/preference/build.gradle b/v7/preference/build.gradle
index a63cc9e..b5fd656 100644
--- a/v7/preference/build.gradle
+++ b/v7/preference/build.gradle
@@ -15,7 +15,6 @@
*/
apply plugin: 'com.android.library'
-
archivesBaseName = 'preference-v7'
dependencies {
@@ -80,28 +79,11 @@
}
def suffix = name.capitalize()
- def jarTask = project.tasks.create(name: "jar${suffix}", type: Jar){
- dependsOn variant.javaCompile
- from variant.javaCompile.destinationDir
- from 'LICENSE.txt'
- }
- def javadocTask = project.tasks.create(name: "javadoc${suffix}", type: Javadoc) {
- source android.sourceSets.main.java
- classpath = files(variant.javaCompile.classpath.files) + files(
- "${android.sdkDirectory}/platforms/${android.compileSdkVersion}/android.jar")
- }
-
- def javadocJarTask = project.tasks.create(name: "javadocJar${suffix}", type: Jar) {
- classifier = 'javadoc'
- from 'build/docs/javadoc'
- }
-
def sourcesJarTask = project.tasks.create(name: "sourceJar${suffix}", type: Jar) {
classifier = 'sources'
from android.sourceSets.main.java.srcDirs
}
- artifacts.add('archives', javadocJarTask);
artifacts.add('archives', sourcesJarTask);
}
diff --git a/v7/recyclerview/Android.mk b/v7/recyclerview/Android.mk
index e434ab2..819b104 100644
--- a/v7/recyclerview/Android.mk
+++ b/v7/recyclerview/Android.mk
@@ -29,6 +29,7 @@
LOCAL_SDK_VERSION := $(SUPPORT_CURRENT_SDK_VERSION)
LOCAL_SRC_FILES := $(call all-java-files-under,src)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+LOCAL_MANIFEST_FILE := AndroidManifest-make.xml
LOCAL_SHARED_ANDROID_LIBRARIES := \
android-support-compat \
android-support-core-ui \
diff --git a/v7/recyclerview/AndroidManifest-make.xml b/v7/recyclerview/AndroidManifest-make.xml
new file mode 100644
index 0000000..d1c1489
--- /dev/null
+++ b/v7/recyclerview/AndroidManifest-make.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.support.v7.recyclerview">
+ <uses-sdk android:minSdkVersion="9"/>
+</manifest>
diff --git a/v7/recyclerview/AndroidManifest.xml b/v7/recyclerview/AndroidManifest.xml
index d1c1489..f4f010d 100644
--- a/v7/recyclerview/AndroidManifest.xml
+++ b/v7/recyclerview/AndroidManifest.xml
@@ -16,4 +16,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="android.support.v7.recyclerview">
<uses-sdk android:minSdkVersion="9"/>
+ <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
</manifest>
diff --git a/v7/recyclerview/build.gradle b/v7/recyclerview/build.gradle
index 11a098e..e262ec7 100644
--- a/v7/recyclerview/build.gradle
+++ b/v7/recyclerview/build.gradle
@@ -1,5 +1,4 @@
apply plugin: 'com.android.library'
-
archivesBaseName = 'recyclerview-v7'
dependencies {
@@ -47,10 +46,6 @@
targetCompatibility JavaVersion.VERSION_1_7
}
- packagingOptions {
- exclude 'LICENSE.txt'
- }
-
testOptions {
unitTests.returnDefaultValues = true
}
@@ -68,28 +63,11 @@
}
def suffix = name.capitalize()
- def jarTask = project.tasks.create(name: "jar${suffix}", type: Jar){
- dependsOn variant.javaCompile
- from variant.javaCompile.destinationDir
- from 'LICENSE.txt'
- }
- def javadocTask = project.tasks.create(name: "javadoc${suffix}", type: Javadoc) {
- source android.sourceSets.main.java
- classpath = files(variant.javaCompile.classpath.files) + files(
- "${android.sdkDirectory}/platforms/${android.compileSdkVersion}/android.jar")
- }
-
- def javadocJarTask = project.tasks.create(name: "javadocJar${suffix}", type: Jar) {
- classifier = 'javadoc'
- from 'build/docs/javadoc'
- }
-
def sourcesJarTask = project.tasks.create(name: "sourceJar${suffix}", type: Jar) {
classifier = 'sources'
from android.sourceSets.main.java.srcDirs
}
- artifacts.add('archives', javadocJarTask);
artifacts.add('archives', sourcesJarTask);
}
diff --git a/v7/recyclerview/src/android/support/v7/widget/LinearLayoutManager.java b/v7/recyclerview/src/android/support/v7/widget/LinearLayoutManager.java
index 78a31b4..6900437 100644
--- a/v7/recyclerview/src/android/support/v7/widget/LinearLayoutManager.java
+++ b/v7/recyclerview/src/android/support/v7/widget/LinearLayoutManager.java
@@ -18,12 +18,14 @@
import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
import static android.support.v7.widget.RecyclerView.NO_POSITION;
+import static android.support.v7.widget.RecyclerView.VERBOSE_TRACING;
import android.content.Context;
import android.graphics.PointF;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.RestrictTo;
+import android.support.v4.os.TraceCompat;
import android.support.v4.view.ViewCompat;
import android.support.v4.view.accessibility.AccessibilityEventCompat;
import android.support.v4.view.accessibility.AccessibilityRecordCompat;
@@ -1493,7 +1495,13 @@
LayoutChunkResult layoutChunkResult = mLayoutChunkResult;
while ((layoutState.mInfinite || remainingSpace > 0) && layoutState.hasMore(state)) {
layoutChunkResult.resetInternal();
+ if (VERBOSE_TRACING) {
+ TraceCompat.beginSection("LLM LayoutChunk");
+ }
layoutChunk(recycler, state, layoutState, layoutChunkResult);
+ if (VERBOSE_TRACING) {
+ TraceCompat.endSection();
+ }
if (layoutChunkResult.mFinished) {
break;
}
diff --git a/v7/recyclerview/src/android/support/v7/widget/RecyclerView.java b/v7/recyclerview/src/android/support/v7/widget/RecyclerView.java
index 5fe10bf..24936e0 100644
--- a/v7/recyclerview/src/android/support/v7/widget/RecyclerView.java
+++ b/v7/recyclerview/src/android/support/v7/widget/RecyclerView.java
@@ -154,6 +154,8 @@
static final boolean DEBUG = false;
+ static final boolean VERBOSE_TRACING = false;
+
private static final int[] NESTED_SCROLLING_ATTRS
= {16843830 /* android.R.attr.nestedScrollingEnabled */};
@@ -702,7 +704,13 @@
@Override
public void addView(View child, int index) {
+ if (VERBOSE_TRACING) {
+ TraceCompat.beginSection("RV addView");
+ }
RecyclerView.this.addView(child, index);
+ if (VERBOSE_TRACING) {
+ TraceCompat.endSection();
+ }
dispatchChildAttached(child);
}
@@ -717,7 +725,13 @@
if (child != null) {
dispatchChildDetached(child);
}
+ if (VERBOSE_TRACING) {
+ TraceCompat.beginSection("RV removeViewAt");
+ }
RecyclerView.this.removeViewAt(index);
+ if (VERBOSE_TRACING) {
+ TraceCompat.endSection();
+ }
}
@Override
diff --git a/v7/recyclerview/tests/src/android/support/v7/widget/StaggeredGridLayoutManagerTest.java b/v7/recyclerview/tests/src/android/support/v7/widget/StaggeredGridLayoutManagerTest.java
index 64111c5..d92b169 100644
--- a/v7/recyclerview/tests/src/android/support/v7/widget/StaggeredGridLayoutManagerTest.java
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/StaggeredGridLayoutManagerTest.java
@@ -279,7 +279,10 @@
item.mText + " (" + item.mId + ")");
}
});
- waitFirstLayout();
+ mLayoutManager.expectLayouts(1);
+ setRecyclerView(mRecyclerView);
+ mLayoutManager.waitForLayout(10);
+ getInstrumentation().waitForIdleSync();
ViewGroup lastChild = (ViewGroup) mRecyclerView.getChildAt(
mRecyclerView.getChildCount() - 1);
RecyclerView.ViewHolder lastViewHolder = mRecyclerView.getChildViewHolder(lastChild);