Merge "Paging API refinements, and package name rework" into oc-mr1-dev
diff --git a/app-toolkit/common/api/0.0.0.txt b/app-toolkit/common/api/0.0.0.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/app-toolkit/common/api/0.0.0.txt
diff --git a/app-toolkit/common/api/1.0.0.txt b/app-toolkit/common/api/1.0.0.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/app-toolkit/common/api/1.0.0.txt
diff --git a/app-toolkit/common/build.gradle b/app-toolkit/common/build.gradle
index ff8375a..4f51a49 100644
--- a/app-toolkit/common/build.gradle
+++ b/app-toolkit/common/build.gradle
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+import android.support.LibraryVersions
import android.support.SupportLibraryExtension;
apply plugin: android.support.SupportJavaLibraryPlugin
@@ -27,6 +28,7 @@
createAndroidCheckstyle(project)
+version = LibraryVersions.ARCH_CORE.toString()
supportLibrary {
name 'Android Arch-Common'
publish true
diff --git a/app-toolkit/core-testing/build.gradle b/app-toolkit/core-testing/build.gradle
index 2e6cde6..8b86b8b 100644
--- a/app-toolkit/core-testing/build.gradle
+++ b/app-toolkit/core-testing/build.gradle
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+import android.support.LibraryVersions
import android.support.SupportLibraryExtension
apply plugin: android.support.FlatfootAndroidLibraryPlugin
@@ -64,6 +65,7 @@
}
}
+version = LibraryVersions.ARCH_CORE_TESTING.toString()
supportLibrary {
name 'Android Core-Testing'
publish true
diff --git a/app-toolkit/init.gradle b/app-toolkit/init.gradle
index e476129..aeb9718 100644
--- a/app-toolkit/init.gradle
+++ b/app-toolkit/init.gradle
@@ -84,7 +84,7 @@
def zipFlatfootDocsTask = rootProject.tasks.create(name : "createFlatfootDocsArchive", type : Zip) {
from rootProject.docsDir
destinationDir distDir
- baseName = String.format("flatfoot-docs-%s", LibraryVersions.FLATFOOT.toString())
+ baseName = "flatfoot-docs"
}
buildServerAnchorTask.dependsOn zipFlatfootDocsTask
@@ -110,16 +110,17 @@
return
}
- def mavenGroup = project.getPath().split(":")[1]
+ def projectPath = project.getPath().split(":")
+ def mavenGroup = projectPath[1]
def finalGroup = rootProject.flatfootProjectGroups[mavenGroup]
if (finalGroup == null) {
return
}
- project.group = finalGroup
- if (!project.version) {
- project.version = LibraryVersions.FLATFOOT.toString()
+ if (projectPath.size() == 2) {// root project.
+ return
}
+ project.group = finalGroup
if (project.getPath().contains("integration-tests")) {
// disable upload tasks
@@ -128,6 +129,21 @@
task.enabled = false
}
}
+ } else {
+ def checkApi = project.tasks.create("checkVersion") {
+ doFirst {
+ if (project.version == null
+ || project.version == LibraryVersions.SUPPORT_LIBRARY.toString()) {
+ throw new GradleException("bad version for $project with $project.version")
+ }
+ }
+ }
+
+ project.tasks.whenTaskAdded { task ->
+ if (task instanceof Upload) {
+ task.dependsOn checkApi
+ }
+ }
}
project.plugins.whenPluginAdded { plugin ->
diff --git a/app-toolkit/runtime/build.gradle b/app-toolkit/runtime/build.gradle
index efb7b50..434d42b 100644
--- a/app-toolkit/runtime/build.gradle
+++ b/app-toolkit/runtime/build.gradle
@@ -15,6 +15,7 @@
*/
import android.support.SupportLibraryExtension
+import android.support.LibraryVersions
apply plugin: android.support.FlatfootAndroidLibraryPlugin
@@ -55,6 +56,7 @@
}
}
+version = LibraryVersions.ARCH_RUNTIME.toString()
supportLibrary {
name 'Android Arch-Runtime'
publish true
diff --git a/buildSrc/src/main/java/android/support/LibraryVersions.java b/buildSrc/src/main/java/android/support/LibraryVersions.java
index 6795488..32c9313 100644
--- a/buildSrc/src/main/java/android/support/LibraryVersions.java
+++ b/buildSrc/src/main/java/android/support/LibraryVersions.java
@@ -26,12 +26,47 @@
public static final Version SUPPORT_LIBRARY = new Version("27.0.0-SNAPSHOT");
/**
- * Version code of the flatfoot libraries.
+ * Version code for flatfoot 1.0 projects (room, lifecycles)
*/
- public static final Version FLATFOOT = new Version("1.0.0-alpha9");
+ private static final Version FLATFOOT_1_0_BATCH = new Version("1.0.0-alpha10");
/**
- * Version code of the lifecycles library.
+ * Version code for Room
*/
- public static final Version LIFECYCLES = new Version("1.0.0-SNAPSHOT");
+ public static final Version ROOM = FLATFOOT_1_0_BATCH;
+
+ /**
+ * Version code for Lifecycle extensions (live data, view model etc)
+ */
+ public static final Version LIFECYCLES_EXT = FLATFOOT_1_0_BATCH;
+
+ /**
+ * Version code for RecyclerView & Room paging
+ */
+ public static final Version PAGING = new Version("1.0.0-alpha1");
+
+ /**
+ * Version code for Lifecycle libs that are required by the support library
+ */
+ public static final Version LIFECYCLES_CORE = new Version("1.0.0");
+
+ /**
+ * Version code for Lifecycle runtime libs that are required by the support library
+ */
+ public static final Version LIFECYCLES_RUNTIME = new Version("1.0.0");
+
+ /**
+ * Version code for shared code of flatfoot
+ */
+ public static final Version ARCH_CORE = new Version("1.0.0");
+
+ /**
+ * Version code for shared code of flatfoot runtime
+ */
+ public static final Version ARCH_RUNTIME = FLATFOOT_1_0_BATCH;
+
+ /**
+ * Version code for shared testing code of flatfoot
+ */
+ public static final Version ARCH_CORE_TESTING = FLATFOOT_1_0_BATCH;
}
diff --git a/compat/api/current.txt b/compat/api/current.txt
index 2d83433..8dea70f 100644
--- a/compat/api/current.txt
+++ b/compat/api/current.txt
@@ -1578,6 +1578,7 @@
method public static float getElevation(android.view.View);
method public static boolean getFitsSystemWindows(android.view.View);
method public static int getImportantForAccessibility(android.view.View);
+ method public static int getImportantForAutofill(android.view.View);
method public static int getLabelFor(android.view.View);
method public static deprecated int getLayerType(android.view.View);
method public static int getLayoutDirection(android.view.View);
@@ -1618,6 +1619,7 @@
method public static boolean isAttachedToWindow(android.view.View);
method public static boolean isFocusedByDefault(android.view.View);
method public static boolean isImportantForAccessibility(android.view.View);
+ method public static boolean isImportantForAutofill(android.view.View);
method public static boolean isInLayout(android.view.View);
method public static boolean isKeyboardNavigationCluster(android.view.View);
method public static boolean isLaidOut(android.view.View);
@@ -1645,6 +1647,7 @@
method public static void setAccessibilityLiveRegion(android.view.View, int);
method public static deprecated void setActivated(android.view.View, boolean);
method public static deprecated void setAlpha(android.view.View, float);
+ method public static void setAutofillHints(android.view.View, java.lang.String...);
method public static void setBackground(android.view.View, android.graphics.drawable.Drawable);
method public static void setBackgroundTintList(android.view.View, android.content.res.ColorStateList);
method public static void setBackgroundTintMode(android.view.View, android.graphics.PorterDuff.Mode);
@@ -1655,6 +1658,7 @@
method public static void setFocusedByDefault(android.view.View, boolean);
method public static void setHasTransientState(android.view.View, boolean);
method public static void setImportantForAccessibility(android.view.View, int);
+ method public static void setImportantForAutofill(android.view.View, int);
method public static void setKeyboardNavigationCluster(android.view.View, boolean);
method public static void setLabelFor(android.view.View, int);
method public static void setLayerPaint(android.view.View, android.graphics.Paint);
diff --git a/compat/java/android/support/v4/view/ViewCompat.java b/compat/java/android/support/v4/view/ViewCompat.java
index 9a66cec..e7443d7 100644
--- a/compat/java/android/support/v4/view/ViewCompat.java
+++ b/compat/java/android/support/v4/view/ViewCompat.java
@@ -19,6 +19,7 @@
import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
import android.animation.ValueAnimator;
+import android.annotation.TargetApi;
import android.content.ClipData;
import android.content.Context;
import android.content.res.ColorStateList;
@@ -115,6 +116,17 @@
@Deprecated
public static final int OVER_SCROLL_NEVER = 2;
+ @TargetApi(Build.VERSION_CODES.O)
+ @IntDef({
+ View.IMPORTANT_FOR_AUTOFILL_AUTO,
+ View.IMPORTANT_FOR_AUTOFILL_YES,
+ View.IMPORTANT_FOR_AUTOFILL_NO,
+ View.IMPORTANT_FOR_AUTOFILL_YES_EXCLUDE_DESCENDANTS,
+ View.IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ private @interface AutofillImportance {}
+
@IntDef({
IMPORTANT_FOR_ACCESSIBILITY_AUTO,
IMPORTANT_FOR_ACCESSIBILITY_YES,
@@ -439,6 +451,10 @@
static Field sAccessibilityDelegateField;
static boolean sAccessibilityDelegateCheckFailed = false;
+ public void setAutofillHints(@NonNull View v, @Nullable String... autofillHints) {
+ // no-op
+ }
+
public void setAccessibilityDelegate(View v,
@Nullable AccessibilityDelegateCompat delegate) {
v.setAccessibilityDelegate(delegate == null ? null : delegate.getBridge());
@@ -991,6 +1007,19 @@
public boolean hasExplicitFocusable(@NonNull View view) {
return view.hasFocusable();
}
+
+ @TargetApi(Build.VERSION_CODES.O)
+ public @AutofillImportance int getImportantForAutofill(@NonNull View v) {
+ return View.IMPORTANT_FOR_AUTOFILL_AUTO;
+ }
+
+ public void setImportantForAutofill(@NonNull View v, @AutofillImportance int mode) {
+ // no-op
+ }
+
+ public boolean isImportantForAutofill(@NonNull View v) {
+ return true;
+ }
}
@RequiresApi(15)
@@ -1523,6 +1552,27 @@
@RequiresApi(26)
static class ViewCompatApi26Impl extends ViewCompatApi24Impl {
+
+ @Override
+ public void setAutofillHints(@NonNull View v, @Nullable String... autofillHints) {
+ v.setAutofillHints(autofillHints);
+ }
+
+ @Override
+ public @AutofillImportance int getImportantForAutofill(@NonNull View v) {
+ return v.getImportantForAutofill();
+ }
+
+ @Override
+ public void setImportantForAutofill(@NonNull View v, @AutofillImportance int mode) {
+ v.setImportantForAutofill(mode);
+ }
+
+ @Override
+ public boolean isImportantForAutofill(@NonNull View v) {
+ return v.isImportantForAutofill();
+ }
+
@Override
public void setTooltipText(View view, CharSequence tooltipText) {
view.setTooltipText(tooltipText);
@@ -1799,6 +1849,165 @@
}
/**
+ * Sets the hints that help an {@link android.service.autofill.AutofillService} determine how
+ * to autofill the view with the user's data.
+ *
+ * <p>Typically, there is only one way to autofill a view, but there could be more than one.
+ * For example, if the application accepts either an username or email address to identify
+ * an user.
+ *
+ * <p>These hints are not validated by the Android System, but passed "as is" to the service.
+ * Hence, they can have any value, but it's recommended to use the {@code AUTOFILL_HINT_}
+ * constants such as:
+ * {@link View#AUTOFILL_HINT_USERNAME}, {@link View#AUTOFILL_HINT_PASSWORD},
+ * {@link View#AUTOFILL_HINT_EMAIL_ADDRESS},
+ * {@link View#AUTOFILL_HINT_NAME},
+ * {@link View#AUTOFILL_HINT_PHONE},
+ * {@link View#AUTOFILL_HINT_POSTAL_ADDRESS}, {@link View#AUTOFILL_HINT_POSTAL_CODE},
+ * {@link View#AUTOFILL_HINT_CREDIT_CARD_NUMBER},
+ * {@link View#AUTOFILL_HINT_CREDIT_CARD_SECURITY_CODE},
+ * {@link View#AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_DATE},
+ * {@link View#AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_DAY},
+ * {@link View#AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_MONTH} or
+ * {@link View#AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_YEAR}.
+ *
+ * <p>This method is only supported on API >= 26.
+ * On API 25 and below, it is a no-op</p>
+ *
+ * @param autofillHints The autofill hints to set. If the array is emtpy, {@code null} is set.
+ * @attr ref android.R.styleable#View_autofillHints
+ */
+ public static void setAutofillHints(@NonNull View v, @Nullable String... autofillHints) {
+ IMPL.setAutofillHints(v, autofillHints);
+ }
+
+ /**
+ * Gets the mode for determining whether this view is important for autofill.
+ *
+ * <p>See {@link #setImportantForAutofill(View, int)} and {@link #isImportantForAutofill(View)}
+ * for more info about this mode.
+ *
+ * <p>This method is only supported on API >= 26.
+ * On API 25 and below, it will always return {@link View#IMPORTANT_FOR_AUTOFILL_AUTO}.</p>
+ *
+ * @return {@link View#IMPORTANT_FOR_AUTOFILL_AUTO} by default, or value passed to
+ * {@link #setImportantForAutofill(View, int)}.
+ *
+ * @attr ref android.R.styleable#View_importantForAutofill
+ */
+ public static @AutofillImportance int getImportantForAutofill(@NonNull View v) {
+ return IMPL.getImportantForAutofill(v);
+ }
+
+ /**
+ * Sets the mode for determining whether this view is considered important for autofill.
+ *
+ * <p>The platform determines the importance for autofill automatically but you
+ * can use this method to customize the behavior. For example:
+ *
+ * <ol>
+ * <li>When the view contents is irrelevant for autofill (for example, a text field used in a
+ * "Captcha" challenge), it should be {@link View#IMPORTANT_FOR_AUTOFILL_NO}.
+ * <li>When both the view and its children are irrelevant for autofill (for example, the root
+ * view of an activity containing a spreadhseet editor), it should be
+ * {@link View#IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS}.
+ * <li>When the view content is relevant for autofill but its children aren't (for example,
+ * a credit card expiration date represented by a custom view that overrides the proper
+ * autofill methods and has 2 children representing the month and year), it should
+ * be {@link View#IMPORTANT_FOR_AUTOFILL_YES_EXCLUDE_DESCENDANTS}.
+ * </ol>
+ *
+ * <p><b>NOTE:</strong> setting the mode as does {@link View#IMPORTANT_FOR_AUTOFILL_NO} or
+ * {@link View#IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS} does not guarantee the view (and
+ * its children) will be always be considered not important; for example, when the user
+ * explicitly makes an autofill request, all views are considered important. See
+ * {@link #isImportantForAutofill(View)} for more details about how the View's importance for
+ * autofill is used.
+ *
+ * <p>This method is only supported on API >= 26.
+ * On API 25 and below, it is a no-op</p>
+ *
+ *
+ * @param mode {@link View#IMPORTANT_FOR_AUTOFILL_AUTO},
+ * {@link View#IMPORTANT_FOR_AUTOFILL_YES},
+ * {@link View#IMPORTANT_FOR_AUTOFILL_NO},
+ * {@link View#IMPORTANT_FOR_AUTOFILL_YES_EXCLUDE_DESCENDANTS},
+ * or {@link View#IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS}.
+ *
+ * @attr ref android.R.styleable#View_importantForAutofill
+ */
+ public static void setImportantForAutofill(@NonNull View v, @AutofillImportance int mode) {
+ IMPL.setImportantForAutofill(v, mode);
+ }
+
+ /**
+ * Hints the Android System whether the {@link android.app.assist.AssistStructure.ViewNode}
+ * associated with this view is considered important for autofill purposes.
+ *
+ * <p>Generally speaking, a view is important for autofill if:
+ * <ol>
+ * <li>The view can be autofilled by an {@link android.service.autofill.AutofillService}.
+ * <li>The view contents can help an {@link android.service.autofill.AutofillService}
+ * determine how other views can be autofilled.
+ * <ol>
+ *
+ * <p>For example, view containers should typically return {@code false} for performance reasons
+ * (since the important info is provided by their children), but if its properties have relevant
+ * information (for example, a resource id called {@code credentials}, it should return
+ * {@code true}. On the other hand, views representing labels or editable fields should
+ * typically return {@code true}, but in some cases they could return {@code false}
+ * (for example, if they're part of a "Captcha" mechanism).
+ *
+ * <p>The value returned by this method depends on the value returned by
+ * {@link #getImportantForAutofill(View)}:
+ *
+ * <ol>
+ * <li>if it returns {@link View#IMPORTANT_FOR_AUTOFILL_YES} or
+ * {@link View#IMPORTANT_FOR_AUTOFILL_YES_EXCLUDE_DESCENDANTS},
+ * then it returns {@code true}
+ * <li>if it returns {@link View#IMPORTANT_FOR_AUTOFILL_NO} or
+ * {@link View#IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS},
+ * then it returns {@code false}
+ * <li>if it returns {@link View#IMPORTANT_FOR_AUTOFILL_AUTO},
+ * then it uses some simple heuristics that can return {@code true}
+ * in some cases (like a container with a resource id), but {@code false} in most.
+ * <li>otherwise, it returns {@code false}.
+ * </ol>
+ *
+ * <p>When a view is considered important for autofill:
+ * <ul>
+ * <li>The view might automatically trigger an autofill request when focused on.
+ * <li>The contents of the view are included in the {@link android.view.ViewStructure}
+ * used in an autofill request.
+ * </ul>
+ *
+ * <p>On the other hand, when a view is considered not important for autofill:
+ * <ul>
+ * <li>The view never automatically triggers autofill requests, but it can trigger a manual
+ * request through {@link android.view.autofill.AutofillManager#requestAutofill(View)}.
+ * <li>The contents of the view are not included in the {@link android.view.ViewStructure}
+ * used in an autofill request, unless the request has the
+ * {@link View#AUTOFILL_FLAG_INCLUDE_NOT_IMPORTANT_VIEWS} flag.
+ * </ul>
+ *
+ * <p>This method is only supported on API >= 26.
+ * On API 25 and below, it will always return {@code true}.</p>
+ *
+ * @return whether the view is considered important for autofill.
+ *
+ * @see #setImportantForAutofill(View, int)
+ * @see View#IMPORTANT_FOR_AUTOFILL_AUTO
+ * @see View#IMPORTANT_FOR_AUTOFILL_YES
+ * @see View#IMPORTANT_FOR_AUTOFILL_NO
+ * @see View#IMPORTANT_FOR_AUTOFILL_YES_EXCLUDE_DESCENDANTS
+ * @see View#IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS
+ * @see android.view.autofill.AutofillManager#requestAutofill(View)
+ */
+ public static boolean isImportantForAutofill(@NonNull View v) {
+ return IMPL.isImportantForAutofill(v);
+ }
+
+ /**
* Checks whether provided View has an accessibility delegate attached to it.
*
* @param v The View instance to check
diff --git a/lifecycle/common/api/1.0.0.txt b/lifecycle/common/api/1.0.0.txt
new file mode 100644
index 0000000..151db2b
--- /dev/null
+++ b/lifecycle/common/api/1.0.0.txt
@@ -0,0 +1,44 @@
+package android.arch.lifecycle {
+
+ public abstract class Lifecycle {
+ ctor public Lifecycle();
+ method public abstract void addObserver(android.arch.lifecycle.LifecycleObserver);
+ method public abstract android.arch.lifecycle.Lifecycle.State getCurrentState();
+ method public abstract void removeObserver(android.arch.lifecycle.LifecycleObserver);
+ }
+
+ public static final class Lifecycle.Event extends java.lang.Enum {
+ method public static android.arch.lifecycle.Lifecycle.Event valueOf(java.lang.String);
+ method public static final android.arch.lifecycle.Lifecycle.Event[] values();
+ enum_constant public static final android.arch.lifecycle.Lifecycle.Event ON_ANY;
+ enum_constant public static final android.arch.lifecycle.Lifecycle.Event ON_CREATE;
+ enum_constant public static final android.arch.lifecycle.Lifecycle.Event ON_DESTROY;
+ enum_constant public static final android.arch.lifecycle.Lifecycle.Event ON_PAUSE;
+ enum_constant public static final android.arch.lifecycle.Lifecycle.Event ON_RESUME;
+ enum_constant public static final android.arch.lifecycle.Lifecycle.Event ON_START;
+ enum_constant public static final android.arch.lifecycle.Lifecycle.Event ON_STOP;
+ }
+
+ public static final class Lifecycle.State extends java.lang.Enum {
+ method public boolean isAtLeast(android.arch.lifecycle.Lifecycle.State);
+ method public static android.arch.lifecycle.Lifecycle.State valueOf(java.lang.String);
+ method public static final android.arch.lifecycle.Lifecycle.State[] values();
+ enum_constant public static final android.arch.lifecycle.Lifecycle.State CREATED;
+ enum_constant public static final android.arch.lifecycle.Lifecycle.State DESTROYED;
+ enum_constant public static final android.arch.lifecycle.Lifecycle.State INITIALIZED;
+ enum_constant public static final android.arch.lifecycle.Lifecycle.State RESUMED;
+ enum_constant public static final android.arch.lifecycle.Lifecycle.State STARTED;
+ }
+
+ public abstract interface LifecycleObserver {
+ }
+
+ public abstract interface LifecycleOwner {
+ method public abstract android.arch.lifecycle.Lifecycle getLifecycle();
+ }
+
+ public abstract class OnLifecycleEvent implements java.lang.annotation.Annotation {
+ }
+
+}
+
diff --git a/lifecycle/common/build.gradle b/lifecycle/common/build.gradle
index f9b8513..57cfd00 100644
--- a/lifecycle/common/build.gradle
+++ b/lifecycle/common/build.gradle
@@ -26,8 +26,8 @@
}
createAndroidCheckstyle(project)
-version = LibraryVersions.LIFECYCLES.toString()
+version = LibraryVersions.LIFECYCLES_CORE.toString()
supportLibrary {
name 'Android Lifecycle-Common'
publish true
diff --git a/lifecycle/compiler/build.gradle b/lifecycle/compiler/build.gradle
index 5d3dfdf..b1477f5 100644
--- a/lifecycle/compiler/build.gradle
+++ b/lifecycle/compiler/build.gradle
@@ -1,3 +1,5 @@
+import android.support.LibraryVersions
+
apply plugin: 'kotlin'
apply plugin: 'maven'
apply plugin: 'checkstyle'
@@ -23,4 +25,5 @@
testCompile files(org.gradle.internal.jvm.Jvm.current().getToolsJar())
}
+version = LibraryVersions.LIFECYCLES_EXT.toString()
createKotlinCheckstyle(project)
diff --git a/lifecycle/extensions/build.gradle b/lifecycle/extensions/build.gradle
index b3530ea..71c90ef 100644
--- a/lifecycle/extensions/build.gradle
+++ b/lifecycle/extensions/build.gradle
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+import android.support.LibraryVersions
import android.support.SupportLibraryExtension
apply plugin: android.support.FlatfootAndroidLibraryPlugin
@@ -55,6 +56,7 @@
createAndroidCheckstyle(project)
+version = LibraryVersions.LIFECYCLES_EXT.toString()
supportLibrary {
name 'Android Lifecycle Extensions'
publish true
diff --git a/lifecycle/reactivestreams/build.gradle b/lifecycle/reactivestreams/build.gradle
index 2f05cab..f973e0e 100644
--- a/lifecycle/reactivestreams/build.gradle
+++ b/lifecycle/reactivestreams/build.gradle
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+import android.support.LibraryVersions
import android.support.SupportLibraryExtension
apply plugin: android.support.FlatfootAndroidLibraryPlugin
@@ -55,6 +56,7 @@
createAndroidCheckstyle(project)
+version = LibraryVersions.LIFECYCLES_EXT.toString()
supportLibrary {
name 'Android Lifecycle Reactivestreams'
publish true
diff --git a/lifecycle/runtime/api/1.0.0.txt b/lifecycle/runtime/api/1.0.0.txt
new file mode 100644
index 0000000..93a55fc
--- /dev/null
+++ b/lifecycle/runtime/api/1.0.0.txt
@@ -0,0 +1,18 @@
+package android.arch.lifecycle {
+
+ public class LifecycleRegistry extends android.arch.lifecycle.Lifecycle {
+ ctor public LifecycleRegistry(android.arch.lifecycle.LifecycleOwner);
+ method public void addObserver(android.arch.lifecycle.LifecycleObserver);
+ method public android.arch.lifecycle.Lifecycle.State getCurrentState();
+ method public int getObserverCount();
+ method public void handleLifecycleEvent(android.arch.lifecycle.Lifecycle.Event);
+ method public void markState(android.arch.lifecycle.Lifecycle.State);
+ method public void removeObserver(android.arch.lifecycle.LifecycleObserver);
+ }
+
+ public abstract interface LifecycleRegistryOwner implements android.arch.lifecycle.LifecycleOwner {
+ method public abstract android.arch.lifecycle.LifecycleRegistry getLifecycle();
+ }
+
+}
+
diff --git a/lifecycle/runtime/build.gradle b/lifecycle/runtime/build.gradle
index 3280425..7678e95 100644
--- a/lifecycle/runtime/build.gradle
+++ b/lifecycle/runtime/build.gradle
@@ -35,8 +35,8 @@
}
createAndroidCheckstyle(project)
-version = LibraryVersions.LIFECYCLES.toString()
+version = LibraryVersions.LIFECYCLES_RUNTIME.toString()
supportLibrary {
name 'Android Lifecycle Runtime'
publish true
diff --git a/paging/common/build.gradle b/paging/common/build.gradle
index d627c90..a1945dd 100644
--- a/paging/common/build.gradle
+++ b/paging/common/build.gradle
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+import android.support.LibraryVersions
import android.support.SupportLibraryExtension;
apply plugin: android.support.SupportJavaLibraryPlugin
@@ -37,6 +38,7 @@
createAndroidCheckstyle(project)
createKotlinCheckstyle(project)
+version = LibraryVersions.PAGING.toString()
supportLibrary {
name 'Android Paging-Common'
publish false
diff --git a/paging/runtime/build.gradle b/paging/runtime/build.gradle
index 84d558d..8dad089 100644
--- a/paging/runtime/build.gradle
+++ b/paging/runtime/build.gradle
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+import android.support.LibraryVersions
import android.support.SupportLibraryExtension
apply plugin: android.support.FlatfootAndroidLibraryPlugin
@@ -66,6 +67,7 @@
}
}
+version = LibraryVersions.PAGING.toString()
supportLibrary {
name 'Android Lifecycle Extensions'
publish false
diff --git a/room/common/build.gradle b/room/common/build.gradle
index 7c2bd1b..4336583 100644
--- a/room/common/build.gradle
+++ b/room/common/build.gradle
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+import android.support.LibraryVersions
import android.support.SupportLibraryExtension;
apply plugin: android.support.SupportJavaLibraryPlugin
@@ -26,6 +27,7 @@
createAndroidCheckstyle(project)
+version = LibraryVersions.ROOM.toString()
supportLibrary {
name 'Android Room-Common'
publish true
diff --git a/room/compiler/build.gradle b/room/compiler/build.gradle
index bce93f4..8934f88 100644
--- a/room/compiler/build.gradle
+++ b/room/compiler/build.gradle
@@ -1,3 +1,5 @@
+import android.support.LibraryVersions
+
/*
* Copyright (C) 2016 The Android Open Source Project
*
@@ -24,6 +26,7 @@
main.java.srcDirs += antlrOut
}
project.ext.noDocs = true
+version = LibraryVersions.ROOM.toString()
// Temporary hack to stop AS to adding two guavas into test's classpath
configurations.all {
diff --git a/room/compiler/src/main/kotlin/android/arch/persistence/room/processor/ProcessorErrors.kt b/room/compiler/src/main/kotlin/android/arch/persistence/room/processor/ProcessorErrors.kt
index 1e0963b..7b9e0b9 100644
--- a/room/compiler/src/main/kotlin/android/arch/persistence/room/processor/ProcessorErrors.kt
+++ b/room/compiler/src/main/kotlin/android/arch/persistence/room/processor/ProcessorErrors.kt
@@ -29,7 +29,7 @@
object ProcessorErrors {
private fun String.trim(): String {
- return this.trimIndent().replace(System.lineSeparator(), " ")
+ return this.trimIndent().replace("\n", " ")
}
val MISSING_QUERY_ANNOTATION = "Query methods must be annotated with ${Query::class.java}"
val MISSING_INSERT_ANNOTATION = "Insertion methods must be annotated with ${Insert::class.java}"
diff --git a/room/compiler/src/main/kotlin/android/arch/persistence/room/vo/Index.kt b/room/compiler/src/main/kotlin/android/arch/persistence/room/vo/Index.kt
index 60adf2b..69f16f3 100644
--- a/room/compiler/src/main/kotlin/android/arch/persistence/room/vo/Index.kt
+++ b/room/compiler/src/main/kotlin/android/arch/persistence/room/vo/Index.kt
@@ -33,7 +33,7 @@
return """
CREATE $uniqueSQL INDEX `$name`
ON `$tableName` (${fields.map { it.columnName }.joinToString(", ") { "`$it`"}})
- """.trimIndent().replace(System.lineSeparator(), " ")
+ """.trimIndent().replace("\n", " ")
}
val columnNames by lazy { fields.map {it.columnName} }
diff --git a/room/db-impl/build.gradle b/room/db-impl/build.gradle
index 56df267..a5da1f1 100644
--- a/room/db-impl/build.gradle
+++ b/room/db-impl/build.gradle
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+import android.support.LibraryVersions
import android.support.SupportLibraryExtension
apply plugin: android.support.FlatfootAndroidLibraryPlugin
@@ -55,6 +56,7 @@
}
}
+version = LibraryVersions.ROOM.toString()
supportLibrary {
name 'Android DB-Impl'
publish true
diff --git a/room/db/build.gradle b/room/db/build.gradle
index 5fe3a1d..4757a79 100644
--- a/room/db/build.gradle
+++ b/room/db/build.gradle
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+import android.support.LibraryVersions
import android.support.SupportLibraryExtension
apply plugin: android.support.FlatfootAndroidLibraryPlugin
@@ -54,6 +55,7 @@
}
}
+version = LibraryVersions.ROOM.toString()
supportLibrary {
name 'Android DB'
publish true
diff --git a/room/migration/build.gradle b/room/migration/build.gradle
index 1aebefb..45785ef 100644
--- a/room/migration/build.gradle
+++ b/room/migration/build.gradle
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+import android.support.LibraryVersions
import android.support.SupportLibraryExtension;
apply plugin: android.support.SupportJavaLibraryPlugin
@@ -31,6 +32,7 @@
testCompile libs.mockito_core
}
+version = LibraryVersions.ROOM.toString()
supportLibrary {
name 'Android Room Migration'
publish true
diff --git a/room/runtime/build.gradle b/room/runtime/build.gradle
index fa00e78..18fa660 100644
--- a/room/runtime/build.gradle
+++ b/room/runtime/build.gradle
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+import android.support.LibraryVersions
import android.support.SupportLibraryExtension
apply plugin: android.support.FlatfootAndroidLibraryPlugin
@@ -75,6 +76,7 @@
}
}
+version = LibraryVersions.ROOM.toString()
supportLibrary {
name 'Android Room-Runtime'
publish true
diff --git a/room/rxjava2/build.gradle b/room/rxjava2/build.gradle
index 0b6a499..d35e7d5 100644
--- a/room/rxjava2/build.gradle
+++ b/room/rxjava2/build.gradle
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+import android.support.LibraryVersions
import android.support.SupportLibraryExtension
apply plugin: android.support.FlatfootAndroidLibraryPlugin
@@ -68,6 +69,7 @@
}
}
+version = LibraryVersions.ROOM.toString()
supportLibrary {
name 'Android Room RXJava2'
publish true
diff --git a/room/testing/build.gradle b/room/testing/build.gradle
index e0264f2..ad25e64 100644
--- a/room/testing/build.gradle
+++ b/room/testing/build.gradle
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+import android.support.LibraryVersions
import android.support.SupportLibraryExtension
apply plugin: android.support.FlatfootAndroidLibraryPlugin
@@ -61,6 +62,7 @@
}
}
+version = LibraryVersions.ROOM.toString()
supportLibrary {
name 'Android Room Testimg'
publish true
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/GuidedStepSupportActivity.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/GuidedStepSupportActivity.java
index 717fccd..c0f9361 100644
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/GuidedStepSupportActivity.java
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/GuidedStepSupportActivity.java
@@ -546,8 +546,10 @@
@Override
public void onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState) {
- String desc = "The description can be quite long as well. " +
- "Just be sure to set multilineDescription to true in the GuidedAction.";
+ String desc = "The description can be quite long as well. "
+ + "Just be sure to set multilineDescription to true in the GuidedAction."
+ + "For testing purpose we make this line even longer since "
+ + "multilineDescriptionMinLines will be set to 2.";
actions.add(new GuidedAction.Builder(getActivity())
.title("Note that Guided Actions can have titles that are quite long.")
.description(desc)
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/PhotoItem.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/PhotoItem.java
index adde7d3..c839560 100644
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/PhotoItem.java
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/PhotoItem.java
@@ -17,7 +17,7 @@
import android.os.Parcelable;
public class PhotoItem implements Parcelable {
-
+ private int mId;
private String mTitle;
private String mContent;
private int mImageResourceId;
@@ -26,10 +26,22 @@
this(title, null, imageResourceId);
}
+ public PhotoItem(String title, int imageResourceId, int id) {
+ this(title, imageResourceId);
+ mId = id;
+ }
+
public PhotoItem(String title, String content, int imageResourceId) {
mTitle = title;
mContent = content;
mImageResourceId = imageResourceId;
+ // the id was set to -1 if user don't provide this parameter
+ mId = -1;
+ }
+
+ public PhotoItem(String title, String content, int imageResourceId, int id) {
+ this(title, content, imageResourceId);
+ mId = id;
}
public int getImageResourceId() {
@@ -73,8 +85,34 @@
}
};
+ public int getId() {
+ return this.mId;
+ }
+
private PhotoItem(Parcel in) {
mTitle = in.readString();
mImageResourceId = in.readInt();
}
-}
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ PhotoItem photoItem = (PhotoItem) o;
+ if (mId != photoItem.mId) return false;
+ if (mImageResourceId != photoItem.mImageResourceId) return false;
+ if (mTitle != null ? !mTitle.equals(photoItem.mTitle) : photoItem.mTitle != null) {
+ return false;
+ }
+ return mContent != null ? mContent.equals(photoItem.mContent) : photoItem.mContent == null;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = mId;
+ result = 31 * result + (mTitle != null ? mTitle.hashCode() : 0);
+ result = 31 * result + (mContent != null ? mContent.hashCode() : 0);
+ result = 31 * result + mImageResourceId;
+ return result;
+ }
+}
\ No newline at end of file
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/SampleVideoSupportFragment.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/SampleVideoSupportFragment.java
index 5891560..4af3ef7 100644
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/SampleVideoSupportFragment.java
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/SampleVideoSupportFragment.java
@@ -50,7 +50,7 @@
public class SampleVideoSupportFragment extends android.support.v17.leanback.app.VideoSupportFragment {
// Media Session Token
- private static final String MEDIA_SESSION_COMPAT_TOKEN = "media session video";
+ private static final String MEDIA_SESSION_COMPAT_TOKEN = "media session support video";
private PlaybackTransportControlGlueSample<MediaPlayerAdapter> mMediaPlayerGlue;
@@ -158,7 +158,7 @@
mMediaPlayerGlue = new PlaybackTransportControlGlueSample(getActivity(),
new MediaPlayerAdapter(getActivity()));
- // If the glue is switched, re-register the mediasession
+ // If the glue is switched, re-register the media session
mMediaPlayerGlue.connectToMediaSession(mMediaSessionCompat);
mMediaPlayerGlue.setMode(PlaybackControlsRow.RepeatAction.INDEX_ONE);
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/SearchFragment.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/SearchFragment.java
index 7152bae..0c9cb7f 100644
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/SearchFragment.java
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/SearchFragment.java
@@ -5,6 +5,7 @@
import android.os.Bundle;
import android.os.Handler;
import android.support.v17.leanback.widget.ArrayObjectAdapter;
+import android.support.v17.leanback.widget.DiffCallback;
import android.support.v17.leanback.widget.HeaderItem;
import android.support.v17.leanback.widget.ImageCardView;
import android.support.v17.leanback.widget.ListRow;
@@ -19,8 +20,10 @@
import android.text.TextUtils;
import android.util.Log;
+import java.util.ArrayList;
+
public class SearchFragment extends android.support.v17.leanback.app.SearchFragment
- implements android.support.v17.leanback.app.SearchFragment.SearchResultProvider {
+ implements android.support.v17.leanback.app.SearchFragment.SearchResultProvider {
private static final String TAG = "leanback.SearchFragment";
private static final int NUM_ROWS = 3;
private static final int SEARCH_DELAY_MS = 1000;
@@ -29,6 +32,31 @@
private Handler mHandler = new Handler();
private String mQuery;
+ // Flag to represent if data set one is presented in the fragment
+ private boolean mIsDataSetOnePresented;
+
+ // Adapter for first row
+ private ArrayObjectAdapter mFirstRowAdapter;
+
+ // The diff callback which defines the standard to judge if two items are the same or if
+ // two items have the same content.
+ private DiffCallback<PhotoItem> mDiffCallback = new DiffCallback<PhotoItem>() {
+
+ // when two photo items have the same id, they are the same from adapter's
+ // perspective
+ @Override
+ public boolean areItemsTheSame(PhotoItem oldItem, PhotoItem newItem) {
+ return oldItem.getId() == newItem.getId();
+ }
+
+ // when two photo items is equal to each other (based on the equal method defined in
+ // PhotoItem), they have the same content.
+ @Override
+ public boolean areContentsTheSame(PhotoItem oldItem, PhotoItem newItem) {
+ return oldItem.equals(newItem);
+ }
+ };
+
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -73,11 +101,29 @@
}
private void loadRows() {
- for (int i = 0; i < NUM_ROWS; ++i) {
+ HeaderItem header = new HeaderItem(0, mQuery + " results row " + 0);
+
+ // Every time when the query event is fired, we will update the fake search result in the
+ // first row based on the flag mIsDataSetOnePresented flag.
+ // Also the first row adapter will only be created once so the animation will be triggered
+ // when the items in the adapter changed.
+ if (!mIsDataSetOnePresented) {
+ if (mFirstRowAdapter == null) {
+ mFirstRowAdapter = createFirstListRowAdapter();
+ } else {
+ mFirstRowAdapter.setItems(createDataSetOne(), mDiffCallback);
+ }
+ mIsDataSetOnePresented = true;
+ } else {
+ mFirstRowAdapter.setItems(createDataSetTwo(), mDiffCallback);
+ mIsDataSetOnePresented = false;
+ }
+ mRowsAdapter.add(new ListRow(header, mFirstRowAdapter));
+ for (int i = 1; i < NUM_ROWS + 1; ++i) {
ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(new CardPresenter());
listRowAdapter.add(new PhotoItem("Hello world", R.drawable.gallery_photo_1));
listRowAdapter.add(new PhotoItem("This is a test", R.drawable.gallery_photo_2));
- HeaderItem header = new HeaderItem(i, mQuery + " results row " + i);
+ header = new HeaderItem(i, mQuery + " results row " + i);
mRowsAdapter.add(new ListRow(header, listRowAdapter));
}
}
@@ -98,9 +144,155 @@
Bundle bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(
getActivity(),
- ((ImageCardView)itemViewHolder.view).getMainImageView(),
+ ((ImageCardView) itemViewHolder.view).getMainImageView(),
DetailsActivity.SHARED_ELEMENT_NAME).toBundle();
getActivity().startActivity(intent, bundle);
}
}
+
+
+ private ArrayObjectAdapter createFirstListRowAdapter() {
+ ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(new CardPresenter());
+ listRowAdapter.setItems(createDataSetOne(), mDiffCallback);
+ mIsDataSetOnePresented = true;
+ return listRowAdapter;
+ }
+
+ /**
+ * Create a data set (data set one) for the last row of this browse fragment. It will be
+ * changed by another set of data when user click one of the photo items in the list.
+ * Different with other rows in the browsing fragment, the photo item in last row all have been
+ * allocated with a unique id. And the id will be used to jduge if two photo items are the same
+ * or not.
+ *
+ * @return List of photoItem
+ */
+ private ArrayList<PhotoItem> createDataSetOne() {
+ ArrayList<PhotoItem> photoItems = new ArrayList<>();
+ photoItems.add(new PhotoItem(
+ "Hello world",
+ R.drawable.gallery_photo_1,
+ 1));
+ photoItems.add(new PhotoItem(
+ "This is a test",
+ "Only a test",
+ R.drawable.gallery_photo_2,
+ 2));
+ photoItems.add(new PhotoItem(
+ "Android TV",
+ "by Google",
+ R.drawable.gallery_photo_3,
+ 3));
+ photoItems.add(new PhotoItem(
+ "Leanback",
+ R.drawable.gallery_photo_4,
+ 4));
+ photoItems.add(new PhotoItem(
+ "GuidedStep (Slide left/right)",
+ R.drawable.gallery_photo_5,
+ 5));
+ photoItems.add(new PhotoItem(
+ "GuidedStep (Slide bottom up)",
+ "Open GuidedStepFragment",
+ R.drawable.gallery_photo_6,
+ 6));
+ photoItems.add(new PhotoItem(
+ "Android TV",
+ "open RowsActivity",
+ R.drawable.gallery_photo_7,
+ 7));
+ photoItems.add(new PhotoItem(
+ "Leanback",
+ "open BrowseActivity",
+ R.drawable.gallery_photo_8,
+ 8));
+ photoItems.add(new PhotoItem(
+ "Hello world",
+ R.drawable.gallery_photo_1,
+ 1));
+ photoItems.add(new PhotoItem(
+ "This is a test",
+ "Only a test",
+ R.drawable.gallery_photo_2,
+ 2));
+ photoItems.add(new PhotoItem(
+ "Android TV",
+ "by Google",
+ R.drawable.gallery_photo_3,
+ 3));
+ photoItems.add(new PhotoItem(
+ "Leanback",
+ R.drawable.gallery_photo_4,
+ 4));
+ return photoItems;
+ }
+
+ /**
+ * Create a new data set (data set one) for the last row of this browse fragment. It will be
+ * changed by another set of data when user click one of the photo items in the list.
+ * Different with other rows in the browsing fragment, the photo item in last row all have been
+ * allocated with a unique id. And the id will be used to jduge if two photo items are the same
+ * or not.
+ *
+ * @return List of photoItem
+ */
+ private ArrayList<PhotoItem> createDataSetTwo() {
+ ArrayList<PhotoItem> photoItems = new ArrayList<>();
+ photoItems.add(new PhotoItem(
+ "This is a test",
+ "Only a test",
+ R.drawable.gallery_photo_2,
+ 2));
+ photoItems.add(new PhotoItem(
+ "Hello world",
+ R.drawable.gallery_photo_1,
+ 1));
+ photoItems.add(new PhotoItem(
+ "Leanback",
+ R.drawable.gallery_photo_4,
+ 4));
+ photoItems.add(new PhotoItem(
+ "Android TV",
+ "by Google",
+ R.drawable.gallery_photo_3,
+ 3));
+ photoItems.add(new PhotoItem(
+ "change title",
+ R.drawable.gallery_photo_5,
+ 5));
+ photoItems.add(new PhotoItem(
+ "GuidedStep (Slide bottom up)",
+ "change comment",
+ R.drawable.gallery_photo_6,
+ 6));
+ photoItems.add(new PhotoItem(
+ "Android TV",
+ R.drawable.gallery_photo_7,
+ 7));
+ photoItems.add(new PhotoItem(
+ "Leanback",
+ "open BrowseActivity",
+ R.drawable.gallery_photo_7,
+ 8));
+ photoItems.add(new PhotoItem(
+ "Hello world",
+ R.drawable.gallery_photo_1,
+ 10));
+ photoItems.add(new PhotoItem(
+ "This is a test",
+ "Only a test",
+ R.drawable.gallery_photo_2,
+ 20));
+ photoItems.add(new PhotoItem(
+ "Android TV",
+ "by Google",
+ R.drawable.gallery_photo_3,
+ 30));
+ photoItems.add(new PhotoItem(
+ "Leanback",
+ R.drawable.gallery_photo_4,
+ 40));
+ return photoItems;
+ }
+
}
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/SearchSupportFragment.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/SearchSupportFragment.java
index 0a3baf2..af56352 100644
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/SearchSupportFragment.java
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/SearchSupportFragment.java
@@ -8,6 +8,7 @@
import android.os.Bundle;
import android.os.Handler;
import android.support.v17.leanback.widget.ArrayObjectAdapter;
+import android.support.v17.leanback.widget.DiffCallback;
import android.support.v17.leanback.widget.HeaderItem;
import android.support.v17.leanback.widget.ImageCardView;
import android.support.v17.leanback.widget.ListRow;
@@ -22,8 +23,10 @@
import android.text.TextUtils;
import android.util.Log;
+import java.util.ArrayList;
+
public class SearchSupportFragment extends android.support.v17.leanback.app.SearchSupportFragment
- implements android.support.v17.leanback.app.SearchSupportFragment.SearchResultProvider {
+ implements android.support.v17.leanback.app.SearchSupportFragment.SearchResultProvider {
private static final String TAG = "leanback.SearchSupportFragment";
private static final int NUM_ROWS = 3;
private static final int SEARCH_DELAY_MS = 1000;
@@ -32,6 +35,31 @@
private Handler mHandler = new Handler();
private String mQuery;
+ // Flag to represent if data set one is presented in the fragment
+ private boolean mIsDataSetOnePresented;
+
+ // Adapter for first row
+ private ArrayObjectAdapter mFirstRowAdapter;
+
+ // The diff callback which defines the standard to judge if two items are the same or if
+ // two items have the same content.
+ private DiffCallback<PhotoItem> mDiffCallback = new DiffCallback<PhotoItem>() {
+
+ // when two photo items have the same id, they are the same from adapter's
+ // perspective
+ @Override
+ public boolean areItemsTheSame(PhotoItem oldItem, PhotoItem newItem) {
+ return oldItem.getId() == newItem.getId();
+ }
+
+ // when two photo items is equal to each other (based on the equal method defined in
+ // PhotoItem), they have the same content.
+ @Override
+ public boolean areContentsTheSame(PhotoItem oldItem, PhotoItem newItem) {
+ return oldItem.equals(newItem);
+ }
+ };
+
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -76,11 +104,29 @@
}
private void loadRows() {
- for (int i = 0; i < NUM_ROWS; ++i) {
+ HeaderItem header = new HeaderItem(0, mQuery + " results row " + 0);
+
+ // Every time when the query event is fired, we will update the fake search result in the
+ // first row based on the flag mIsDataSetOnePresented flag.
+ // Also the first row adapter will only be created once so the animation will be triggered
+ // when the items in the adapter changed.
+ if (!mIsDataSetOnePresented) {
+ if (mFirstRowAdapter == null) {
+ mFirstRowAdapter = createFirstListRowAdapter();
+ } else {
+ mFirstRowAdapter.setItems(createDataSetOne(), mDiffCallback);
+ }
+ mIsDataSetOnePresented = true;
+ } else {
+ mFirstRowAdapter.setItems(createDataSetTwo(), mDiffCallback);
+ mIsDataSetOnePresented = false;
+ }
+ mRowsAdapter.add(new ListRow(header, mFirstRowAdapter));
+ for (int i = 1; i < NUM_ROWS + 1; ++i) {
ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(new CardPresenter());
listRowAdapter.add(new PhotoItem("Hello world", R.drawable.gallery_photo_1));
listRowAdapter.add(new PhotoItem("This is a test", R.drawable.gallery_photo_2));
- HeaderItem header = new HeaderItem(i, mQuery + " results row " + i);
+ header = new HeaderItem(i, mQuery + " results row " + i);
mRowsAdapter.add(new ListRow(header, listRowAdapter));
}
}
@@ -101,9 +147,155 @@
Bundle bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(
getActivity(),
- ((ImageCardView)itemViewHolder.view).getMainImageView(),
+ ((ImageCardView) itemViewHolder.view).getMainImageView(),
DetailsSupportActivity.SHARED_ELEMENT_NAME).toBundle();
getActivity().startActivity(intent, bundle);
}
}
+
+
+ private ArrayObjectAdapter createFirstListRowAdapter() {
+ ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(new CardPresenter());
+ listRowAdapter.setItems(createDataSetOne(), mDiffCallback);
+ mIsDataSetOnePresented = true;
+ return listRowAdapter;
+ }
+
+ /**
+ * Create a data set (data set one) for the last row of this browse fragment. It will be
+ * changed by another set of data when user click one of the photo items in the list.
+ * Different with other rows in the browsing fragment, the photo item in last row all have been
+ * allocated with a unique id. And the id will be used to jduge if two photo items are the same
+ * or not.
+ *
+ * @return List of photoItem
+ */
+ private ArrayList<PhotoItem> createDataSetOne() {
+ ArrayList<PhotoItem> photoItems = new ArrayList<>();
+ photoItems.add(new PhotoItem(
+ "Hello world",
+ R.drawable.gallery_photo_1,
+ 1));
+ photoItems.add(new PhotoItem(
+ "This is a test",
+ "Only a test",
+ R.drawable.gallery_photo_2,
+ 2));
+ photoItems.add(new PhotoItem(
+ "Android TV",
+ "by Google",
+ R.drawable.gallery_photo_3,
+ 3));
+ photoItems.add(new PhotoItem(
+ "Leanback",
+ R.drawable.gallery_photo_4,
+ 4));
+ photoItems.add(new PhotoItem(
+ "GuidedStep (Slide left/right)",
+ R.drawable.gallery_photo_5,
+ 5));
+ photoItems.add(new PhotoItem(
+ "GuidedStep (Slide bottom up)",
+ "Open GuidedStepFragment",
+ R.drawable.gallery_photo_6,
+ 6));
+ photoItems.add(new PhotoItem(
+ "Android TV",
+ "open RowsActivity",
+ R.drawable.gallery_photo_7,
+ 7));
+ photoItems.add(new PhotoItem(
+ "Leanback",
+ "open BrowseActivity",
+ R.drawable.gallery_photo_8,
+ 8));
+ photoItems.add(new PhotoItem(
+ "Hello world",
+ R.drawable.gallery_photo_1,
+ 1));
+ photoItems.add(new PhotoItem(
+ "This is a test",
+ "Only a test",
+ R.drawable.gallery_photo_2,
+ 2));
+ photoItems.add(new PhotoItem(
+ "Android TV",
+ "by Google",
+ R.drawable.gallery_photo_3,
+ 3));
+ photoItems.add(new PhotoItem(
+ "Leanback",
+ R.drawable.gallery_photo_4,
+ 4));
+ return photoItems;
+ }
+
+ /**
+ * Create a new data set (data set one) for the last row of this browse fragment. It will be
+ * changed by another set of data when user click one of the photo items in the list.
+ * Different with other rows in the browsing fragment, the photo item in last row all have been
+ * allocated with a unique id. And the id will be used to jduge if two photo items are the same
+ * or not.
+ *
+ * @return List of photoItem
+ */
+ private ArrayList<PhotoItem> createDataSetTwo() {
+ ArrayList<PhotoItem> photoItems = new ArrayList<>();
+ photoItems.add(new PhotoItem(
+ "This is a test",
+ "Only a test",
+ R.drawable.gallery_photo_2,
+ 2));
+ photoItems.add(new PhotoItem(
+ "Hello world",
+ R.drawable.gallery_photo_1,
+ 1));
+ photoItems.add(new PhotoItem(
+ "Leanback",
+ R.drawable.gallery_photo_4,
+ 4));
+ photoItems.add(new PhotoItem(
+ "Android TV",
+ "by Google",
+ R.drawable.gallery_photo_3,
+ 3));
+ photoItems.add(new PhotoItem(
+ "change title",
+ R.drawable.gallery_photo_5,
+ 5));
+ photoItems.add(new PhotoItem(
+ "GuidedStep (Slide bottom up)",
+ "change comment",
+ R.drawable.gallery_photo_6,
+ 6));
+ photoItems.add(new PhotoItem(
+ "Android TV",
+ R.drawable.gallery_photo_7,
+ 7));
+ photoItems.add(new PhotoItem(
+ "Leanback",
+ "open BrowseActivity",
+ R.drawable.gallery_photo_7,
+ 8));
+ photoItems.add(new PhotoItem(
+ "Hello world",
+ R.drawable.gallery_photo_1,
+ 10));
+ photoItems.add(new PhotoItem(
+ "This is a test",
+ "Only a test",
+ R.drawable.gallery_photo_2,
+ 20));
+ photoItems.add(new PhotoItem(
+ "Android TV",
+ "by Google",
+ R.drawable.gallery_photo_3,
+ 30));
+ photoItems.add(new PhotoItem(
+ "Leanback",
+ R.drawable.gallery_photo_4,
+ 40));
+ return photoItems;
+ }
+
}
diff --git a/v17/leanback/api/current.txt b/v17/leanback/api/current.txt
index 4795807..1db7e5f 100644
--- a/v17/leanback/api/current.txt
+++ b/v17/leanback/api/current.txt
@@ -1541,10 +1541,12 @@
method public void clear();
method public java.lang.Object get(int);
method public int indexOf(java.lang.Object);
+ method public void move(int, int);
method public void notifyArrayItemRangeChanged(int, int);
method public boolean remove(java.lang.Object);
method public int removeItems(int, int);
method public void replace(int, java.lang.Object);
+ method public void setItems(java.util.List, android.support.v17.leanback.widget.DiffCallback);
method public int size();
method public <E> java.util.List<E> unmodifiableList();
}
@@ -1813,6 +1815,12 @@
method public android.support.v17.leanback.widget.Parallax.IntProperty getOverviewRowTop();
}
+ public abstract class DiffCallback<T> {
+ ctor public DiffCallback();
+ method public abstract boolean areContentsTheSame(T, T);
+ method public abstract boolean areItemsTheSame(T, T);
+ }
+
public class DividerPresenter extends android.support.v17.leanback.widget.Presenter {
ctor public DividerPresenter();
method public void onBindViewHolder(android.support.v17.leanback.widget.Presenter.ViewHolder, java.lang.Object);
@@ -2389,6 +2397,7 @@
method public final boolean hasStableIds();
method public boolean isImmediateNotifySupported();
method protected final void notifyChanged();
+ method protected final void notifyItemMoved(int, int);
method public final void notifyItemRangeChanged(int, int);
method protected final void notifyItemRangeInserted(int, int);
method protected final void notifyItemRangeRemoved(int, int);
@@ -2406,6 +2415,7 @@
public static abstract class ObjectAdapter.DataObserver {
ctor public ObjectAdapter.DataObserver();
method public void onChanged();
+ method public void onItemMoved(int, int);
method public void onItemRangeChanged(int, int);
method public void onItemRangeInserted(int, int);
method public void onItemRangeRemoved(int, int);
diff --git a/v17/leanback/res/values-pa/strings.xml b/v17/leanback/res/values-pa/strings.xml
index eb58bd6..4b3c515 100644
--- a/v17/leanback/res/values-pa/strings.xml
+++ b/v17/leanback/res/values-pa/strings.xml
@@ -41,11 +41,11 @@
<string name="lb_playback_controls_repeat_none" msgid="87476947476529036">"ਕੋਈ ਵੀ ਨਾ ਦੁਹਰਾਓ"</string>
<string name="lb_playback_controls_repeat_all" msgid="6730354406289599000">"ਸਾਰਿਆਂ ਨੂੰ ਦੁਹਰਾਓ"</string>
<string name="lb_playback_controls_repeat_one" msgid="3285202316452203619">"ਇੱਕ ਦੁਹਰਾਓ"</string>
- <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"ਸ਼ਫਲ ਨੂੰ ਸਮਰੱਥ ਬਣਾਓ"</string>
+ <string name="lb_playback_controls_shuffle_enable" msgid="1099874107835264529">"ਬੇਤਰਤੀਬ ਨੂੰ ਚਾਲੂ ਕਰੋ"</string>
<string name="lb_playback_controls_shuffle_disable" msgid="8388150597335115226">"ਸ਼ਫਲ ਨੂੰ ਅਸਮਰੱਥ ਬਣਾਓ"</string>
- <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"ਉੱਚ ਗੁਣਵੱਤਾ ਨੂੰ ਸਮਰੱਥ ਬਣਾਓ"</string>
+ <string name="lb_playback_controls_high_quality_enable" msgid="202415780019335254">"ਉੱਚ ਗੁਣਵੱਤਾ ਨੂੰ ਚਾਲੂ ਕਰੋ"</string>
<string name="lb_playback_controls_high_quality_disable" msgid="8637371582779057866">"ਉੱਚ ਗੁਣਵੱਤਾ ਨੂੰ ਅਸਮਰੱਥ ਬਣਾਓ"</string>
- <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"ਬੰਦ ਕੈਪਸ਼ਨਿੰਗ ਸਮਰੱਥ ਬਣਾਓ"</string>
+ <string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"ਬੰਦ ਸੁਰਖੀਆਂ ਚਾਲੂ ਕਰੋ"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"ਬੰਦ ਕੈਪਸ਼ਨਿੰਗ ਅਸਮਰੱਥ ਬਣਾਓ"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"ਤਸਵੀਰ ਮੋਡ ਵਿੱਚ ਤਸਵੀਰ ਦਾਖਲ ਕਰੋ"</string>
<string name="lb_playback_time_separator" msgid="3208380806582304911">"/"</string>
diff --git a/v17/leanback/res/values-te/strings.xml b/v17/leanback/res/values-te/strings.xml
index 34ea221..5188d19 100644
--- a/v17/leanback/res/values-te/strings.xml
+++ b/v17/leanback/res/values-te/strings.xml
@@ -31,7 +31,7 @@
<string name="lb_playback_controls_fast_forward_multiplier" msgid="1058753672110224526">"%1$dX ఫాస్ట్ ఫార్వార్డ్ చేయి"</string>
<string name="lb_playback_controls_rewind" msgid="2227196334132350684">"రివైండ్ చేయి"</string>
<string name="lb_playback_controls_rewind_multiplier" msgid="1640629531440849942">"%1$dX రివైండ్ చేయి"</string>
- <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"తదుపరి దానికి దాటవేయి"</string>
+ <string name="lb_playback_controls_skip_next" msgid="2946499493161095772">"తర్వాత దానికి దాటవేయి"</string>
<string name="lb_playback_controls_skip_previous" msgid="2326801832933178348">"మునుపటి దానికి దాటవేయి"</string>
<string name="lb_playback_controls_more_actions" msgid="2330770008796987655">"మరిన్ని చర్యలు"</string>
<string name="lb_playback_controls_thumb_up" msgid="6530420347129222601">"విజయ సంకేతం ఎంపికను తీసివేయి"</string>
@@ -55,5 +55,5 @@
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"కొనసాగించు"</string>
<string name="lb_media_player_error" msgid="3650250994187305396">"MediaPlayer ఎర్రర్ కోడ్ %1$d అదనంగా %2$d"</string>
<string name="lb_onboarding_get_started" msgid="6961440391306351139">"ప్రారంభించు"</string>
- <string name="lb_onboarding_accessibility_next" msgid="2918313444257732434">"తదుపరి"</string>
+ <string name="lb_onboarding_accessibility_next" msgid="2918313444257732434">"తర్వాత"</string>
</resources>
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/ArrayObjectAdapter.java b/v17/leanback/src/android/support/v17/leanback/widget/ArrayObjectAdapter.java
index b31d30a..40bd05f 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/ArrayObjectAdapter.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/ArrayObjectAdapter.java
@@ -13,6 +13,10 @@
*/
package android.support.v17.leanback.widget;
+import android.support.v7.util.DiffUtil;
+import android.support.v7.util.ListUpdateCallback;
+import android.util.Log;
+
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -23,7 +27,13 @@
*/
public class ArrayObjectAdapter extends ObjectAdapter {
- private ArrayList<Object> mItems = new ArrayList<Object>();
+ private static final Boolean DEBUG = false;
+ private static final String TAG = "ArrayObjectAdapter";
+
+ private final List mItems = new ArrayList<Object>();
+
+ // Un modifiable version of mItems;
+ private List mUnmodifiableItems;
/**
* Constructs an adapter with the given {@link PresenterSelector}.
@@ -60,9 +70,9 @@
* Returns the index for the first occurrence of item in the adapter, or -1 if
* not found.
*
- * @param item The item to find in the list.
+ * @param item The item to find in the list.
* @return Index of the first occurrence of the item in the adapter, or -1
- * if not found.
+ * if not found.
*/
public int indexOf(Object item) {
return mItems.indexOf(item);
@@ -73,7 +83,7 @@
* not same as items being added or removed.
*
* @param positionStart The position of first item that has changed.
- * @param itemCount The count of how many items have changed.
+ * @param itemCount The count of how many items have changed.
*/
public void notifyArrayItemRangeChanged(int positionStart, int itemCount) {
notifyItemRangeChanged(positionStart, itemCount);
@@ -93,7 +103,7 @@
* If the index is > {@link #size} an exception will be thrown.
*
* @param index The index at which the item should be inserted.
- * @param item The item to insert into the adapter.
+ * @param item The item to insert into the adapter.
*/
public void add(int index, Object item) {
mItems.add(index, item);
@@ -132,11 +142,28 @@
}
/**
+ * Moved the item at fromPosition to toPosition.
+ *
+ * @param fromPosition Previous position of the item.
+ * @param toPosition New position of the item.
+ */
+ public void move(int fromPosition, int toPosition) {
+ if (fromPosition == toPosition) {
+ // no-op
+ return;
+ }
+ Object item = mItems.remove(fromPosition);
+ mItems.add(toPosition, item);
+ notifyItemMoved(fromPosition, toPosition);
+ }
+
+ /**
* Replaces item at position with a new item and calls notifyItemRangeChanged()
* at the given position. Note that this method does not compare new item to
* existing item.
- * @param position The index of item to replace.
- * @param item The new item to be placed at given position.
+ *
+ * @param position The index of item to replace.
+ * @param item The new item to be placed at given position.
*/
public void replace(int position, Object item) {
mItems.set(position, item);
@@ -148,7 +175,7 @@
* the starting position and the number of elements to remove.
*
* @param position The index of the first item to remove.
- * @param count The number of items to remove.
+ * @param count The number of items to remove.
* @return The number of items removed.
*/
public int removeItems(int position, int count) {
@@ -180,11 +207,92 @@
* Gets a read-only view of the list of object of this ArrayObjectAdapter.
*/
public <E> List<E> unmodifiableList() {
- return Collections.unmodifiableList((List<E>) mItems);
+
+ // The mUnmodifiableItems will only be created once as long as the content of mItems has not
+ // been changed.
+ if (mUnmodifiableItems == null) {
+ mUnmodifiableItems = Collections.unmodifiableList(mItems);
+ }
+ return mUnmodifiableItems;
}
@Override
public boolean isImmediateNotifySupported() {
return true;
}
+
+ /**
+ * Set a new item list to adapter. The DiffUtil will compute the difference and dispatch it to
+ * specified position.
+ *
+ * @param itemList List of new Items
+ * @param callback DiffCallback Object to compute the difference between the old data set and
+ * new data set.
+ */
+ public void setItems(final List itemList, final DiffCallback callback) {
+
+ DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new DiffUtil.Callback() {
+ @Override
+ public int getOldListSize() {
+ return mItems.size();
+ }
+
+ @Override
+ public int getNewListSize() {
+ return itemList.size();
+ }
+
+ @Override
+ public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
+ return callback.areItemsTheSame(mItems.get(oldItemPosition),
+ itemList.get(newItemPosition));
+ }
+
+ @Override
+ public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
+ return callback.areContentsTheSame(mItems.get(oldItemPosition),
+ itemList.get(newItemPosition));
+ }
+ });
+
+ // update items.
+ mItems.clear();
+ mItems.addAll(itemList);
+
+ // dispatch diff result
+ diffResult.dispatchUpdatesTo(new ListUpdateCallback() {
+
+ @Override
+ public void onInserted(int position, int count) {
+ if (DEBUG) {
+ Log.d(TAG, "onInserted");
+ }
+ notifyItemRangeInserted(position, count);
+ }
+
+ @Override
+ public void onRemoved(int position, int count) {
+ if (DEBUG) {
+ Log.d(TAG, "onRemoved");
+ }
+ notifyItemRangeRemoved(position, count);
+ }
+
+ @Override
+ public void onMoved(int fromPosition, int toPosition) {
+ if (DEBUG) {
+ Log.d(TAG, "onMoved");
+ }
+ notifyItemMoved(fromPosition, toPosition);
+ }
+
+ @Override
+ public void onChanged(int position, int count, Object payload) {
+ if (DEBUG) {
+ Log.d(TAG, "onChanged");
+ }
+ notifyItemRangeChanged(position, count);
+ }
+ });
+ }
}
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/DiffCallback.java b/v17/leanback/src/android/support/v17/leanback/widget/DiffCallback.java
new file mode 100644
index 0000000..841c864
--- /dev/null
+++ b/v17/leanback/src/android/support/v17/leanback/widget/DiffCallback.java
@@ -0,0 +1,46 @@
+/*
+ * 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.widget;
+
+/**
+ * This callback class which will be passed as the parameter for setItems method to compute the
+ * difference between the old items and new items.
+ *
+ * @param <T> The type of the item in list.
+ */
+public abstract class DiffCallback<T> {
+
+ /**
+ * This method is used to provide a standard to judge if two items are the same or not.
+ * Will be used by DiffUtil.calculateDiff method.
+ *
+ * @param oldItem Previous item.
+ * @param newItem New item.
+ * @return If two items are the same or not.
+ */
+ public abstract boolean areItemsTheSame(T oldItem, T newItem);
+
+ /**
+ * This method is used to provide a standard to judge if two items have the same content or
+ * not. Will be used by DiffUtil.calculateDiff method.
+ *
+ * @param oldItem Previous item.
+ * @param newItem New item.
+ * @return If two items have the same content.
+ */
+ public abstract boolean areContentsTheSame(T oldItem, T newItem);
+}
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 529f566..8b0c4a7 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/GridLayoutManager.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/GridLayoutManager.java
@@ -423,6 +423,7 @@
/**
* The orientation of a "row".
*/
+ @RecyclerView.Orientation
int mOrientation = HORIZONTAL;
private OrientationHelper mOrientationHelper = OrientationHelper.createHorizontalHelper(this);
@@ -674,7 +675,7 @@
setItemPrefetchEnabled(false);
}
- public void setOrientation(int orientation) {
+ public void setOrientation(@RecyclerView.Orientation int orientation) {
if (orientation != HORIZONTAL && orientation != VERTICAL) {
if (DEBUG) Log.v(getTag(), "invalid orientation: " + orientation);
return;
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/ItemBridgeAdapter.java b/v17/leanback/src/android/support/v17/leanback/widget/ItemBridgeAdapter.java
index f5dfd99..3ac708f 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/ItemBridgeAdapter.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/ItemBridgeAdapter.java
@@ -159,6 +159,11 @@
public void onItemRangeRemoved(int positionStart, int itemCount) {
ItemBridgeAdapter.this.notifyItemRangeRemoved(positionStart, itemCount);
}
+
+ @Override
+ public void onItemMoved(int fromPosition, int toPosition) {
+ ItemBridgeAdapter.this.notifyItemMoved(fromPosition, toPosition);
+ }
};
public ItemBridgeAdapter(ObjectAdapter adapter, PresenterSelector presenterSelector) {
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/ObjectAdapter.java b/v17/leanback/src/android/support/v17/leanback/widget/ObjectAdapter.java
index ff10028..d833385 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/ObjectAdapter.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/ObjectAdapter.java
@@ -60,6 +60,15 @@
}
/**
+ * Called when an item is moved from one position to another position
+ * @param fromPosition Previous position of the item.
+ * @param toPosition New position of the item.
+ */
+ public void onItemMoved(int fromPosition, int toPosition) {
+ onChanged();
+ }
+
+ /**
* Called when a range of items is removed from the ObjectAdapter.
*
* @param positionStart The position of the first removed item.
@@ -98,6 +107,12 @@
mObservers.get(i).onItemRangeRemoved(positionStart, itemCount);
}
}
+
+ public void notifyItemMoved(int positionStart, int toPosition) {
+ for (int i = mObservers.size() - 1; i >= 0; i--) {
+ mObservers.get(i).onItemMoved(positionStart, toPosition);
+ }
+ }
}
private final DataObservable mObservable = new DataObservable();
@@ -210,6 +225,16 @@
}
/**
+ * Notifies UI that item at fromPosition has been moved to toPosition.
+ *
+ * @param fromPosition Previous position of the item.
+ * @param toPosition New position of the item.
+ */
+ protected final void notifyItemMoved(int fromPosition, int toPosition) {
+ mObservable.notifyItemMoved(fromPosition, toPosition);
+ }
+
+ /**
* Notifies UI that the underlying data has changed.
*/
final protected void notifyChanged() {
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/widget/ObjectAdapterTest.java b/v17/leanback/tests/java/android/support/v17/leanback/widget/ObjectAdapterTest.java
new file mode 100644
index 0000000..7327166
--- /dev/null
+++ b/v17/leanback/tests/java/android/support/v17/leanback/widget/ObjectAdapterTest.java
@@ -0,0 +1,369 @@
+/*
+ * 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.widget;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.never;
+
+import android.support.test.filters.SmallTest;
+import android.support.v7.widget.RecyclerView;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.mockito.Mockito;
+
+import java.util.ArrayList;
+
+@SmallTest
+@RunWith(JUnit4.class)
+public class ObjectAdapterTest {
+
+ protected ItemBridgeAdapter mBridgeAdapter;
+ protected ObjectAdapter mAdapter;
+
+ static void assertAdapterContent(ObjectAdapter adapter, Object[] data) {
+ assertEquals(adapter.size(), data.length);
+ for (int i = 0; i < adapter.size(); i++) {
+ assertEquals(adapter.get(i), data[i]);
+ }
+ }
+
+ static class AdapterItem {
+ private int mId;
+ private String mName;
+
+ AdapterItem(int id, String name) {
+ this.mId = id;
+ this.mName = name;
+ }
+
+ public int getId() {
+ return mId;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ AdapterItem test = (AdapterItem) o;
+
+ if (mId != test.mId) return false;
+ return mName != null ? mName.equals(test.mName) : test.mName == null;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = mId;
+ result = 31 * result + (mName != null ? mName.hashCode() : 0);
+ return result;
+ }
+ }
+
+ @Test
+ public void arrayObjectAdapter() {
+ ArrayObjectAdapter adapter = new ArrayObjectAdapter();
+ mAdapter = adapter;
+ mBridgeAdapter = new ItemBridgeAdapter(mAdapter);
+ ArrayList items = new ArrayList();
+ items.add("a");
+ items.add("b");
+ items.add("c");
+ adapter.addAll(0, items);
+
+ RecyclerView.AdapterDataObserver observer = Mockito.mock(
+ RecyclerView.AdapterDataObserver.class);
+ mBridgeAdapter.registerAdapterDataObserver(observer);
+
+ // size
+ assertEquals(adapter.size(), 3);
+
+ // get
+ assertEquals(adapter.get(0), "a");
+ assertEquals(adapter.get(1), "b");
+ assertEquals(adapter.get(2), "c");
+
+ // indexOf
+ assertEquals(adapter.indexOf("a"), 0);
+ assertEquals(adapter.indexOf("b"), 1);
+ assertEquals(adapter.indexOf("c"), 2);
+
+ // insert
+ adapter.add(1, "a1");
+ Mockito.verify(observer).onItemRangeInserted(1, 1);
+ assertAdapterContent(adapter, new Object[]{"a", "a1", "b", "c"});
+ Mockito.reset(observer);
+
+ // insert multiple
+ ArrayList newItems1 = new ArrayList();
+ newItems1.add("a2");
+ newItems1.add("a3");
+ adapter.addAll(1, newItems1);
+ Mockito.verify(observer).onItemRangeInserted(1, 2);
+ assertAdapterContent(adapter, new Object[]{"a", "a2", "a3", "a1", "b", "c"});
+ Mockito.reset(observer);
+
+ // update
+ adapter.notifyArrayItemRangeChanged(2, 3);
+ Mockito.verify(observer).onItemRangeChanged(2, 3, null);
+ assertAdapterContent(adapter, new Object[]{"a", "a2", "a3", "a1", "b", "c"});
+ Mockito.reset(observer);
+
+ // remove
+ adapter.removeItems(1, 4);
+ Mockito.verify(observer).onItemRangeRemoved(1, 4);
+ assertAdapterContent(adapter, new Object[]{"a", "c"});
+ Mockito.reset(observer);
+
+ // move
+ adapter.move(0, 1);
+ Mockito.verify(observer).onItemRangeMoved(0, 1, 1);
+ assertAdapterContent(adapter, new Object[]{"c", "a"});
+ Mockito.reset(observer);
+
+ // replace
+ adapter.replace(0, "a");
+ Mockito.verify(observer).onItemRangeChanged(0, 1, null);
+ assertAdapterContent(adapter, new Object[]{"a", "a"});
+ Mockito.reset(observer);
+ adapter.replace(1, "b");
+ Mockito.verify(observer).onItemRangeChanged(1, 1, null);
+ assertAdapterContent(adapter, new Object[]{"a", "b"});
+ Mockito.reset(observer);
+
+ // remove multiple
+ items.clear();
+ items.add("a");
+ items.add("b");
+ adapter.addAll(0, items);
+ adapter.removeItems(0, 2);
+ Mockito.verify(observer).onItemRangeRemoved(0, 2);
+ assertAdapterContent(adapter, new Object[]{"a", "b"});
+ Mockito.reset(observer);
+
+ // clear
+ adapter.clear();
+ Mockito.verify(observer).onItemRangeRemoved(0, 2);
+ assertAdapterContent(adapter, new Object[]{});
+ Mockito.reset(observer);
+
+ // isImmediateNotifySupported
+ assertTrue(adapter.isImmediateNotifySupported());
+
+ // setItems (test basic functionality with specialized comparator and verify adapter's item
+ // lists)
+ items.clear();
+ items.add("a");
+ items.add("b");
+ items.add("c");
+
+ DiffCallback callback = new DiffCallback<String>() {
+
+ // Always treat two items are the same.
+ @Override
+ public boolean areItemsTheSame(String oldItem, String newItem) {
+ return true;
+ }
+
+ // Always treat two items have the same content.
+ @Override
+ public boolean areContentsTheSame(String oldItem, String newItem) {
+ return true;
+ }
+ };
+
+ adapter.setItems(items, callback);
+ Mockito.verify(observer).onItemRangeInserted(0, 3);
+ assertAdapterContent(adapter, new Object[]{"a", "b", "c"});
+ Mockito.reset(observer);
+
+ // setItems (test basic functionality with specialized comparator and verify adapter's item
+ // lists)
+ items.clear();
+ items.add("a");
+ items.add("b");
+ items.add("c");
+
+ callback = new DiffCallback<String>() {
+
+ // Always treat two items are the different.
+ @Override
+ public boolean areItemsTheSame(String oldItem, String newItem) {
+ return false;
+ }
+
+ // Always treat two items have the different content.
+ @Override
+ public boolean areContentsTheSame(String oldItem, String newItem) {
+ return false;
+ }
+ };
+
+ adapter.setItems(items, callback);
+ Mockito.verify(observer).onItemRangeRemoved(0, 3);
+ Mockito.verify(observer).onItemRangeInserted(0, 3);
+
+ // No change or move event should be fired under current callback.
+ Mockito.verify(observer, never()).onItemRangeChanged(anyInt(), anyInt(), any());
+ Mockito.verify(observer, never()).onItemRangeMoved(anyInt(), anyInt(), anyInt());
+ assertAdapterContent(adapter, new Object[]{"a", "b", "c"});
+ Mockito.reset(observer);
+
+ // setItems (Using specialized java class to simulate actual scenario)
+ callback = new DiffCallback<AdapterItem>() {
+
+ // Using item's mId as the standard to judge if two items is the same
+ @Override
+ public boolean areItemsTheSame(AdapterItem oldItem, AdapterItem newItem) {
+ return oldItem.getId() == newItem.getId();
+ }
+
+ // Using equals method to judge if two items have the same content.
+ @Override
+ public boolean areContentsTheSame(AdapterItem oldItem, AdapterItem newItem) {
+ return oldItem.equals(newItem);
+ }
+ };
+
+
+ // Trigger notifyItemMoved event
+ adapter.clear();
+ items.clear();
+ items.add(new AdapterItem(1, "a"));
+ items.add(new AdapterItem(2, "b"));
+ items.add(new AdapterItem(3, "c"));
+ adapter.setItems(items, callback);
+ Mockito.reset(observer);
+ items.clear();
+ items.add(new AdapterItem(1, "a"));
+ items.add(new AdapterItem(2, "c"));
+ items.add(new AdapterItem(3, "b"));
+ adapter.setItems(items, callback);
+ Mockito.verify(observer).onItemRangeChanged(1, 2, null);
+ Mockito.reset(observer);
+
+ // Trigger notifyItemRangeChanged event
+ adapter.clear();
+ items.clear();
+ items.add(new AdapterItem(1, "a"));
+ items.add(new AdapterItem(2, "b"));
+ items.add(new AdapterItem(3, "c"));
+ adapter.clear();
+ adapter.setItems(items, callback);
+ Mockito.reset(observer);
+ items.clear();
+ items.add(new AdapterItem(2, "b"));
+ items.add(new AdapterItem(1, "a"));
+ items.add(new AdapterItem(3, "c"));
+ adapter.setItems(items, callback);
+ Mockito.verify(observer).onItemRangeMoved(1, 0, 1);
+ Mockito.reset(observer);
+
+ // Trigger notifyItemRangeRemoved event
+ adapter.clear();
+ items.clear();
+ items.add(new AdapterItem(1, "a"));
+ items.add(new AdapterItem(2, "b"));
+ items.add(new AdapterItem(3, "c"));
+ adapter.clear();
+ adapter.setItems(items, callback);
+ Mockito.reset(observer);
+ items.clear();
+ items.add(new AdapterItem(2, "b"));
+ items.add(new AdapterItem(3, "c"));
+ adapter.setItems(items, callback);
+ Mockito.verify(observer).onItemRangeRemoved(0, 1);
+ Mockito.reset(observer);
+
+ // Trigger notifyItemRangeInserted event
+ adapter.clear();
+ items.clear();
+ items.add(new AdapterItem(1, "a"));
+ items.add(new AdapterItem(2, "b"));
+ items.add(new AdapterItem(3, "c"));
+ adapter.clear();
+ adapter.setItems(items, callback);
+ Mockito.reset(observer);
+ items.clear();
+ items.add(new AdapterItem(1, "a"));
+ items.add(new AdapterItem(2, "b"));
+ items.add(new AdapterItem(3, "c"));
+ items.add(new AdapterItem(4, "d"));
+ adapter.setItems(items, callback);
+ Mockito.verify(observer).onItemRangeInserted(3, 1);
+ Mockito.reset(observer);
+
+ // Trigger notifyItemRangeInserted event and notifyItemRangeRemoved event simultaneously
+ adapter.clear();
+ items.clear();
+ items.add(new AdapterItem(1, "a"));
+ items.add(new AdapterItem(2, "b"));
+ items.add(new AdapterItem(3, "c"));
+ adapter.clear();
+ adapter.setItems(items, callback);
+ Mockito.reset(observer);
+ items.clear();
+ items.add(new AdapterItem(2, "a"));
+ items.add(new AdapterItem(2, "b"));
+ items.add(new AdapterItem(3, "c"));
+ adapter.setItems(items, callback);
+ Mockito.verify(observer).onItemRangeRemoved(0, 1);
+ Mockito.verify(observer).onItemRangeInserted(0, 1);
+ Mockito.reset(observer);
+
+
+ // Trigger notifyItemRangeMoved and notifyItemRangeChanged event simultaneously
+ adapter.clear();
+ items.clear();
+ items.add(new AdapterItem(1, "a"));
+ items.add(new AdapterItem(2, "b"));
+ items.add(new AdapterItem(3, "c"));
+ adapter.clear();
+ adapter.setItems(items, callback);
+ Mockito.reset(observer);
+ items.clear();
+ items.add(new AdapterItem(1, "aa"));
+ items.add(new AdapterItem(3, "c"));
+ items.add(new AdapterItem(2, "b"));
+ adapter.setItems(items, callback);
+ Mockito.verify(observer).onItemRangeChanged(0, 1, null);
+ Mockito.verify(observer).onItemRangeMoved(2, 1, 1);
+ Mockito.reset(observer);
+
+ // Trigger multiple items insertion event
+ adapter.clear();
+ items.clear();
+ items.add(new AdapterItem(0, "a"));
+ items.add(new AdapterItem(1, "b"));
+ adapter.clear();
+ adapter.setItems(items, callback);
+ Mockito.reset(observer);
+ items.clear();
+ items.add(new AdapterItem(0, "a"));
+ items.add(new AdapterItem(1, "b"));
+ items.add(new AdapterItem(2, "c"));
+ items.add(new AdapterItem(3, "d"));
+ adapter.setItems(items, callback);
+ Mockito.verify(observer).onItemRangeInserted(2, 2);
+ Mockito.reset(observer);
+ }
+
+}
diff --git a/v7/appcompat/res/values-hi/strings.xml b/v7/appcompat/res/values-hi/strings.xml
index 30d3001..0d90e55 100644
--- a/v7/appcompat/res/values-hi/strings.xml
+++ b/v7/appcompat/res/values-hi/strings.xml
@@ -17,21 +17,21 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="abc_action_mode_done" msgid="4076576682505996667">"पूर्ण"</string>
- <string name="abc_action_bar_home_description" msgid="4600421777120114993">"मुख्यपृष्ठ पर नेविगेट करें"</string>
- <string name="abc_action_bar_up_description" msgid="1594238315039666878">"ऊपर नेविगेट करें"</string>
- <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"अधिक विकल्प"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"होम पेज पर जाएं"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"ऊपर जाएं"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"ज़्यादा विकल्प"</string>
<string name="abc_toolbar_collapse_description" msgid="1603543279005712093">"संक्षिप्त करें"</string>
- <string name="abc_searchview_description_search" msgid="8264924765203268293">"खोजें"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"सर्च करें"</string>
<string name="abc_search_hint" msgid="7723749260725869598">"खोजा जा रहा है…"</string>
- <string name="abc_searchview_description_query" msgid="2550479030709304392">"खोज क्वेरी"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"सर्च क्वेरी"</string>
<string name="abc_searchview_description_clear" msgid="3691816814315814921">"क्वेरी साफ़ करें"</string>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"क्वेरी सबमिट करें"</string>
- <string name="abc_searchview_description_voice" msgid="893419373245838918">"ध्वनि खोज"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"आवाज़ सर्च"</string>
<string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"कोई एप्लिकेशन चुनें"</string>
<string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"सभी देखें"</string>
<string name="abc_shareactionprovider_share_with_application" msgid="3300176832234831527">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> के साथ साझा करें"</string>
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"इसके द्वारा साझा करें"</string>
<string name="abc_capital_on" msgid="3405795526292276155">"चालू"</string>
<string name="abc_capital_off" msgid="121134116657445385">"बंद"</string>
- <string name="search_menu_title" msgid="146198913615257606">"खोज"</string>
+ <string name="search_menu_title" msgid="146198913615257606">"सर्च"</string>
</resources>
diff --git a/v7/appcompat/res/values-iw/strings.xml b/v7/appcompat/res/values-iw/strings.xml
index 9ac2072..0a7d0bb 100644
--- a/v7/appcompat/res/values-iw/strings.xml
+++ b/v7/appcompat/res/values-iw/strings.xml
@@ -21,8 +21,8 @@
<string name="abc_action_bar_up_description" msgid="1594238315039666878">"נווט למעלה"</string>
<string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"עוד אפשרויות"</string>
<string name="abc_toolbar_collapse_description" msgid="1603543279005712093">"כווץ"</string>
- <string name="abc_searchview_description_search" msgid="8264924765203268293">"חפש"</string>
- <string name="abc_search_hint" msgid="7723749260725869598">"חפש…"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"חיפוש"</string>
+ <string name="abc_search_hint" msgid="7723749260725869598">"חיפוש…"</string>
<string name="abc_searchview_description_query" msgid="2550479030709304392">"שאילתת חיפוש"</string>
<string name="abc_searchview_description_clear" msgid="3691816814315814921">"מחק שאילתה"</string>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"שלח שאילתה"</string>
@@ -33,5 +33,5 @@
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"שתף עם"</string>
<string name="abc_capital_on" msgid="3405795526292276155">"פועל"</string>
<string name="abc_capital_off" msgid="121134116657445385">"כבוי"</string>
- <string name="search_menu_title" msgid="146198913615257606">"חפש"</string>
+ <string name="search_menu_title" msgid="146198913615257606">"חיפוש"</string>
</resources>
diff --git a/v7/appcompat/res/values-te/strings.xml b/v7/appcompat/res/values-te/strings.xml
index 93f9aec..f7d7577 100644
--- a/v7/appcompat/res/values-te/strings.xml
+++ b/v7/appcompat/res/values-te/strings.xml
@@ -21,8 +21,8 @@
<string name="abc_action_bar_up_description" msgid="1594238315039666878">"పైకి నావిగేట్ చేయండి"</string>
<string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"మరిన్ని ఎంపికలు"</string>
<string name="abc_toolbar_collapse_description" msgid="1603543279005712093">"కుదించండి"</string>
- <string name="abc_searchview_description_search" msgid="8264924765203268293">"శోధించు"</string>
- <string name="abc_search_hint" msgid="7723749260725869598">"శోధించు..."</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"వెతుకు"</string>
+ <string name="abc_search_hint" msgid="7723749260725869598">"వెతుకు..."</string>
<string name="abc_searchview_description_query" msgid="2550479030709304392">"ప్రశ్న శోధించండి"</string>
<string name="abc_searchview_description_clear" msgid="3691816814315814921">"ప్రశ్నను క్లియర్ చేయి"</string>
<string name="abc_searchview_description_submit" msgid="8928215447528550784">"ప్రశ్నని సమర్పించు"</string>
@@ -33,5 +33,5 @@
<string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"వీరితో భాగస్వామ్యం చేయి"</string>
<string name="abc_capital_on" msgid="3405795526292276155">"ఆన్ చేయి"</string>
<string name="abc_capital_off" msgid="121134116657445385">"ఆఫ్ చేయి"</string>
- <string name="search_menu_title" msgid="146198913615257606">"శోధించు"</string>
+ <string name="search_menu_title" msgid="146198913615257606">"వెతుకు"</string>
</resources>
diff --git a/v7/mediarouter/res/values-bn/strings.xml b/v7/mediarouter/res/values-bn/strings.xml
index 56fcdd9..b827751 100644
--- a/v7/mediarouter/res/values-bn/strings.xml
+++ b/v7/mediarouter/res/values-bn/strings.xml
@@ -30,7 +30,7 @@
<string name="mr_controller_play" msgid="683634565969987458">"চালান"</string>
<string name="mr_controller_pause" msgid="5451884435510905406">"বিরাম দিন"</string>
<string name="mr_controller_stop" msgid="735874641921425123">"থামান"</string>
- <string name="mr_controller_expand_group" msgid="8062427022744266907">"প্রসারিত করুন"</string>
+ <string name="mr_controller_expand_group" msgid="8062427022744266907">"বড় করুন"</string>
<string name="mr_controller_collapse_group" msgid="7924809056904240926">"সঙ্কুচিত করুন"</string>
<string name="mr_controller_album_art" msgid="6422801843540543585">"অ্যালবাম শৈলি"</string>
<string name="mr_controller_volume_slider" msgid="2361785992211841709">"ভলিউম স্লাইডার"</string>
diff --git a/v7/mediarouter/res/values-hi/strings.xml b/v7/mediarouter/res/values-hi/strings.xml
index 878a4b2..adf3e88 100644
--- a/v7/mediarouter/res/values-hi/strings.xml
+++ b/v7/mediarouter/res/values-hi/strings.xml
@@ -35,6 +35,6 @@
<string name="mr_controller_album_art" msgid="6422801843540543585">"एल्बम आर्ट"</string>
<string name="mr_controller_volume_slider" msgid="2361785992211841709">"वॉल्यूम स्लाइडर"</string>
<string name="mr_controller_no_media_selected" msgid="6547130360349182381">"कोई मीडिया चयनित नहीं है"</string>
- <string name="mr_controller_no_info_available" msgid="5585418471741142924">"कोई जानकारी उपलब्ध नहीं"</string>
+ <string name="mr_controller_no_info_available" msgid="5585418471741142924">"कोई जानकारी मौजूद नहीं है"</string>
<string name="mr_controller_casting_screen" msgid="4868457957151124867">"स्क्रीन कास्ट हो रही है"</string>
</resources>
diff --git a/v7/recyclerview/src/android/support/v7/widget/GridLayoutManager.java b/v7/recyclerview/src/android/support/v7/widget/GridLayoutManager.java
index dfc7c12..67605b9 100644
--- a/v7/recyclerview/src/android/support/v7/widget/GridLayoutManager.java
+++ b/v7/recyclerview/src/android/support/v7/widget/GridLayoutManager.java
@@ -91,8 +91,8 @@
* #VERTICAL}.
* @param reverseLayout When set to true, layouts from end to start.
*/
- public GridLayoutManager(Context context, int spanCount, int orientation,
- boolean reverseLayout) {
+ public GridLayoutManager(Context context, int spanCount,
+ @RecyclerView.Orientation int orientation, boolean reverseLayout) {
super(context, orientation, reverseLayout);
setSpanCount(spanCount);
}
diff --git a/v7/recyclerview/src/android/support/v7/widget/LinearLayoutManager.java b/v7/recyclerview/src/android/support/v7/widget/LinearLayoutManager.java
index a12e9a8..27df490 100644
--- a/v7/recyclerview/src/android/support/v7/widget/LinearLayoutManager.java
+++ b/v7/recyclerview/src/android/support/v7/widget/LinearLayoutManager.java
@@ -62,10 +62,10 @@
*/
private static final float MAX_SCROLL_FACTOR = 1 / 3f;
-
/**
* Current orientation. Either {@link #HORIZONTAL} or {@link #VERTICAL}
*/
+ @RecyclerView.Orientation
int mOrientation;
/**
@@ -163,7 +163,8 @@
* #VERTICAL}.
* @param reverseLayout When set to true, layouts from end to start.
*/
- public LinearLayoutManager(Context context, int orientation, boolean reverseLayout) {
+ public LinearLayoutManager(Context context, @RecyclerView.Orientation int orientation,
+ boolean reverseLayout) {
setOrientation(orientation);
setReverseLayout(reverseLayout);
setAutoMeasureEnabled(true);
@@ -319,6 +320,7 @@
* @return Current orientation, either {@link #HORIZONTAL} or {@link #VERTICAL}
* @see #setOrientation(int)
*/
+ @RecyclerView.Orientation
public int getOrientation() {
return mOrientation;
}
@@ -329,7 +331,7 @@
*
* @param orientation {@link #HORIZONTAL} or {@link #VERTICAL}
*/
- public void setOrientation(int orientation) {
+ public void setOrientation(@RecyclerView.Orientation int orientation) {
if (orientation != HORIZONTAL && orientation != VERTICAL) {
throw new IllegalArgumentException("invalid orientation:" + orientation);
}
diff --git a/v7/recyclerview/src/android/support/v7/widget/OrientationHelper.java b/v7/recyclerview/src/android/support/v7/widget/OrientationHelper.java
index 8987b9c..5e90f2e 100644
--- a/v7/recyclerview/src/android/support/v7/widget/OrientationHelper.java
+++ b/v7/recyclerview/src/android/support/v7/widget/OrientationHelper.java
@@ -18,7 +18,6 @@
import android.graphics.Rect;
import android.view.View;
-import android.widget.LinearLayout;
/**
* Helper class for LayoutManagers to abstract measurements depending on the View's orientation.
@@ -36,9 +35,9 @@
protected final RecyclerView.LayoutManager mLayoutManager;
- public static final int HORIZONTAL = LinearLayout.HORIZONTAL;
+ public static final int HORIZONTAL = RecyclerView.HORIZONTAL;
- public static final int VERTICAL = LinearLayout.VERTICAL;
+ public static final int VERTICAL = RecyclerView.VERTICAL;
private int mLastTotalSpace = INVALID_SIZE;
@@ -230,7 +229,7 @@
* @return A new OrientationHelper
*/
public static OrientationHelper createOrientationHelper(
- RecyclerView.LayoutManager layoutManager, int orientation) {
+ RecyclerView.LayoutManager layoutManager, @RecyclerView.Orientation int orientation) {
switch (orientation) {
case HORIZONTAL:
return createHorizontalHelper(layoutManager);
diff --git a/v7/recyclerview/src/android/support/v7/widget/RecyclerView.java b/v7/recyclerview/src/android/support/v7/widget/RecyclerView.java
index 9978adc..dea8546 100644
--- a/v7/recyclerview/src/android/support/v7/widget/RecyclerView.java
+++ b/v7/recyclerview/src/android/support/v7/widget/RecyclerView.java
@@ -73,6 +73,7 @@
import android.view.accessibility.AccessibilityManager;
import android.view.animation.Interpolator;
import android.widget.EdgeEffect;
+import android.widget.LinearLayout;
import android.widget.OverScroller;
import java.lang.annotation.Retention;
@@ -205,8 +206,15 @@
private static final boolean IGNORE_DETACHED_FOCUSED_CHILD = Build.VERSION.SDK_INT <= 15;
static final boolean DISPATCH_TEMP_DETACH = false;
- public static final int HORIZONTAL = 0;
- public static final int VERTICAL = 1;
+
+ /** @hide */
+ @RestrictTo(LIBRARY_GROUP)
+ @IntDef({HORIZONTAL, VERTICAL})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface Orientation {}
+
+ public static final int HORIZONTAL = LinearLayout.HORIZONTAL;
+ public static final int VERTICAL = LinearLayout.VERTICAL;
public static final int NO_POSITION = -1;
public static final long NO_ID = -1;
diff --git a/wear/tests/src/android/support/wear/widget/RoundedDrawableTest.java b/wear/tests/src/android/support/wear/widget/RoundedDrawableTest.java
index 82027f7..21aee7b 100644
--- a/wear/tests/src/android/support/wear/widget/RoundedDrawableTest.java
+++ b/wear/tests/src/android/support/wear/widget/RoundedDrawableTest.java
@@ -32,10 +32,12 @@
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
+import android.os.Build;
import android.support.test.filters.SmallTest;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
import android.support.wear.test.R;
+import android.support.test.filters.SdkSuppress;
import org.junit.Before;
import org.junit.Rule;
@@ -129,9 +131,11 @@
}
@Test
+ @SdkSuppress(minSdkVersion = Build.VERSION_CODES.N)
public void inflate() {
- RoundedDrawable roundedDrawable = (RoundedDrawable) mActivityRule.getActivity().getDrawable(
- R.drawable.rounded_drawable);
+ RoundedDrawable roundedDrawable =
+ (RoundedDrawable) mActivityRule.getActivity().getDrawable(
+ R.drawable.rounded_drawable);
assertEquals(
mActivityRule.getActivity().getColor(R.color.rounded_drawable_background_color),
roundedDrawable.getBackgroundColor());