1/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package android.databinding;
17
18import java.lang.annotation.ElementType;
19import java.lang.annotation.Target;
20
21/**
22 * InverseBindingAdapter is associated with a method used to retrieve the value for a View
23 * when setting values gathered from the View. This is similar to {@link BindingAdapter}s:
24 * <pre>
25 * &commat;InverseBindingAdapter(attribute = "android:text", event = "android:textAttrChanged")
26 * public static String captureTextValue(TextView view, CharSequence originalValue) {
27 *     CharSequence newValue = view.getText();
28 *     CharSequence oldValue = value.get();
29 *     if (oldValue == null) {
30 *         value.set(newValue);
31 *     } else if (!contentEquals(newValue, oldValue)) {
32 *         value.set(newValue);
33 *     }
34 * }
35 * </pre>
36 * <p>
37 * The default value for event is the attribute name suffixed with "AttrChanged". In the
38 * above example, the default value would have been <code>android:textAttrChanged</code> even
39 * if it wasn't provided.
40 * <p>
41 * The event attribute is used to notify the data binding system that the value has changed.
42 * The developer will typically create a {@link BindingAdapter} to assign the event. For example:
43 * <p>
44 * <pre>
45 * &commat;BindingAdapter(value = {"android:beforeTextChanged", "android:onTextChanged",
46 *                          "android:afterTextChanged", "android:textAttrChanged"},
47 *                          requireAll = false)
48 * public static void setTextWatcher(TextView view, final BeforeTextChanged before,
49 *                                   final OnTextChanged on, final AfterTextChanged after,
50 *                                   final InverseBindingListener textAttrChanged) {
51 *     TextWatcher newValue = new TextWatcher() {
52 *         ...
53 *         &commat;Override
54 *         public void onTextChanged(CharSequence s, int start, int before, int count) {
55 *             if (on != null) {
56 *                 on.onTextChanged(s, start, before, count);
57 *             }
58 *             if (textAttrChanged != null) {
59 *                 textAttrChanged.onChange();
60 *             }
61 *         }
62 *     }
63 *     TextWatcher oldValue = ListenerUtil.trackListener(view, newValue, R.id.textWatcher);
64 *     if (oldValue != null) {
65 *         view.removeTextChangedListener(oldValue);
66 *     }
67 *     view.addTextChangedListener(newValue);
68 * }
69 * </pre>
70 * <p>
71 * Like <code>BindingAdapter</code>s, InverseBindingAdapter methods may also take
72 * {@link DataBindingComponent} as the first parameter and may be an instance method with the
73 * instance retrieved from the <code>DataBindingComponent</code>.
74 *
75 * @see DataBindingUtil#setDefaultComponent(DataBindingComponent)
76 * @see InverseBindingMethod
77 */
78@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
79public @interface InverseBindingAdapter {
80
81    /**
82     * The attribute that the value is to be retrieved for.
83     */
84    String attribute();
85
86    /**
87     * The event used to trigger changes. This is used in {@link BindingAdapter}s for the
88     * data binding system to set the event listener when two-way binding is used.
89     */
90    String event() default "";
91}
92