summaryrefslogtreecommitdiff
path: root/extensions
diff options
context:
space:
mode:
authorGeorge Mount <mount@google.com>2015-06-17 16:09:52 -0700
committerGeorge Mount <mount@google.com>2015-06-23 15:18:43 -0700
commit716ba89e7f459f49ea85070d4710c1d79d715298 (patch)
tree256cfa9eb7d085f88d27001d35bcea9728a35596 /extensions
parentaf84cb304c158381a8bf0f0ac1c37c5a2ad04bfb (diff)
downloaddata-binding-716ba89e7f459f49ea85070d4710c1d79d715298.tar.gz
Support calling listener methods without interfaces.
Bug 21594573 It is convenient to be able to assign event listeners by just referencing a method, similar to the way onClick="handler" works. This adds a whole lot of listeners for the framework. Additional listeners must be added for support library components. This isn't perfect in resolving listeners. Perfect resolution requires that each expression is evaluated in its own context within the binding statement. If, for example, the same method name is used for a listener and an accessor, we will assume that the listener is used always and there will be a compilation failure. Change-Id: If4705122b67a451430451b6e7d890eb813af1c5c
Diffstat (limited to 'extensions')
-rw-r--r--extensions/baseAdapters/src/main/java/android/databinding/adapters/AbsListViewBindingAdapter.java50
-rw-r--r--extensions/baseAdapters/src/main/java/android/databinding/adapters/ActionMenuViewBindingAdapter.java26
-rw-r--r--extensions/baseAdapters/src/main/java/android/databinding/adapters/AdapterViewBindingAdapter.java83
-rw-r--r--extensions/baseAdapters/src/main/java/android/databinding/adapters/AutoCompleteTextViewBindingAdapter.java78
-rw-r--r--extensions/baseAdapters/src/main/java/android/databinding/adapters/CalendarViewBindingAdapter.java26
-rw-r--r--extensions/baseAdapters/src/main/java/android/databinding/adapters/ChronometerBindingAdapter.java26
-rw-r--r--extensions/baseAdapters/src/main/java/android/databinding/adapters/CompoundButtonBindingAdapter.java7
-rw-r--r--extensions/baseAdapters/src/main/java/android/databinding/adapters/ExpandableListViewBindingAdapter.java29
-rw-r--r--extensions/baseAdapters/src/main/java/android/databinding/adapters/ListenerUtil.java86
-rw-r--r--extensions/baseAdapters/src/main/java/android/databinding/adapters/NumberPickerBindingAdapter.java28
-rw-r--r--extensions/baseAdapters/src/main/java/android/databinding/adapters/RadioGroupBindingAdapter.java5
-rw-r--r--extensions/baseAdapters/src/main/java/android/databinding/adapters/RatingBarBindingAdapter.java26
-rw-r--r--extensions/baseAdapters/src/main/java/android/databinding/adapters/SearchViewBindingAdapter.java136
-rw-r--r--extensions/baseAdapters/src/main/java/android/databinding/adapters/SeekBarBindingAdapter.java98
-rw-r--r--extensions/baseAdapters/src/main/java/android/databinding/adapters/SpinnerBindingAdapter.java1
-rw-r--r--extensions/baseAdapters/src/main/java/android/databinding/adapters/TabHostBindingAdapter.java26
-rw-r--r--extensions/baseAdapters/src/main/java/android/databinding/adapters/TextViewBindingAdapter.java107
-rw-r--r--extensions/baseAdapters/src/main/java/android/databinding/adapters/TimePickerBindingAdapter.java26
-rw-r--r--extensions/baseAdapters/src/main/java/android/databinding/adapters/ToolbarBindingAdapter.java27
-rw-r--r--extensions/baseAdapters/src/main/java/android/databinding/adapters/VideoViewBindingAdapter.java30
-rw-r--r--extensions/baseAdapters/src/main/java/android/databinding/adapters/ViewBindingAdapter.java134
-rw-r--r--extensions/baseAdapters/src/main/java/android/databinding/adapters/ViewGroupBindingAdapter.java123
-rw-r--r--extensions/baseAdapters/src/main/java/android/databinding/adapters/ViewStubBindingAdapter.java9
-rw-r--r--extensions/baseAdapters/src/main/java/android/databinding/adapters/ZoomControlsBindingAdapter.java27
-rw-r--r--extensions/baseAdapters/src/main/res/values/ids.xml7
25 files changed, 1187 insertions, 34 deletions
diff --git a/extensions/baseAdapters/src/main/java/android/databinding/adapters/AbsListViewBindingAdapter.java b/extensions/baseAdapters/src/main/java/android/databinding/adapters/AbsListViewBindingAdapter.java
index 68eefe7f..50851ac0 100644
--- a/extensions/baseAdapters/src/main/java/android/databinding/adapters/AbsListViewBindingAdapter.java
+++ b/extensions/baseAdapters/src/main/java/android/databinding/adapters/AbsListViewBindingAdapter.java
@@ -15,14 +15,58 @@
*/
package android.databinding.adapters;
+import android.databinding.BindingAdapter;
import android.databinding.BindingMethod;
import android.databinding.BindingMethods;
+import android.widget.AbsListView;
+import android.widget.AbsListView.OnScrollListener;
@BindingMethods({
- @BindingMethod(type = android.widget.AbsListView.class, attribute = "android:listSelector", method = "setSelector"),
- @BindingMethod(type = android.widget.AbsListView.class, attribute = "android:scrollingCache", method = "setScrollingCacheEnabled"),
- @BindingMethod(type = android.widget.AbsListView.class, attribute = "android:smoothScrollbar", method = "setSmoothScrollbarEnabled"),
+ @BindingMethod(type = AbsListView.class, attribute = "android:listSelector", method = "setSelector"),
+ @BindingMethod(type = AbsListView.class, attribute = "android:scrollingCache", method = "setScrollingCacheEnabled"),
+ @BindingMethod(type = AbsListView.class, attribute = "android:smoothScrollbar", method = "setSmoothScrollbarEnabled"),
+ @BindingMethod(type = AbsListView.class, attribute = "android:onMovedToScrapHeap", method = "setRecyclerListener"),
})
public class AbsListViewBindingAdapter {
+ @BindingAdapter("android:onScroll")
+ public static void setOnScroll(AbsListView view, OnScroll listener) {
+ setOnScroll(view, listener, null);
+ }
+
+ @BindingAdapter("android:onScrollStateChanged")
+ public static void setOnScroll(AbsListView view, OnScrollStateChanged listener) {
+ setOnScroll(view, null, listener);
+ }
+
+ @BindingAdapter({"android:onScroll", "android:onScrollStateChanged"})
+ public static void setOnScroll(AbsListView view, final OnScroll scrollListener,
+ final OnScrollStateChanged scrollStateListener) {
+ view.setOnScrollListener(new OnScrollListener() {
+ @Override
+ public void onScrollStateChanged(AbsListView view, int scrollState) {
+ if (scrollStateListener != null) {
+ scrollStateListener.onScrollStateChanged(view, scrollState);
+ }
+ }
+
+ @Override
+ public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
+ int totalItemCount) {
+ if (scrollListener != null) {
+ scrollListener
+ .onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount);
+ }
+ }
+ });
+ }
+
+ public interface OnScroll {
+ void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
+ int totalItemCount);
+ }
+
+ public interface OnScrollStateChanged {
+ void onScrollStateChanged(AbsListView view, int scrollState);
+ }
}
diff --git a/extensions/baseAdapters/src/main/java/android/databinding/adapters/ActionMenuViewBindingAdapter.java b/extensions/baseAdapters/src/main/java/android/databinding/adapters/ActionMenuViewBindingAdapter.java
new file mode 100644
index 00000000..f855ce65
--- /dev/null
+++ b/extensions/baseAdapters/src/main/java/android/databinding/adapters/ActionMenuViewBindingAdapter.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.databinding.adapters;
+
+import android.databinding.BindingMethod;
+import android.databinding.BindingMethods;
+import android.widget.ActionMenuView;
+
+@BindingMethods({
+ @BindingMethod(type = ActionMenuView.class, attribute = "android:onMenuItemClick", method = "setOnMenuItemClickListener"),
+})
+public class ActionMenuViewBindingAdapter {
+}
diff --git a/extensions/baseAdapters/src/main/java/android/databinding/adapters/AdapterViewBindingAdapter.java b/extensions/baseAdapters/src/main/java/android/databinding/adapters/AdapterViewBindingAdapter.java
new file mode 100644
index 00000000..ad85d79b
--- /dev/null
+++ b/extensions/baseAdapters/src/main/java/android/databinding/adapters/AdapterViewBindingAdapter.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.databinding.adapters;
+
+import android.databinding.BindingAdapter;
+import android.databinding.BindingMethod;
+import android.databinding.BindingMethods;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemSelectedListener;
+
+@BindingMethods({
+ @BindingMethod(type = AdapterView.class, attribute = "android:onItemClick", method = "setOnItemClickListener"),
+ @BindingMethod(type = AdapterView.class, attribute = "android:onItemLongClick", method = "setOnItemLongClickListener"),
+})
+public class AdapterViewBindingAdapter {
+
+ @BindingAdapter("android:onItemSelected")
+ public static void setListener(AdapterView view, OnItemSelected listener) {
+ setListener(view, listener, null);
+ }
+
+ @BindingAdapter("android:onNothingSelected")
+ public static void setListener(AdapterView view, OnNothingSelected listener) {
+ setListener(view, null, listener);
+ }
+
+ @BindingAdapter({"android:onItemSelected", "android:onNothingSelected"})
+ public static void setListener(AdapterView view, final OnItemSelected selected,
+ final OnNothingSelected nothingSelected) {
+ if (selected == null && nothingSelected == null) {
+ view.setOnItemSelectedListener(null);
+ } else {
+ view.setOnItemSelectedListener(
+ new OnItemSelectedComponentListener(selected, nothingSelected));
+ }
+ }
+
+ public static class OnItemSelectedComponentListener implements OnItemSelectedListener {
+ private final OnItemSelected mSelected;
+ private final OnNothingSelected mNothingSelected;
+
+ public OnItemSelectedComponentListener(OnItemSelected selected,
+ OnNothingSelected nothingSelected) {
+ this.mSelected = selected;
+ this.mNothingSelected = nothingSelected;
+ }
+ @Override
+ public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
+ if (mSelected != null) {
+ mSelected.onItemSelected(parent, view, position, id);
+ }
+ }
+
+ @Override
+ public void onNothingSelected(AdapterView<?> parent) {
+ if (mNothingSelected != null) {
+ mNothingSelected.onNothingSelected(parent);
+ }
+ }
+ }
+
+ public interface OnItemSelected {
+ void onItemSelected(AdapterView<?> parent, View view, int position, long id);
+ }
+
+ public interface OnNothingSelected {
+ void onNothingSelected(AdapterView<?> parent);
+ }
+}
diff --git a/extensions/baseAdapters/src/main/java/android/databinding/adapters/AutoCompleteTextViewBindingAdapter.java b/extensions/baseAdapters/src/main/java/android/databinding/adapters/AutoCompleteTextViewBindingAdapter.java
index 67723516..72f465ec 100644
--- a/extensions/baseAdapters/src/main/java/android/databinding/adapters/AutoCompleteTextViewBindingAdapter.java
+++ b/extensions/baseAdapters/src/main/java/android/databinding/adapters/AutoCompleteTextViewBindingAdapter.java
@@ -15,13 +15,87 @@
*/
package android.databinding.adapters;
+import android.databinding.BindingAdapter;
import android.databinding.BindingMethod;
import android.databinding.BindingMethods;
+import android.databinding.adapters.AdapterViewBindingAdapter.OnItemSelected;
+import android.databinding.adapters.AdapterViewBindingAdapter.OnItemSelectedComponentListener;
+import android.databinding.adapters.AdapterViewBindingAdapter.OnNothingSelected;
+import android.widget.AutoCompleteTextView;
+import android.widget.AutoCompleteTextView.Validator;
@BindingMethods({
- @BindingMethod(type = android.widget.AutoCompleteTextView.class, attribute = "android:completionThreshold", method = "setThreshold"),
- @BindingMethod(type = android.widget.AutoCompleteTextView.class, attribute = "android:popupBackground", method = "setDropDownBackgroundDrawable"),
+ @BindingMethod(type = AutoCompleteTextView.class, attribute = "android:completionThreshold", method = "setThreshold"),
+ @BindingMethod(type = AutoCompleteTextView.class, attribute = "android:popupBackground", method = "setDropDownBackgroundDrawable"),
+ @BindingMethod(type = AutoCompleteTextView.class, attribute = "android:onDismiss", method = "setOnDismissListener"),
+ @BindingMethod(type = AutoCompleteTextView.class, attribute = "android:onItemClick", method = "setOnItemClickListener"),
})
public class AutoCompleteTextViewBindingAdapter {
+ @BindingAdapter("android:fixText")
+ public static void setListener(AutoCompleteTextView view, FixText listener) {
+ setListener(view, listener, null);
+ }
+
+ @BindingAdapter("android:isValid")
+ public static void setListener(AutoCompleteTextView view, IsValid listener) {
+ setListener(view, null, listener);
+ }
+
+ @BindingAdapter({"android:fixText", "android:isValid"})
+ public static void setListener(AutoCompleteTextView view, final FixText fixText,
+ final IsValid isValid) {
+ if (fixText == null && isValid == null) {
+ view.setValidator(null);
+ } else {
+ view.setValidator(new Validator() {
+ @Override
+ public boolean isValid(CharSequence text) {
+ if (isValid != null) {
+ return isValid.isValid(text);
+ } else {
+ return true;
+ }
+ }
+
+ @Override
+ public CharSequence fixText(CharSequence invalidText) {
+ if (fixText != null) {
+ return fixText.fixText(invalidText);
+ } else {
+ return invalidText;
+ }
+ }
+ });
+ }
+ }
+
+ @BindingAdapter("android:onItemSelected")
+ public static void setListener(AutoCompleteTextView view, OnItemSelected listener) {
+ setListener(view, listener, null);
+ }
+
+ @BindingAdapter("android:onNothingSelected")
+ public static void setListener(AutoCompleteTextView view, OnNothingSelected listener) {
+ setListener(view, null, listener);
+ }
+
+ @BindingAdapter({"android:onItemSelected", "android:onNothingSelected"})
+ public static void setListener(AutoCompleteTextView view, final OnItemSelected selected,
+ final OnNothingSelected nothingSelected) {
+ if (selected == null && nothingSelected == null) {
+ view.setOnItemSelectedListener(null);
+ } else {
+ view.setOnItemSelectedListener(
+ new OnItemSelectedComponentListener(selected, nothingSelected));
+ }
+ }
+
+ public interface IsValid {
+ boolean isValid(CharSequence text);
+ }
+
+ public interface FixText {
+ CharSequence fixText(CharSequence invalidText);
+ }
}
diff --git a/extensions/baseAdapters/src/main/java/android/databinding/adapters/CalendarViewBindingAdapter.java b/extensions/baseAdapters/src/main/java/android/databinding/adapters/CalendarViewBindingAdapter.java
new file mode 100644
index 00000000..fc7fb2f5
--- /dev/null
+++ b/extensions/baseAdapters/src/main/java/android/databinding/adapters/CalendarViewBindingAdapter.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.databinding.adapters;
+
+import android.databinding.BindingMethod;
+import android.databinding.BindingMethods;
+import android.widget.CalendarView;
+
+@BindingMethods({
+ @BindingMethod(type = CalendarView.class, attribute = "android:onSelectedDayChange", method = "setOnDateChangeListener"),
+})
+public class CalendarViewBindingAdapter {
+}
diff --git a/extensions/baseAdapters/src/main/java/android/databinding/adapters/ChronometerBindingAdapter.java b/extensions/baseAdapters/src/main/java/android/databinding/adapters/ChronometerBindingAdapter.java
new file mode 100644
index 00000000..cd2324e6
--- /dev/null
+++ b/extensions/baseAdapters/src/main/java/android/databinding/adapters/ChronometerBindingAdapter.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.databinding.adapters;
+
+import android.databinding.BindingMethod;
+import android.databinding.BindingMethods;
+import android.widget.Chronometer;
+
+@BindingMethods({
+ @BindingMethod(type = Chronometer.class, attribute = "android:onChronometerTick", method = "setOnChronometerTickListener"),
+})
+public class ChronometerBindingAdapter {
+}
diff --git a/extensions/baseAdapters/src/main/java/android/databinding/adapters/CompoundButtonBindingAdapter.java b/extensions/baseAdapters/src/main/java/android/databinding/adapters/CompoundButtonBindingAdapter.java
index 588a8461..3859019d 100644
--- a/extensions/baseAdapters/src/main/java/android/databinding/adapters/CompoundButtonBindingAdapter.java
+++ b/extensions/baseAdapters/src/main/java/android/databinding/adapters/CompoundButtonBindingAdapter.java
@@ -15,12 +15,15 @@
*/
package android.databinding.adapters;
+import android.databinding.BindingAdapter;
import android.databinding.BindingMethod;
import android.databinding.BindingMethods;
+import android.widget.CompoundButton;
+import android.widget.CompoundButton.OnCheckedChangeListener;
@BindingMethods({
- @BindingMethod(type = android.widget.CompoundButton.class, attribute = "android:buttonTint", method = "setButtonTintList"),
+ @BindingMethod(type = CompoundButton.class, attribute = "android:buttonTint", method = "setButtonTintList"),
+ @BindingMethod(type = CompoundButton.class, attribute = "android:onCheckedChanged", method = "setOnCheckedChangeListener"),
})
public class CompoundButtonBindingAdapter {
-
}
diff --git a/extensions/baseAdapters/src/main/java/android/databinding/adapters/ExpandableListViewBindingAdapter.java b/extensions/baseAdapters/src/main/java/android/databinding/adapters/ExpandableListViewBindingAdapter.java
new file mode 100644
index 00000000..1f909b6f
--- /dev/null
+++ b/extensions/baseAdapters/src/main/java/android/databinding/adapters/ExpandableListViewBindingAdapter.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.databinding.adapters;
+
+import android.databinding.BindingMethod;
+import android.databinding.BindingMethods;
+import android.widget.ExpandableListView;
+
+@BindingMethods({
+ @BindingMethod(type = ExpandableListView.class, attribute = "android:onChildClick", method = "setOnChildClickListener"),
+ @BindingMethod(type = ExpandableListView.class, attribute = "android:onGroupClick", method = "setOnGroupClickListener"),
+ @BindingMethod(type = ExpandableListView.class, attribute = "android:onGroupCollapse", method = "setOnGroupCollapseListener"),
+ @BindingMethod(type = ExpandableListView.class, attribute = "android:onGroupExpand", method = "setOnGroupExpandListener"),
+})
+public class ExpandableListViewBindingAdapter {
+}
diff --git a/extensions/baseAdapters/src/main/java/android/databinding/adapters/ListenerUtil.java b/extensions/baseAdapters/src/main/java/android/databinding/adapters/ListenerUtil.java
new file mode 100644
index 00000000..d8c3125b
--- /dev/null
+++ b/extensions/baseAdapters/src/main/java/android/databinding/adapters/ListenerUtil.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.databinding.adapters;
+
+import android.os.Build.VERSION;
+import android.os.Build.VERSION_CODES;
+import android.util.SparseArray;
+import android.view.View;
+
+import java.lang.ref.WeakReference;
+import java.util.WeakHashMap;
+
+public class ListenerUtil {
+ private static SparseArray<WeakHashMap<View, WeakReference<?>>> sListeners =
+ new SparseArray<>();
+
+ /**
+ * This method tracks listeners for a View. Only one listener per listenerResourceId
+ * can be tracked at a time. This is useful for add*Listener and remove*Listener methods
+ * when used with BindingAdapters. This guarantees not to leak the listener or the View,
+ * so will not keep a strong reference to either.
+ *
+ * Example usage:
+ * <pre>
+ * {@code
+ * @BindingAdapter("onFoo")
+ * public static void addFooListener(MyView view, OnFooListener listener) {
+ * OnFooListener oldValue = ListenerUtil.trackListener(view, listener, R.id.fooListener);
+ * if (oldValue != null) {
+ * view.removeOnFooListener(oldValue);
+ * }
+ * if (listener != null) {
+ * view.addOnFooListener(listener);
+ * }
+ * }
+ * }
+ * </pre>
+ *
+ * @param view The View that will have this listener
+ * @param listener The listener to keep track of. May be null if the listener is being removed.
+ * @param listenerResourceId A unique resource ID associated with the listener type.
+ * @return The previously tracked listener. This will be null if the View did not have
+ * a previously-tracked listener.
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> T trackListener(View view, T listener, int listenerResourceId) {
+ if (VERSION.SDK_INT >= VERSION_CODES.ICE_CREAM_SANDWICH) {
+ final T oldValue = (T) view.getTag(listenerResourceId);
+ view.setTag(listenerResourceId, listener);
+ return oldValue;
+ } else {
+ synchronized (sListeners) {
+ WeakHashMap<View, WeakReference<?>> listeners = sListeners.get(listenerResourceId);
+ if (listeners == null) {
+ listeners = new WeakHashMap<>();
+ sListeners.put(listenerResourceId, listeners);
+ }
+ final WeakReference<T> oldValue;
+ if (listener == null) {
+ oldValue = (WeakReference<T>) listeners.remove(view);
+ } else {
+ oldValue = (WeakReference<T>) listeners.put(view, new WeakReference(listener));
+ }
+ if (oldValue == null) {
+ return null;
+ } else {
+ return oldValue.get();
+ }
+ }
+ }
+ }
+
+}
diff --git a/extensions/baseAdapters/src/main/java/android/databinding/adapters/NumberPickerBindingAdapter.java b/extensions/baseAdapters/src/main/java/android/databinding/adapters/NumberPickerBindingAdapter.java
new file mode 100644
index 00000000..17e53cdc
--- /dev/null
+++ b/extensions/baseAdapters/src/main/java/android/databinding/adapters/NumberPickerBindingAdapter.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.databinding.adapters;
+
+import android.databinding.BindingMethod;
+import android.databinding.BindingMethods;
+import android.widget.NumberPicker;
+
+@BindingMethods({
+ @BindingMethod(type = NumberPicker.class, attribute = "android:format", method = "setFormatter"),
+ @BindingMethod(type = NumberPicker.class, attribute = "android:onScrollStateChange", method = "setOnScrollListener"),
+ @BindingMethod(type = NumberPicker.class, attribute = "android:onValueChange", method = "setOnValueChangedListener"),
+})
+public class NumberPickerBindingAdapter {
+}
diff --git a/extensions/baseAdapters/src/main/java/android/databinding/adapters/RadioGroupBindingAdapter.java b/extensions/baseAdapters/src/main/java/android/databinding/adapters/RadioGroupBindingAdapter.java
index b9d1e088..af9f0425 100644
--- a/extensions/baseAdapters/src/main/java/android/databinding/adapters/RadioGroupBindingAdapter.java
+++ b/extensions/baseAdapters/src/main/java/android/databinding/adapters/RadioGroupBindingAdapter.java
@@ -17,10 +17,11 @@ package android.databinding.adapters;
import android.databinding.BindingMethod;
import android.databinding.BindingMethods;
+import android.widget.RadioGroup;
@BindingMethods({
- @BindingMethod(type = android.widget.RadioGroup.class, attribute = "android:checkedButton", method = "check"),
+ @BindingMethod(type = RadioGroup.class, attribute = "android:checkedButton", method = "check"),
+ @BindingMethod(type = RadioGroup.class, attribute = "android:onCheckedChanged", method = "setOnCheckedChangeListener"),
})
public class RadioGroupBindingAdapter {
-
}
diff --git a/extensions/baseAdapters/src/main/java/android/databinding/adapters/RatingBarBindingAdapter.java b/extensions/baseAdapters/src/main/java/android/databinding/adapters/RatingBarBindingAdapter.java
new file mode 100644
index 00000000..5e49c72d
--- /dev/null
+++ b/extensions/baseAdapters/src/main/java/android/databinding/adapters/RatingBarBindingAdapter.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.databinding.adapters;
+
+import android.databinding.BindingMethod;
+import android.databinding.BindingMethods;
+import android.widget.RatingBar;
+
+@BindingMethods({
+ @BindingMethod(type = RatingBar.class, attribute = "android:onRatingChanged", method = "setOnRatingBarChangeListener"),
+})
+public class RatingBarBindingAdapter {
+}
diff --git a/extensions/baseAdapters/src/main/java/android/databinding/adapters/SearchViewBindingAdapter.java b/extensions/baseAdapters/src/main/java/android/databinding/adapters/SearchViewBindingAdapter.java
new file mode 100644
index 00000000..25ddcf8e
--- /dev/null
+++ b/extensions/baseAdapters/src/main/java/android/databinding/adapters/SearchViewBindingAdapter.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.databinding.adapters;
+
+import android.annotation.TargetApi;
+import android.databinding.BindingAdapter;
+import android.databinding.BindingMethod;
+import android.databinding.BindingMethods;
+import android.os.Build;
+import android.os.Build.VERSION;
+import android.os.Build.VERSION_CODES;
+import android.widget.RatingBar;
+import android.widget.SearchView;
+import android.widget.SearchView.OnCloseListener;
+import android.widget.SearchView.OnQueryTextListener;
+import android.widget.SearchView.OnSuggestionListener;
+
+@BindingMethods({
+ @BindingMethod(type = SearchView.class, attribute = "android:onQueryTextFocusChange", method = "setOnQueryTextFocusChangeListener"),
+ @BindingMethod(type = SearchView.class, attribute = "android:onSearchClick", method = "setOnSearchClickListener"),
+ @BindingMethod(type = SearchView.class, attribute = "android:onClose", method = "setOnCloseListener"),
+})
+public class SearchViewBindingAdapter {
+ @BindingAdapter("android:onQueryTextChange")
+ public static void setListener(SearchView view, OnQueryTextChange listener) {
+ setListener(view, null, listener);
+ }
+
+ @BindingAdapter("android:onQueryTextSubmit")
+ public static void setListener(SearchView view, OnQueryTextSubmit listener) {
+ setListener(view, listener, null);
+ }
+
+ @BindingAdapter({"android:onQueryTextSubmit", "android:onQueryTextChange"})
+ public static void setListener(SearchView view, final OnQueryTextSubmit submit,
+ final OnQueryTextChange change) {
+ if (VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB) {
+ if (submit == null && change == null){
+ view.setOnQueryTextListener(null);
+ } else {
+ view.setOnQueryTextListener(new OnQueryTextListener() {
+ @Override
+ public boolean onQueryTextSubmit(String query) {
+ if (submit != null) {
+ return submit.onQueryTextSubmit(query);
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public boolean onQueryTextChange(String newText) {
+ if (change != null) {
+ return change.onQueryTextChange(newText);
+ } else {
+ return false;
+ }
+ }
+ });
+ }
+ }
+ }
+
+ @BindingAdapter("android:onSuggestionClick")
+ public static void setListener(SearchView view, OnSuggestionClick listener) {
+ setListener(view, null, listener);
+ }
+
+ @BindingAdapter("android:onSuggestionSelect")
+ public static void setListener(SearchView view, OnSuggestionSelect listener) {
+ setListener(view, listener, null);
+ }
+
+ @BindingAdapter({"android:onSuggestionSelect", "android:onSuggestionClick"})
+ public static void setListener(SearchView view, final OnSuggestionSelect submit,
+ final OnSuggestionClick change) {
+ if (VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB) {
+ if (submit == null && change == null) {
+ view.setOnSuggestionListener(null);
+ } else {
+ view.setOnSuggestionListener(new OnSuggestionListener() {
+ @Override
+ public boolean onSuggestionSelect(int position) {
+ if (submit != null) {
+ return submit.onSuggestionSelect(position);
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public boolean onSuggestionClick(int position) {
+ if (change != null) {
+ return change.onSuggestionClick(position);
+ } else {
+ return false;
+ }
+ }
+ });
+ }
+ }
+ }
+
+ @TargetApi(VERSION_CODES.HONEYCOMB)
+ public interface OnQueryTextSubmit {
+ boolean onQueryTextSubmit(String query);
+ }
+
+ @TargetApi(VERSION_CODES.HONEYCOMB)
+ public interface OnQueryTextChange {
+ boolean onQueryTextChange(String newText);
+ }
+
+ @TargetApi(VERSION_CODES.HONEYCOMB)
+ public interface OnSuggestionSelect {
+ boolean onSuggestionSelect(int position);
+ }
+
+ @TargetApi(VERSION_CODES.HONEYCOMB)
+ public interface OnSuggestionClick {
+ boolean onSuggestionClick(int position);
+ }
+}
diff --git a/extensions/baseAdapters/src/main/java/android/databinding/adapters/SeekBarBindingAdapter.java b/extensions/baseAdapters/src/main/java/android/databinding/adapters/SeekBarBindingAdapter.java
new file mode 100644
index 00000000..eeac77c9
--- /dev/null
+++ b/extensions/baseAdapters/src/main/java/android/databinding/adapters/SeekBarBindingAdapter.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.databinding.adapters;
+
+import android.databinding.BindingAdapter;
+import android.widget.SeekBar;
+import android.widget.SeekBar.OnSeekBarChangeListener;
+
+public class SeekBarBindingAdapter {
+ @BindingAdapter("android:onProgressChanged")
+ public static void setListener(SeekBar view, OnProgressChanged listener) {
+ setListener(view, null, null, listener);
+ }
+
+ @BindingAdapter("android:onStartTrackingTouch")
+ public static void setListener(SeekBar view, OnStartTrackingTouch listener) {
+ setListener(view, listener, null, null);
+ }
+
+ @BindingAdapter("android:onStopTrackingTouch")
+ public static void setListener(SeekBar view, OnStopTrackingTouch listener) {
+ setListener(view, null, listener, null);
+ }
+
+ @BindingAdapter({"android:onStartTrackingTouch", "android:onStopTrackingTouch"})
+ public static void setListener(SeekBar view, final OnStartTrackingTouch start,
+ final OnStopTrackingTouch stop) {
+ setListener(view, start, stop, null);
+ }
+
+ @BindingAdapter({"android:onStartTrackingTouch", "android:onProgressChanged"})
+ public static void setListener(SeekBar view, final OnStartTrackingTouch start,
+ final OnProgressChanged progressChanged) {
+ setListener(view, start, null, progressChanged);
+ }
+
+ @BindingAdapter({"android:onStopTrackingTouch", "android:onProgressChanged"})
+ public static void setListener(SeekBar view, final OnStopTrackingTouch stop,
+ final OnProgressChanged progressChanged) {
+ setListener(view, null, stop, progressChanged);
+ }
+
+ @BindingAdapter({"android:onStartTrackingTouch", "android:onStopTrackingTouch", "android:onProgressChanged"})
+ public static void setListener(SeekBar view, final OnStartTrackingTouch start,
+ final OnStopTrackingTouch stop, final OnProgressChanged progressChanged) {
+ if (start == null && stop == null && progressChanged == null) {
+ view.setOnSeekBarChangeListener(null);
+ } else {
+ view.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
+ @Override
+ public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+ if (progressChanged != null) {
+ progressChanged.onProgressChanged(seekBar, progress, fromUser);
+ }
+ }
+
+ @Override
+ public void onStartTrackingTouch(SeekBar seekBar) {
+ if (start != null) {
+ start.onStartTrackingTouch(seekBar);
+ }
+ }
+
+ @Override
+ public void onStopTrackingTouch(SeekBar seekBar) {
+ if (stop != null) {
+ stop.onStopTrackingTouch(seekBar);
+ }
+ }
+ });
+ }
+ }
+
+ public interface OnStartTrackingTouch {
+ void onStartTrackingTouch(SeekBar seekBar);
+ }
+
+ public interface OnStopTrackingTouch {
+ void onStopTrackingTouch(SeekBar seekBar);
+ }
+
+ public interface OnProgressChanged {
+ void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser);
+ }
+}
diff --git a/extensions/baseAdapters/src/main/java/android/databinding/adapters/SpinnerBindingAdapter.java b/extensions/baseAdapters/src/main/java/android/databinding/adapters/SpinnerBindingAdapter.java
index 1638af76..711b048e 100644
--- a/extensions/baseAdapters/src/main/java/android/databinding/adapters/SpinnerBindingAdapter.java
+++ b/extensions/baseAdapters/src/main/java/android/databinding/adapters/SpinnerBindingAdapter.java
@@ -22,5 +22,4 @@ import android.databinding.BindingMethods;
@BindingMethod(type = android.widget.Spinner.class, attribute = "android:popupBackground", method = "setPopupBackgroundDrawable"),
})
public class SpinnerBindingAdapter {
-
}
diff --git a/extensions/baseAdapters/src/main/java/android/databinding/adapters/TabHostBindingAdapter.java b/extensions/baseAdapters/src/main/java/android/databinding/adapters/TabHostBindingAdapter.java
new file mode 100644
index 00000000..78f06b0d
--- /dev/null
+++ b/extensions/baseAdapters/src/main/java/android/databinding/adapters/TabHostBindingAdapter.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.databinding.adapters;
+
+import android.databinding.BindingMethod;
+import android.databinding.BindingMethods;
+import android.widget.TabHost;
+
+@BindingMethods({
+ @BindingMethod(type = TabHost.class, attribute = "android:onTabChanged", method = "setOnTabChangedListener"),
+})
+public class TabHostBindingAdapter {
+}
diff --git a/extensions/baseAdapters/src/main/java/android/databinding/adapters/TextViewBindingAdapter.java b/extensions/baseAdapters/src/main/java/android/databinding/adapters/TextViewBindingAdapter.java
index 6b653719..01ea0069 100644
--- a/extensions/baseAdapters/src/main/java/android/databinding/adapters/TextViewBindingAdapter.java
+++ b/extensions/baseAdapters/src/main/java/android/databinding/adapters/TextViewBindingAdapter.java
@@ -20,8 +20,10 @@ import android.databinding.BindingMethod;
import android.databinding.BindingMethods;
import android.graphics.drawable.Drawable;
import android.os.Build;
+import android.text.Editable;
import android.text.InputFilter;
import android.text.InputType;
+import android.text.TextWatcher;
import android.text.method.DialerKeyListener;
import android.text.method.DigitsKeyListener;
import android.text.method.KeyListener;
@@ -31,16 +33,19 @@ import android.util.Log;
import android.util.TypedValue;
import android.widget.TextView;
+import com.android.databinding.library.baseAdapters.R;
+
@BindingMethods({
- @BindingMethod(type = android.widget.TextView.class, attribute = "android:autoLink", method = "setAutoLinkMask"),
- @BindingMethod(type = android.widget.TextView.class, attribute = "android:drawablePadding", method = "setCompoundDrawablePadding"),
- @BindingMethod(type = android.widget.TextView.class, attribute = "android:editorExtras", method = "setInputExtras"),
- @BindingMethod(type = android.widget.TextView.class, attribute = "android:inputType", method = "setRawInputType"),
- @BindingMethod(type = android.widget.TextView.class, attribute = "android:scrollHorizontally", method = "setHorizontallyScrolling"),
- @BindingMethod(type = android.widget.TextView.class, attribute = "android:textAllCaps", method = "setAllCaps"),
- @BindingMethod(type = android.widget.TextView.class, attribute = "android:textColorHighlight", method = "setHighlightColor"),
- @BindingMethod(type = android.widget.TextView.class, attribute = "android:textColorHint", method = "setHintTextColor"),
- @BindingMethod(type = android.widget.TextView.class, attribute = "android:textColorLink", method = "setLinkTextColor"),
+ @BindingMethod(type = TextView.class, attribute = "android:autoLink", method = "setAutoLinkMask"),
+ @BindingMethod(type = TextView.class, attribute = "android:drawablePadding", method = "setCompoundDrawablePadding"),
+ @BindingMethod(type = TextView.class, attribute = "android:editorExtras", method = "setInputExtras"),
+ @BindingMethod(type = TextView.class, attribute = "android:inputType", method = "setRawInputType"),
+ @BindingMethod(type = TextView.class, attribute = "android:scrollHorizontally", method = "setHorizontallyScrolling"),
+ @BindingMethod(type = TextView.class, attribute = "android:textAllCaps", method = "setAllCaps"),
+ @BindingMethod(type = TextView.class, attribute = "android:textColorHighlight", method = "setHighlightColor"),
+ @BindingMethod(type = TextView.class, attribute = "android:textColorHint", method = "setHintTextColor"),
+ @BindingMethod(type = TextView.class, attribute = "android:textColorLink", method = "setLinkTextColor"),
+ @BindingMethod(type = TextView.class, attribute = "android:onEditorAction", method = "setOnEditorActionListener"),
})
public class TextViewBindingAdapter {
@@ -280,4 +285,88 @@ public class TextViewBindingAdapter {
public static void setTextSize(TextView view, float size) {
view.setTextSize(TypedValue.COMPLEX_UNIT_PX, size);
}
+
+ @BindingAdapter("android:afterTextChanged")
+ public static void setListener(TextView view, AfterTextChanged after) {
+ setListener(view, null, null, after);
+ }
+
+ @BindingAdapter("android:beforeTextChanged")
+ public static void setListener(TextView view, BeforeTextChanged before) {
+ setListener(view, before, null, null);
+ }
+
+ @BindingAdapter("android:onTextChanged")
+ public static void setListener(TextView view, OnTextChanged onTextChanged) {
+ setListener(view, null, onTextChanged, null);
+ }
+
+ @BindingAdapter({"android:beforeTextChanged", "android:afterTextChanged"})
+ public static void setListener(TextView view, final BeforeTextChanged before,
+ final AfterTextChanged after) {
+ setListener(view, before, null, after);
+ }
+
+ @BindingAdapter({"android:beforeTextChanged", "android:onTextChanged"})
+ public static void setListener(TextView view, final BeforeTextChanged before,
+ final OnTextChanged on) {
+ setListener(view, before, on, null);
+ }
+
+ @BindingAdapter({"android:onTextChanged", "android:afterTextChanged"})
+ public static void setListener(TextView view,final OnTextChanged on,
+ final AfterTextChanged after) {
+ setListener(view, null, on, after);
+ }
+
+ @BindingAdapter({"android:beforeTextChanged", "android:onTextChanged", "android:afterTextChanged"})
+ public static void setListener(TextView view, final BeforeTextChanged before,
+ final OnTextChanged on, final AfterTextChanged after) {
+ final TextWatcher newValue;
+ if (before == null && after == null && on == null) {
+ newValue = null;
+ } else {
+ newValue = new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ if (before != null) {
+ before.beforeTextChanged(s, start, count, after);
+ }
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ if (on != null) {
+ on.onTextChanged(s, start, before, count);
+ }
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ if (after != null) {
+ after.afterTextChanged(s);
+ }
+ }
+ };
+ }
+ final TextWatcher oldValue = ListenerUtil.trackListener(view, newValue, R.id.textWatcher);
+ if (oldValue != null) {
+ view.removeTextChangedListener(oldValue);
+ }
+ if (newValue != null) {
+ view.addTextChangedListener(newValue);
+ }
+ }
+
+ public interface AfterTextChanged {
+ void afterTextChanged(Editable s);
+ }
+
+ public interface BeforeTextChanged {
+ void beforeTextChanged(CharSequence s, int start, int count, int after);
+ }
+
+ public interface OnTextChanged {
+ void onTextChanged(CharSequence s, int start, int before, int count);
+ }
}
diff --git a/extensions/baseAdapters/src/main/java/android/databinding/adapters/TimePickerBindingAdapter.java b/extensions/baseAdapters/src/main/java/android/databinding/adapters/TimePickerBindingAdapter.java
new file mode 100644
index 00000000..3a11dab9
--- /dev/null
+++ b/extensions/baseAdapters/src/main/java/android/databinding/adapters/TimePickerBindingAdapter.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.databinding.adapters;
+
+import android.databinding.BindingMethod;
+import android.databinding.BindingMethods;
+import android.widget.TimePicker;
+
+@BindingMethods({
+ @BindingMethod(type = TimePicker.class, attribute = "android:onTimeChanged", method = "setOnTimeChangedListener"),
+})
+public class TimePickerBindingAdapter {
+}
diff --git a/extensions/baseAdapters/src/main/java/android/databinding/adapters/ToolbarBindingAdapter.java b/extensions/baseAdapters/src/main/java/android/databinding/adapters/ToolbarBindingAdapter.java
new file mode 100644
index 00000000..8baf2556
--- /dev/null
+++ b/extensions/baseAdapters/src/main/java/android/databinding/adapters/ToolbarBindingAdapter.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.databinding.adapters;
+
+import android.databinding.BindingMethod;
+import android.databinding.BindingMethods;
+import android.widget.Toolbar;
+
+@BindingMethods({
+ @BindingMethod(type = Toolbar.class, attribute = "android:onMenuItemClick", method = "setOnMenuItemClickListener"),
+ @BindingMethod(type = Toolbar.class, attribute = "android:onNavigationClick", method = "setNavigationOnClickListener"),
+})
+public class ToolbarBindingAdapter {
+}
diff --git a/extensions/baseAdapters/src/main/java/android/databinding/adapters/VideoViewBindingAdapter.java b/extensions/baseAdapters/src/main/java/android/databinding/adapters/VideoViewBindingAdapter.java
new file mode 100644
index 00000000..d47c1ef4
--- /dev/null
+++ b/extensions/baseAdapters/src/main/java/android/databinding/adapters/VideoViewBindingAdapter.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.databinding.adapters;
+
+import android.databinding.BindingMethod;
+import android.databinding.BindingMethods;
+import android.widget.VideoView;
+import android.widget.ViewSwitcher;
+
+@BindingMethods({
+ @BindingMethod(type = VideoView.class, attribute = "android:onCompletion", method = "setOnCompletionListener"),
+ @BindingMethod(type = VideoView.class, attribute = "android:onError", method = "setOnErrorListener"),
+ @BindingMethod(type = VideoView.class, attribute = "android:onInfo", method = "setOnInfoListener"),
+ @BindingMethod(type = VideoView.class, attribute = "android:onPrepared", method = "setOnPreparedListener"),
+})
+public class VideoViewBindingAdapter {
+}
diff --git a/extensions/baseAdapters/src/main/java/android/databinding/adapters/ViewBindingAdapter.java b/extensions/baseAdapters/src/main/java/android/databinding/adapters/ViewBindingAdapter.java
index 7ffff6e2..f9fae7b6 100644
--- a/extensions/baseAdapters/src/main/java/android/databinding/adapters/ViewBindingAdapter.java
+++ b/extensions/baseAdapters/src/main/java/android/databinding/adapters/ViewBindingAdapter.java
@@ -15,27 +15,44 @@
*/
package android.databinding.adapters;
+import android.annotation.TargetApi;
import android.databinding.BindingAdapter;
import android.databinding.BindingMethod;
import android.databinding.BindingMethods;
import android.os.Build;
+import android.os.Build.VERSION;
+import android.os.Build.VERSION_CODES;
import android.view.View;
+import android.view.View.OnAttachStateChangeListener;
+import com.android.databinding.library.baseAdapters.R;
@BindingMethods({
- @BindingMethod(type = android.view.View.class, attribute = "android:backgroundTint", method = "setBackgroundTintList"),
- @BindingMethod(type = android.view.View.class, attribute = "android:fadeScrollbars", method = "setScrollbarFadingEnabled"),
- @BindingMethod(type = android.view.View.class, attribute = "android:nextFocusForward", method = "setNextFocusForwardId"),
- @BindingMethod(type = android.view.View.class, attribute = "android:nextFocusLeft", method = "setNextFocusLeftId"),
- @BindingMethod(type = android.view.View.class, attribute = "android:nextFocusRight", method = "setNextFocusRightId"),
- @BindingMethod(type = android.view.View.class, attribute = "android:nextFocusUp", method = "setNextFocusUpId"),
- @BindingMethod(type = android.view.View.class, attribute = "android:nextFocusDown", method = "setNextFocusDownId"),
- @BindingMethod(type = android.view.View.class, attribute = "android:requiresFadingEdge", method = "setVerticalFadingEdgeEnabled"),
- @BindingMethod(type = android.view.View.class, attribute = "android:scrollbarDefaultDelayBeforeFade", method = "setScrollBarDefaultDelayBeforeFade"),
- @BindingMethod(type = android.view.View.class, attribute = "android:scrollbarFadeDuration", method = "setScrollBarFadeDuration"),
- @BindingMethod(type = android.view.View.class, attribute = "android:scrollbarSize", method = "setScrollBarSize"),
- @BindingMethod(type = android.view.View.class, attribute = "android:scrollbarStyle", method = "setScrollBarStyle"),
- @BindingMethod(type = android.view.View.class, attribute = "android:transformPivotX", method = "setPivotX"),
- @BindingMethod(type = android.view.View.class, attribute = "android:transformPivotY", method = "setPivotY"),
+ @BindingMethod(type = View.class, attribute = "android:backgroundTint", method = "setBackgroundTintList"),
+ @BindingMethod(type = View.class, attribute = "android:fadeScrollbars", method = "setScrollbarFadingEnabled"),
+ @BindingMethod(type = View.class, attribute = "android:getOutline", method = "setOutlineProvider"),
+ @BindingMethod(type = View.class, attribute = "android:nextFocusForward", method = "setNextFocusForwardId"),
+ @BindingMethod(type = View.class, attribute = "android:nextFocusLeft", method = "setNextFocusLeftId"),
+ @BindingMethod(type = View.class, attribute = "android:nextFocusRight", method = "setNextFocusRightId"),
+ @BindingMethod(type = View.class, attribute = "android:nextFocusUp", method = "setNextFocusUpId"),
+ @BindingMethod(type = View.class, attribute = "android:nextFocusDown", method = "setNextFocusDownId"),
+ @BindingMethod(type = View.class, attribute = "android:requiresFadingEdge", method = "setVerticalFadingEdgeEnabled"),
+ @BindingMethod(type = View.class, attribute = "android:scrollbarDefaultDelayBeforeFade", method = "setScrollBarDefaultDelayBeforeFade"),
+ @BindingMethod(type = View.class, attribute = "android:scrollbarFadeDuration", method = "setScrollBarFadeDuration"),
+ @BindingMethod(type = View.class, attribute = "android:scrollbarSize", method = "setScrollBarSize"),
+ @BindingMethod(type = View.class, attribute = "android:scrollbarStyle", method = "setScrollBarStyle"),
+ @BindingMethod(type = View.class, attribute = "android:transformPivotX", method = "setPivotX"),
+ @BindingMethod(type = View.class, attribute = "android:transformPivotY", method = "setPivotY"),
+ @BindingMethod(type = View.class, attribute = "android:onDrag", method = "setOnDragListener"),
+ @BindingMethod(type = View.class, attribute = "android:onClick", method = "setOnClickListener"),
+ @BindingMethod(type = View.class, attribute = "android:onApplyWindowInsets", method = "setOnApplyWindowInsetsListener"),
+ @BindingMethod(type = View.class, attribute = "android:onCreateContextMenu", method = "setOnCreateContextMenuListener"),
+ @BindingMethod(type = View.class, attribute = "android:onFocusChange", method = "setOnFocusChangeListener"),
+ @BindingMethod(type = View.class, attribute = "android:onGenericMotion", method = "setOnGenericMotionListener"),
+ @BindingMethod(type = View.class, attribute = "android:onHover", method = "setOnHoverListener"),
+ @BindingMethod(type = View.class, attribute = "android:onKey", method = "setOnKeyListener"),
+ @BindingMethod(type = View.class, attribute = "android:onLongClick", method = "setOnLongClickListener"),
+ @BindingMethod(type = View.class, attribute = "android:onSystemUiVisibilityChange", method = "setOnSystemUiVisibilityChangeListener"),
+ @BindingMethod(type = View.class, attribute = "android:onTouch", method = "setOnTouchListener"),
})
public class ViewBindingAdapter {
public static int FADING_EDGE_NONE = 0;
@@ -107,4 +124,93 @@ public class ViewBindingAdapter {
view.setOnClickListener(clickListener);
view.setClickable(clickable);
}
+
+ @BindingAdapter({"android:onClick", "android:clickable"})
+ public static void setOnClick(View view, View.OnClickListener clickListener,
+ boolean clickable) {
+ view.setOnClickListener(clickListener);
+ view.setClickable(clickable);
+ }
+
+ @BindingAdapter({"android:onLongClickListener", "android:longClickable"})
+ public static void setListener(View view, View.OnLongClickListener clickListener,
+ boolean clickable) {
+ view.setOnLongClickListener(clickListener);
+ view.setLongClickable(clickable);
+ }
+
+ @BindingAdapter({"android:onLongClick", "android:longClickable"})
+ public static void setOnLongClick(View view, View.OnLongClickListener clickListener,
+ boolean clickable) {
+ view.setOnLongClickListener(clickListener);
+ view.setLongClickable(clickable);
+ }
+
+ @BindingAdapter("android:onViewAttachedToWindow")
+ public static void setListener(View view, OnViewAttachedToWindow attached) {
+ setListener(view, null, attached);
+ }
+
+ @BindingAdapter("android:onViewDetachedFromWindow")
+ public static void setListener(View view, OnViewDetachedFromWindow detached) {
+ setListener(view, detached, null);
+ }
+
+ @BindingAdapter({"android:onViewDetachedFromWindow", "android:onViewAttachedToWindow"})
+ public static void setListener(View view, final OnViewDetachedFromWindow detach,
+ final OnViewAttachedToWindow attach) {
+ if (VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB_MR1) {
+ final OnAttachStateChangeListener newListener;
+ if (detach == null && attach == null) {
+ newListener = null;
+ } else {
+ newListener = new OnAttachStateChangeListener() {
+ @Override
+ public void onViewAttachedToWindow(View v) {
+ if (attach != null) {
+ attach.onViewAttachedToWindow(v);
+ }
+ }
+
+ @Override
+ public void onViewDetachedFromWindow(View v) {
+ if (detach != null) {
+ detach.onViewDetachedFromWindow(v);
+ }
+ }
+ };
+ }
+ final OnAttachStateChangeListener oldListener = ListenerUtil.trackListener(view,
+ newListener, R.id.onAttachStateChangeListener);
+ if (oldListener != null) {
+ view.removeOnAttachStateChangeListener(oldListener);
+ }
+ if (newListener != null) {
+ view.addOnAttachStateChangeListener(newListener);
+ }
+ }
+ }
+
+ @BindingAdapter("android:onLayoutChange")
+ public static void setOnLayoutChangeListener(View view, View.OnLayoutChangeListener oldValue,
+ View.OnLayoutChangeListener newValue) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
+ if (oldValue != null) {
+ view.removeOnLayoutChangeListener(oldValue);
+ }
+ if (newValue != null) {
+ view.addOnLayoutChangeListener(newValue);
+ }
+ }
+ }
+
+ @TargetApi(VERSION_CODES.HONEYCOMB_MR1)
+ public interface OnViewDetachedFromWindow {
+ void onViewDetachedFromWindow(View v);
+ }
+
+ @TargetApi(VERSION_CODES.HONEYCOMB_MR1)
+ public interface OnViewAttachedToWindow {
+ void onViewAttachedToWindow(View v);
+ }
}
diff --git a/extensions/baseAdapters/src/main/java/android/databinding/adapters/ViewGroupBindingAdapter.java b/extensions/baseAdapters/src/main/java/android/databinding/adapters/ViewGroupBindingAdapter.java
index ea01fbd8..af108186 100644
--- a/extensions/baseAdapters/src/main/java/android/databinding/adapters/ViewGroupBindingAdapter.java
+++ b/extensions/baseAdapters/src/main/java/android/databinding/adapters/ViewGroupBindingAdapter.java
@@ -21,7 +21,11 @@ import android.databinding.BindingAdapter;
import android.databinding.BindingMethod;
import android.databinding.BindingMethods;
import android.os.Build;
+import android.view.View;
import android.view.ViewGroup;
+import android.view.ViewGroup.OnHierarchyChangeListener;
+import android.view.animation.Animation;
+import android.view.animation.Animation.AnimationListener;
@BindingMethods({
@BindingMethod(type = android.view.ViewGroup.class, attribute = "android:alwaysDrawnWithCache", method = "setAlwaysDrawnWithCacheEnabled"),
@@ -39,4 +43,123 @@ public class ViewGroupBindingAdapter {
view.setLayoutTransition(null);
}
}
+
+ @BindingAdapter("android:onChildViewAdded")
+ public static void setListener(ViewGroup view, OnChildViewAdded listener) {
+ setListener(view, listener, null);
+ }
+
+ @BindingAdapter("android:onChildViewRemoved")
+ public static void setListener(ViewGroup view, OnChildViewRemoved listener) {
+ setListener(view, null, listener);
+ }
+
+ @BindingAdapter({"android:onChildViewAdded", "android:onChildViewRemoved"})
+ public static void setListener(ViewGroup view, final OnChildViewAdded added,
+ final OnChildViewRemoved removed) {
+ if (added == null && removed == null) {
+ view.setOnHierarchyChangeListener(null);
+ } else {
+ view.setOnHierarchyChangeListener(new OnHierarchyChangeListener() {
+ @Override
+ public void onChildViewAdded(View parent, View child) {
+ if (added != null) {
+ added.onChildViewAdded(parent, child);
+ }
+ }
+
+ @Override
+ public void onChildViewRemoved(View parent, View child) {
+ if (removed != null) {
+ removed.onChildViewRemoved(parent, child);
+ }
+ }
+ });
+ }
+ }
+
+ @BindingAdapter({"android:onAnimationStart", "android:onAnimationEnd",
+ "android:onAnimationRepeat"})
+ public static void setListener(ViewGroup view, final OnAnimationStart start,
+ final OnAnimationEnd end, final OnAnimationRepeat repeat) {
+ if (start == null && end == null && repeat == null) {
+ view.setLayoutAnimationListener(null);
+ } else {
+ view.setLayoutAnimationListener(new AnimationListener() {
+ @Override
+ public void onAnimationStart(Animation animation) {
+ if (start != null) {
+ start.onAnimationStart(animation);
+ }
+ }
+
+ @Override
+ public void onAnimationEnd(Animation animation) {
+ if (end != null) {
+ end.onAnimationEnd(animation);
+ }
+ }
+
+ @Override
+ public void onAnimationRepeat(Animation animation) {
+ if (repeat != null) {
+ repeat.onAnimationRepeat(animation);
+ }
+ }
+ });
+ }
+ }
+
+ @BindingAdapter({"android:onAnimationStart", "android:onAnimationEnd"})
+ public static void setListener(ViewGroup view, final OnAnimationStart start,
+ final OnAnimationEnd end) {
+ setListener(view, start, end, null);
+ }
+
+ @BindingAdapter({"android:onAnimationEnd", "android:onAnimationRepeat"})
+ public static void setListener(ViewGroup view, final OnAnimationEnd end,
+ final OnAnimationRepeat repeat) {
+ setListener(view, null, end, repeat);
+ }
+
+ @BindingAdapter({"android:onAnimationStart", "android:onAnimationRepeat"})
+ public static void setListener(ViewGroup view, final OnAnimationStart start,
+ final OnAnimationRepeat repeat) {
+ setListener(view, start, null, repeat);
+ }
+
+ @BindingAdapter("android:onAnimationStart")
+ public static void setListener(ViewGroup view, final OnAnimationStart start) {
+ setListener(view, start, null, null);
+ }
+
+ @BindingAdapter("android:onAnimationEnd")
+ public static void setListener(ViewGroup view, final OnAnimationEnd end) {
+ setListener(view, null, end, null);
+ }
+
+ @BindingAdapter("android:onAnimationRepeat")
+ public static void setListener(ViewGroup view, final OnAnimationRepeat repeat) {
+ setListener(view, null, null, repeat);
+ }
+
+ public interface OnChildViewAdded {
+ void onChildViewAdded(View parent, View child);
+ }
+
+ public interface OnChildViewRemoved {
+ void onChildViewRemoved(View parent, View child);
+ }
+
+ public interface OnAnimationStart {
+ void onAnimationStart(Animation animation);
+ }
+
+ public interface OnAnimationEnd {
+ void onAnimationEnd(Animation animation);
+ }
+
+ public interface OnAnimationRepeat {
+ void onAnimationRepeat(Animation animation);
+ }
}
diff --git a/extensions/baseAdapters/src/main/java/android/databinding/adapters/ViewStubBindingAdapter.java b/extensions/baseAdapters/src/main/java/android/databinding/adapters/ViewStubBindingAdapter.java
index 1661458b..f835f313 100644
--- a/extensions/baseAdapters/src/main/java/android/databinding/adapters/ViewStubBindingAdapter.java
+++ b/extensions/baseAdapters/src/main/java/android/databinding/adapters/ViewStubBindingAdapter.java
@@ -15,14 +15,21 @@
*/
package android.databinding.adapters;
+import android.databinding.BindingAdapter;
import android.databinding.BindingMethod;
import android.databinding.BindingMethods;
import android.databinding.Untaggable;
+import android.databinding.ViewStubProxy;
+import android.view.ViewStub.OnInflateListener;
@Untaggable({"android.view.ViewStub"})
@BindingMethods({
@BindingMethod(type = android.view.ViewStub.class, attribute = "android:layout", method = "setLayoutResource")
})
public class ViewStubBindingAdapter {
-
+ @BindingAdapter("android:onInflate")
+ public static void setOnInflateListener(ViewStubProxy viewStubProxy,
+ OnInflateListener listener) {
+ viewStubProxy.setOnInflateListener(listener);
+ }
}
diff --git a/extensions/baseAdapters/src/main/java/android/databinding/adapters/ZoomControlsBindingAdapter.java b/extensions/baseAdapters/src/main/java/android/databinding/adapters/ZoomControlsBindingAdapter.java
new file mode 100644
index 00000000..bb278eb0
--- /dev/null
+++ b/extensions/baseAdapters/src/main/java/android/databinding/adapters/ZoomControlsBindingAdapter.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.databinding.adapters;
+
+import android.databinding.BindingMethod;
+import android.databinding.BindingMethods;
+import android.widget.ZoomControls;
+
+@BindingMethods({
+ @BindingMethod(type = ZoomControls.class, attribute = "android:onZoomIn", method = "setOnZoomInClickListener"),
+ @BindingMethod(type = ZoomControls.class, attribute = "android:onZoomOut", method = "setOnZoomOutClickListener"),
+})
+public class ZoomControlsBindingAdapter {
+}
diff --git a/extensions/baseAdapters/src/main/res/values/ids.xml b/extensions/baseAdapters/src/main/res/values/ids.xml
new file mode 100644
index 00000000..7e76dbe4
--- /dev/null
+++ b/extensions/baseAdapters/src/main/res/values/ids.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Used to track OnAttachStateChangeListeners for View BindingAdapter -->
+ <item type="id" name="onAttachStateChangeListener"/>
+ <!-- Used to track TextWatcher for TextView BindingAdapter -->
+ <item type="id" name="textWatcher"/>
+</resources> \ No newline at end of file