diff options
author | George Mount <mount@google.com> | 2015-09-17 07:42:41 -0700 |
---|---|---|
committer | George Mount <mount@google.com> | 2016-01-14 14:29:32 -0800 |
commit | 3b920788e90bb0abe615a5d5c899915f0014444b (patch) | |
tree | e31dc6bc137aaa23792ddddbad9988f229ed0d84 /extensions/library | |
parent | d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01 (diff) | |
download | data-binding-3b920788e90bb0abe615a5d5c899915f0014444b.tar.gz |
Two-way binding extensions
Bug 1474349
Bug 22460238
Two-way data binding won't work without a few changes to the
extension library. This adds those changes and tests to ensure
that two-way data binding works.
Change-Id: I5e204609925bb2dc5404176f9b4e59386f200c7f
Diffstat (limited to 'extensions/library')
-rw-r--r-- | extensions/library/src/main/java/android/databinding/ViewDataBinding.java | 273 |
1 files changed, 260 insertions, 13 deletions
diff --git a/extensions/library/src/main/java/android/databinding/ViewDataBinding.java b/extensions/library/src/main/java/android/databinding/ViewDataBinding.java index 2dacd1e9..5e760237 100644 --- a/extensions/library/src/main/java/android/databinding/ViewDataBinding.java +++ b/extensions/library/src/main/java/android/databinding/ViewDataBinding.java @@ -16,8 +16,6 @@ package android.databinding; -import com.android.databinding.library.R; - import android.annotation.TargetApi; import android.content.res.ColorStateList; import android.databinding.CallbackRegistry.NotifierCallback; @@ -27,15 +25,22 @@ import android.os.Build.VERSION_CODES; import android.os.Handler; import android.os.Looper; import android.text.TextUtils; +import android.util.LongSparseArray; +import android.util.SparseArray; +import android.util.SparseBooleanArray; import android.util.SparseIntArray; +import android.util.SparseLongArray; import android.view.Choreographer; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnAttachStateChangeListener; import android.view.ViewGroup; +import com.android.databinding.library.R; + import java.lang.ref.WeakReference; import java.util.List; +import java.util.Map; /** * Base class for generated data binding classes. If possible, the generated binding should @@ -43,7 +48,7 @@ import java.util.List; * binding is unknown, {@link DataBindingUtil#bind(View)} or * {@link DataBindingUtil#inflate(LayoutInflater, int, ViewGroup, boolean)} should be used. */ -public abstract class ViewDataBinding { +public abstract class ViewDataBinding extends BaseObservable { /** * Instead of directly accessing Build.VERSION.SDK_INT, generated code uses this value so that @@ -565,6 +570,15 @@ public abstract class ViewDataBinding { } /** @hide */ + protected int getColorFromResource(int resourceId) { + if (VERSION.SDK_INT >= VERSION_CODES.M) { + return getRoot().getContext().getColor(resourceId); + } else { + return getRoot().getResources().getColor(resourceId); + } + } + + /** @hide */ protected ColorStateList getColorStateListFromResource(int resourceId) { if (VERSION.SDK_INT >= VERSION_CODES.M) { return getRoot().getContext().getColorStateList(resourceId); @@ -584,84 +598,295 @@ public abstract class ViewDataBinding { /** @hide */ protected static <T> T getFromArray(T[] arr, int index) { - if (index < 0 || index >= arr.length) { + if (arr == null || index < 0 || index >= arr.length) { return null; } return arr[index]; } /** @hide */ + protected static <T> void setTo(T[] arr, int index, T value) { + if (arr == null || index < 0 || index >= arr.length) { + return; + } + arr[index] = value; + } + + /** @hide */ protected static boolean getFromArray(boolean[] arr, int index) { - if (index < 0 || index >= arr.length) { + if (arr == null || index < 0 || index >= arr.length) { return false; } return arr[index]; } /** @hide */ + protected static void setTo(boolean[] arr, int index, boolean value) { + if (arr == null || index < 0 || index >= arr.length) { + return; + } + arr[index] = value; + } + + /** @hide */ protected static byte getFromArray(byte[] arr, int index) { - if (index < 0 || index >= arr.length) { + if (arr == null || index < 0 || index >= arr.length) { return 0; } return arr[index]; } /** @hide */ + protected static void setTo(byte[] arr, int index, byte value) { + if (arr == null || index < 0 || index >= arr.length) { + return; + } + arr[index] = value; + } + + /** @hide */ protected static short getFromArray(short[] arr, int index) { - if (index < 0 || index >= arr.length) { + if (arr == null || index < 0 || index >= arr.length) { return 0; } return arr[index]; } /** @hide */ + protected static void setTo(short[] arr, int index, short value) { + if (arr == null || index < 0 || index >= arr.length) { + return; + } + arr[index] = value; + } + + /** @hide */ protected static char getFromArray(char[] arr, int index) { - if (index < 0 || index >= arr.length) { + if (arr == null || index < 0 || index >= arr.length) { return 0; } return arr[index]; } /** @hide */ + protected static void setTo(char[] arr, int index, char value) { + if (arr == null || index < 0 || index >= arr.length) { + return; + } + arr[index] = value; + } + + /** @hide */ protected static int getFromArray(int[] arr, int index) { - if (index < 0 || index >= arr.length) { + if (arr == null || index < 0 || index >= arr.length) { return 0; } return arr[index]; } /** @hide */ + protected static void setTo(int[] arr, int index, int value) { + if (arr == null || index < 0 || index >= arr.length) { + return; + } + arr[index] = value; + } + + /** @hide */ protected static long getFromArray(long[] arr, int index) { - if (index < 0 || index >= arr.length) { + if (arr == null || index < 0 || index >= arr.length) { return 0; } return arr[index]; } /** @hide */ + protected static void setTo(long[] arr, int index, long value) { + if (arr == null || index < 0 || index >= arr.length) { + return; + } + arr[index] = value; + } + + /** @hide */ protected static float getFromArray(float[] arr, int index) { - if (index < 0 || index >= arr.length) { + if (arr == null || index < 0 || index >= arr.length) { return 0; } return arr[index]; } /** @hide */ + protected static void setTo(float[] arr, int index, float value) { + if (arr == null || index < 0 || index >= arr.length) { + return; + } + arr[index] = value; + } + + /** @hide */ protected static double getFromArray(double[] arr, int index) { - if (index < 0 || index >= arr.length) { + if (arr == null || index < 0 || index >= arr.length) { return 0; } return arr[index]; } /** @hide */ + protected static void setTo(double[] arr, int index, double value) { + if (arr == null || index < 0 || index >= arr.length) { + return; + } + arr[index] = value; + } + + /** @hide */ protected static <T> T getFromList(List<T> list, int index) { - if (index < 0 || index >= list.size()) { + if (list == null || index < 0 || index >= list.size()) { + return null; + } + return list.get(index); + } + + /** @hide */ + protected static <T> void setTo(List<T> list, int index, T value) { + if (list == null || index < 0 || index >= list.size()) { + return; + } + list.set(index, value); + } + + /** @hide */ + protected static <T> T getFromList(SparseArray<T> list, int index) { + if (list == null || index < 0) { + return null; + } + return list.get(index); + } + + /** @hide */ + protected static <T> void setTo(SparseArray<T> list, int index, T value) { + if (list == null || index < 0 || index >= list.size()) { + return; + } + list.put(index, value); + } + + /** @hide */ + @TargetApi(VERSION_CODES.JELLY_BEAN) + protected static <T> T getFromList(LongSparseArray<T> list, int index) { + if (list == null || index < 0) { return null; } return list.get(index); } + /** @hide */ + @TargetApi(VERSION_CODES.JELLY_BEAN) + protected static <T> void setTo(LongSparseArray<T> list, int index, T value) { + if (list == null || index < 0 || index >= list.size()) { + return; + } + list.put(index, value); + } + + /** @hide */ + protected static <T> T getFromList(android.support.v4.util.LongSparseArray<T> list, int index) { + if (list == null || index < 0) { + return null; + } + return list.get(index); + } + + /** @hide */ + protected static <T> void setTo(android.support.v4.util.LongSparseArray<T> list, int index, + T value) { + if (list == null || index < 0 || index >= list.size()) { + return; + } + list.put(index, value); + } + + /** @hide */ + protected static boolean getFromList(SparseBooleanArray list, int index) { + if (list == null || index < 0) { + return false; + } + return list.get(index); + } + + /** @hide */ + protected static void setTo(SparseBooleanArray list, int index, boolean value) { + if (list == null || index < 0 || index >= list.size()) { + return; + } + list.put(index, value); + } + + /** @hide */ + protected static int getFromList(SparseIntArray list, int index) { + if (list == null || index < 0) { + return 0; + } + return list.get(index); + } + + /** @hide */ + protected static void setTo(SparseIntArray list, int index, int value) { + if (list == null || index < 0 || index >= list.size()) { + return; + } + list.put(index, value); + } + + /** @hide */ + @TargetApi(VERSION_CODES.JELLY_BEAN_MR2) + protected static long getFromList(SparseLongArray list, int index) { + if (list == null || index < 0) { + return 0; + } + return list.get(index); + } + + /** @hide */ + @TargetApi(VERSION_CODES.JELLY_BEAN_MR2) + protected static void setTo(SparseLongArray list, int index, long value) { + if (list == null || index < 0 || index >= list.size()) { + return; + } + list.put(index, value); + } + + /** @hide */ + protected static <K, T> T getFrom(Map<K, T> map, K key) { + if (map == null) { + return null; + } + return map.get(key); + } + + /** @hide */ + protected static <K, T> void setTo(Map<K, T> map, K key, T value) { + if (map == null) { + return; + } + map.put(key, value); + } + + /** @hide */ + protected static void setBindingInverseListener(ViewDataBinding binder, + InverseBindingListener oldListener, PropertyChangedInverseListener listener) { + if (oldListener != listener) { + if (oldListener != null) { + binder.removeOnPropertyChangedCallback( + (PropertyChangedInverseListener) oldListener); + } + if (listener != null) { + binder.addOnPropertyChangedCallback(listener); + } + } + } + /** * Walks the view hierarchy under roots and pulls out tagged Views, includes, and views with * IDs into an Object[] that is returned. This is used to walk the view hierarchy once to find @@ -1046,4 +1271,26 @@ public abstract class ViewDataBinding { this.layoutIds[index] = layoutIds; } } + + /** + * This class is used by generated subclasses of {@link ViewDataBinding} to listen for + * changes on variables of Bindings. This is important for two-way data binding on variables + * in included Bindings. + * @hide + */ + protected static abstract class PropertyChangedInverseListener + extends Observable.OnPropertyChangedCallback implements InverseBindingListener { + final int mPropertyId; + + public PropertyChangedInverseListener(int propertyId) { + mPropertyId = propertyId; + } + + @Override + public void onPropertyChanged(Observable sender, int propertyId) { + if (propertyId == mPropertyId || propertyId == 0) { + onChange(); + } + } + } } |