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 * BindingAdapter is applied to methods that are used to manipulate how values with expressions
23 * are set to views. The simplest example is to have a public static method that takes the view
24 * and the value to set:
25 * <p><pre>
26 *<code>@BindingAdapter("android:bufferType")
27 * public static void setBufferType(TextView view, TextView.BufferType bufferType) {
28 *     view.setText(view.getText(), bufferType);
29 * }</code></pre>
30 * In the above example, when android:bufferType is used on a TextView, the method
31 * setBufferType is called.
32 * <p>
33 * It is also possible to take previously set values, if the old values are listed first:
34 * <p><pre>
35 *<code>@BindingAdapter("android:onLayoutChange")
36 * public static void setOnLayoutChangeListener(View view, View.OnLayoutChangeListener oldValue,
37 *                                              View.OnLayoutChangeListener newValue) {
38 *     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
39 *         if (oldValue != null) {
40 *             view.removeOnLayoutChangeListener(oldValue);
41 *         }
42 *         if (newValue != null) {
43 *             view.addOnLayoutChangeListener(newValue);
44 *         }
45 *     }
46 * }</code></pre>
47 * When a binding adapter may also take multiple attributes, it will only be called when all
48 * attributes associated with the binding adapter have binding expressions associated with them.
49 * This is useful when there are unusual interactions between attributes. For example:
50 * <p><pre>
51 *<code>@BindingAdapter({"android:onClick", "android:clickable"})
52 * public static void setOnClick(View view, View.OnClickListener clickListener,
53 *                               boolean clickable) {
54 *     view.setOnClickListener(clickListener);
55 *     view.setClickable(clickable);
56 * }</code></pre>
57 * The order of the parameters must match the order of the attributes in values in the
58 * BindingAdapter.
59 * <p>
60 * A binding adapter may optionally take a class extending DataBindingComponent as the first
61 * parameter as well. If it does, it will be passed the value passed in during binding, either
62 * directly in the inflate method or indirectly, using the value from
63 * {@link DataBindingUtil#getDefaultComponent()}.
64 * <p>
65 * If a binding adapter is an instance method, the generated DataBindingComponent will have
66 * a getter to retrieve an instance of the BindingAdapter's class to use to call the method.
67 */
68@Target(ElementType.METHOD)
69public @interface BindingAdapter {
70
71    /**
72     * @return The attributes associated with this binding adapter.
73     */
74    String[] value();
75
76    /**
77     * Whether every attribute must be assigned a binding expression or if some
78     * can be absent. When this is false, the BindingAdapter will be called
79     * when at least one associated attribute has a binding expression. The attributes
80     * for which there was no binding expression (even a normal XML value) will
81     * cause the associated parameter receive the Java default value. Care must be
82     * taken to ensure that a default value is not confused with a valid XML value.
83     *
84     * @return whether or not every attribute must be assigned a binding expression. The default
85     *         value is true.
86     */
87    boolean requireAll() default true;
88}
89