[go: nahoru, domu]

13561e3e665698843b1c664385a842e779198960bGeorge Mount/*
23561e3e665698843b1c664385a842e779198960bGeorge Mount * Copyright (C) 2015 The Android Open Source Project
33561e3e665698843b1c664385a842e779198960bGeorge Mount *
43561e3e665698843b1c664385a842e779198960bGeorge Mount * Licensed under the Apache License, Version 2.0 (the "License");
53561e3e665698843b1c664385a842e779198960bGeorge Mount * you may not use this file except in compliance with the License.
63561e3e665698843b1c664385a842e779198960bGeorge Mount * You may obtain a copy of the License at
73561e3e665698843b1c664385a842e779198960bGeorge Mount *
83561e3e665698843b1c664385a842e779198960bGeorge Mount *      http://www.apache.org/licenses/LICENSE-2.0
93561e3e665698843b1c664385a842e779198960bGeorge Mount *
103561e3e665698843b1c664385a842e779198960bGeorge Mount * Unless required by applicable law or agreed to in writing, software
113561e3e665698843b1c664385a842e779198960bGeorge Mount * distributed under the License is distributed on an "AS IS" BASIS,
123561e3e665698843b1c664385a842e779198960bGeorge Mount * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133561e3e665698843b1c664385a842e779198960bGeorge Mount * See the License for the specific language governing permissions and
143561e3e665698843b1c664385a842e779198960bGeorge Mount * limitations under the License.
153561e3e665698843b1c664385a842e779198960bGeorge Mount */
16fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountpackage android.databinding.adapters;
173561e3e665698843b1c664385a842e779198960bGeorge Mount
183b920788e90bb0abe615a5d5c899915f0014444bGeorge Mountimport com.android.databinding.library.baseAdapters.R;
193b920788e90bb0abe615a5d5c899915f0014444bGeorge Mount
20fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.BindingAdapter;
21fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.BindingMethod;
22fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.BindingMethods;
233b920788e90bb0abe615a5d5c899915f0014444bGeorge Mountimport android.databinding.InverseBindingAdapter;
243b920788e90bb0abe615a5d5c899915f0014444bGeorge Mountimport android.databinding.InverseBindingListener;
253561e3e665698843b1c664385a842e779198960bGeorge Mountimport android.graphics.drawable.Drawable;
263561e3e665698843b1c664385a842e779198960bGeorge Mountimport android.os.Build;
27716ba89e7f459f49ea85070d4710c1d79d715298George Mountimport android.text.Editable;
283561e3e665698843b1c664385a842e779198960bGeorge Mountimport android.text.InputFilter;
2971eb6908f2689bd17000237eb645896c36da0138George Mountimport android.text.InputType;
303b920788e90bb0abe615a5d5c899915f0014444bGeorge Mountimport android.text.Spanned;
313b920788e90bb0abe615a5d5c899915f0014444bGeorge Mountimport android.text.SpannableString;
323b920788e90bb0abe615a5d5c899915f0014444bGeorge Mountimport android.text.SpannableStringBuilder;
33716ba89e7f459f49ea85070d4710c1d79d715298George Mountimport android.text.TextWatcher;
343561e3e665698843b1c664385a842e779198960bGeorge Mountimport android.text.method.DialerKeyListener;
353561e3e665698843b1c664385a842e779198960bGeorge Mountimport android.text.method.DigitsKeyListener;
363561e3e665698843b1c664385a842e779198960bGeorge Mountimport android.text.method.KeyListener;
373561e3e665698843b1c664385a842e779198960bGeorge Mountimport android.text.method.PasswordTransformationMethod;
383561e3e665698843b1c664385a842e779198960bGeorge Mountimport android.text.method.TextKeyListener;
393561e3e665698843b1c664385a842e779198960bGeorge Mountimport android.util.Log;
403561e3e665698843b1c664385a842e779198960bGeorge Mountimport android.util.TypedValue;
413561e3e665698843b1c664385a842e779198960bGeorge Mountimport android.widget.TextView;
423561e3e665698843b1c664385a842e779198960bGeorge Mount
433561e3e665698843b1c664385a842e779198960bGeorge Mount@BindingMethods({
44716ba89e7f459f49ea85070d4710c1d79d715298George Mount        @BindingMethod(type = TextView.class, attribute = "android:autoLink", method = "setAutoLinkMask"),
45716ba89e7f459f49ea85070d4710c1d79d715298George Mount        @BindingMethod(type = TextView.class, attribute = "android:drawablePadding", method = "setCompoundDrawablePadding"),
46716ba89e7f459f49ea85070d4710c1d79d715298George Mount        @BindingMethod(type = TextView.class, attribute = "android:editorExtras", method = "setInputExtras"),
47716ba89e7f459f49ea85070d4710c1d79d715298George Mount        @BindingMethod(type = TextView.class, attribute = "android:inputType", method = "setRawInputType"),
48716ba89e7f459f49ea85070d4710c1d79d715298George Mount        @BindingMethod(type = TextView.class, attribute = "android:scrollHorizontally", method = "setHorizontallyScrolling"),
49716ba89e7f459f49ea85070d4710c1d79d715298George Mount        @BindingMethod(type = TextView.class, attribute = "android:textAllCaps", method = "setAllCaps"),
50716ba89e7f459f49ea85070d4710c1d79d715298George Mount        @BindingMethod(type = TextView.class, attribute = "android:textColorHighlight", method = "setHighlightColor"),
51716ba89e7f459f49ea85070d4710c1d79d715298George Mount        @BindingMethod(type = TextView.class, attribute = "android:textColorHint", method = "setHintTextColor"),
52716ba89e7f459f49ea85070d4710c1d79d715298George Mount        @BindingMethod(type = TextView.class, attribute = "android:textColorLink", method = "setLinkTextColor"),
53716ba89e7f459f49ea85070d4710c1d79d715298George Mount        @BindingMethod(type = TextView.class, attribute = "android:onEditorAction", method = "setOnEditorActionListener"),
543561e3e665698843b1c664385a842e779198960bGeorge Mount})
553561e3e665698843b1c664385a842e779198960bGeorge Mountpublic class TextViewBindingAdapter {
563561e3e665698843b1c664385a842e779198960bGeorge Mount
573561e3e665698843b1c664385a842e779198960bGeorge Mount    private static final String TAG = "TextViewBindingAdapters";
583561e3e665698843b1c664385a842e779198960bGeorge Mount    public static final int INTEGER = 0x01;
593561e3e665698843b1c664385a842e779198960bGeorge Mount    public static final int SIGNED = 0x03;
603561e3e665698843b1c664385a842e779198960bGeorge Mount    public static final int DECIMAL = 0x05;
613561e3e665698843b1c664385a842e779198960bGeorge Mount
623b920788e90bb0abe615a5d5c899915f0014444bGeorge Mount    @BindingAdapter("android:text")
633b920788e90bb0abe615a5d5c899915f0014444bGeorge Mount    public static void setText(TextView view, CharSequence text) {
643b920788e90bb0abe615a5d5c899915f0014444bGeorge Mount        final CharSequence oldText = view.getText();
653b920788e90bb0abe615a5d5c899915f0014444bGeorge Mount        if (text == oldText || (text == null && oldText.length() == 0)) {
663b920788e90bb0abe615a5d5c899915f0014444bGeorge Mount            return;
673b920788e90bb0abe615a5d5c899915f0014444bGeorge Mount        }
683b920788e90bb0abe615a5d5c899915f0014444bGeorge Mount        if (text instanceof Spanned) {
693b920788e90bb0abe615a5d5c899915f0014444bGeorge Mount            if (text.equals(oldText)) {
703b920788e90bb0abe615a5d5c899915f0014444bGeorge Mount                return; // No change in the spans, so don't set anything.
713b920788e90bb0abe615a5d5c899915f0014444bGeorge Mount            }
723b920788e90bb0abe615a5d5c899915f0014444bGeorge Mount        } else if (!haveContentsChanged(text, oldText)) {
733b920788e90bb0abe615a5d5c899915f0014444bGeorge Mount            return; // No content changes, so don't set anything.
743b920788e90bb0abe615a5d5c899915f0014444bGeorge Mount        }
753b920788e90bb0abe615a5d5c899915f0014444bGeorge Mount        view.setText(text);
763b920788e90bb0abe615a5d5c899915f0014444bGeorge Mount    }
773b920788e90bb0abe615a5d5c899915f0014444bGeorge Mount
783b920788e90bb0abe615a5d5c899915f0014444bGeorge Mount    @InverseBindingAdapter(attribute = "android:text", event = "android:textAttrChanged")
793b920788e90bb0abe615a5d5c899915f0014444bGeorge Mount    public static String getTextString(TextView view) {
803b920788e90bb0abe615a5d5c899915f0014444bGeorge Mount        return view.getText().toString();
813b920788e90bb0abe615a5d5c899915f0014444bGeorge Mount    }
823b920788e90bb0abe615a5d5c899915f0014444bGeorge Mount
8310960eb5f73fd587c2f8d18cfc61873c04017512George Mount    @BindingAdapter({"android:autoText"})
843561e3e665698843b1c664385a842e779198960bGeorge Mount    public static void setAutoText(TextView view, boolean autoText) {
853561e3e665698843b1c664385a842e779198960bGeorge Mount        KeyListener listener = view.getKeyListener();
863561e3e665698843b1c664385a842e779198960bGeorge Mount
873561e3e665698843b1c664385a842e779198960bGeorge Mount        TextKeyListener.Capitalize capitalize = TextKeyListener.Capitalize.NONE;
883561e3e665698843b1c664385a842e779198960bGeorge Mount
8971eb6908f2689bd17000237eb645896c36da0138George Mount        int inputType = listener != null ? listener.getInputType() : 0;
9071eb6908f2689bd17000237eb645896c36da0138George Mount        if ((inputType & InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS) != 0) {
9171eb6908f2689bd17000237eb645896c36da0138George Mount            capitalize = TextKeyListener.Capitalize.CHARACTERS;
9271eb6908f2689bd17000237eb645896c36da0138George Mount        } else if ((inputType & InputType.TYPE_TEXT_FLAG_CAP_WORDS) != 0) {
9371eb6908f2689bd17000237eb645896c36da0138George Mount            capitalize = TextKeyListener.Capitalize.WORDS;
9471eb6908f2689bd17000237eb645896c36da0138George Mount        } else if ((inputType & InputType.TYPE_TEXT_FLAG_CAP_SENTENCES) != 0) {
9571eb6908f2689bd17000237eb645896c36da0138George Mount            capitalize = TextKeyListener.Capitalize.SENTENCES;
963561e3e665698843b1c664385a842e779198960bGeorge Mount        }
9771eb6908f2689bd17000237eb645896c36da0138George Mount        view.setKeyListener(TextKeyListener.getInstance(autoText, capitalize));
983561e3e665698843b1c664385a842e779198960bGeorge Mount    }
993561e3e665698843b1c664385a842e779198960bGeorge Mount
10010960eb5f73fd587c2f8d18cfc61873c04017512George Mount    @BindingAdapter({"android:capitalize"})
10171eb6908f2689bd17000237eb645896c36da0138George Mount    public static void setCapitalize(TextView view, TextKeyListener.Capitalize capitalize) {
1023561e3e665698843b1c664385a842e779198960bGeorge Mount        KeyListener listener = view.getKeyListener();
1033561e3e665698843b1c664385a842e779198960bGeorge Mount
10471eb6908f2689bd17000237eb645896c36da0138George Mount        int inputType = listener.getInputType();
10571eb6908f2689bd17000237eb645896c36da0138George Mount        boolean autoText = (inputType & InputType.TYPE_TEXT_FLAG_AUTO_CORRECT) != 0;
10671eb6908f2689bd17000237eb645896c36da0138George Mount        view.setKeyListener(TextKeyListener.getInstance(autoText, capitalize));
1073561e3e665698843b1c664385a842e779198960bGeorge Mount    }
1083561e3e665698843b1c664385a842e779198960bGeorge Mount
10910960eb5f73fd587c2f8d18cfc61873c04017512George Mount    @BindingAdapter({"android:bufferType"})
1103561e3e665698843b1c664385a842e779198960bGeorge Mount    public static void setBufferType(TextView view, TextView.BufferType bufferType) {
1113561e3e665698843b1c664385a842e779198960bGeorge Mount        view.setText(view.getText(), bufferType);
1123561e3e665698843b1c664385a842e779198960bGeorge Mount    }
1133561e3e665698843b1c664385a842e779198960bGeorge Mount
11410960eb5f73fd587c2f8d18cfc61873c04017512George Mount    @BindingAdapter({"android:digits"})
1153561e3e665698843b1c664385a842e779198960bGeorge Mount    public static void setDigits(TextView view, CharSequence digits) {
1163561e3e665698843b1c664385a842e779198960bGeorge Mount        if (digits != null) {
1173561e3e665698843b1c664385a842e779198960bGeorge Mount            view.setKeyListener(DigitsKeyListener.getInstance(digits.toString()));
1183561e3e665698843b1c664385a842e779198960bGeorge Mount        } else if (view.getKeyListener() instanceof DigitsKeyListener) {
1193561e3e665698843b1c664385a842e779198960bGeorge Mount            view.setKeyListener(null);
1203561e3e665698843b1c664385a842e779198960bGeorge Mount        }
1213561e3e665698843b1c664385a842e779198960bGeorge Mount    }
1223561e3e665698843b1c664385a842e779198960bGeorge Mount
12310960eb5f73fd587c2f8d18cfc61873c04017512George Mount    @BindingAdapter({"android:numeric"})
1243561e3e665698843b1c664385a842e779198960bGeorge Mount    public static void setNumeric(TextView view, int numeric) {
1253561e3e665698843b1c664385a842e779198960bGeorge Mount        view.setKeyListener(DigitsKeyListener.getInstance((numeric & SIGNED) != 0,
1263561e3e665698843b1c664385a842e779198960bGeorge Mount                (numeric & DECIMAL) != 0));
1273561e3e665698843b1c664385a842e779198960bGeorge Mount    }
1283561e3e665698843b1c664385a842e779198960bGeorge Mount
12910960eb5f73fd587c2f8d18cfc61873c04017512George Mount    @BindingAdapter({"android:phoneNumber"})
1303561e3e665698843b1c664385a842e779198960bGeorge Mount    public static void setPhoneNumber(TextView view, boolean phoneNumber) {
1313561e3e665698843b1c664385a842e779198960bGeorge Mount        if (phoneNumber) {
1323561e3e665698843b1c664385a842e779198960bGeorge Mount            view.setKeyListener(DialerKeyListener.getInstance());
1333561e3e665698843b1c664385a842e779198960bGeorge Mount        } else if (view.getKeyListener() instanceof DialerKeyListener) {
1343561e3e665698843b1c664385a842e779198960bGeorge Mount            view.setKeyListener(null);
1353561e3e665698843b1c664385a842e779198960bGeorge Mount        }
1363561e3e665698843b1c664385a842e779198960bGeorge Mount    }
1373561e3e665698843b1c664385a842e779198960bGeorge Mount
13843af89d9798bf5d3f2fccaf0ed38735407b06b10George Mount    private static void setIntrinsicBounds(Drawable drawable) {
13943af89d9798bf5d3f2fccaf0ed38735407b06b10George Mount        if (drawable != null) {
14043af89d9798bf5d3f2fccaf0ed38735407b06b10George Mount            drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
14143af89d9798bf5d3f2fccaf0ed38735407b06b10George Mount        }
14243af89d9798bf5d3f2fccaf0ed38735407b06b10George Mount    }
14343af89d9798bf5d3f2fccaf0ed38735407b06b10George Mount
14410960eb5f73fd587c2f8d18cfc61873c04017512George Mount    @BindingAdapter({"android:drawableBottom"})
1453561e3e665698843b1c664385a842e779198960bGeorge Mount    public static void setDrawableBottom(TextView view, Drawable drawable) {
14643af89d9798bf5d3f2fccaf0ed38735407b06b10George Mount        setIntrinsicBounds(drawable);
1473561e3e665698843b1c664385a842e779198960bGeorge Mount        Drawable[] drawables = view.getCompoundDrawables();
1483561e3e665698843b1c664385a842e779198960bGeorge Mount        view.setCompoundDrawables(drawables[0], drawables[1], drawables[2], drawable);
1493561e3e665698843b1c664385a842e779198960bGeorge Mount    }
1503561e3e665698843b1c664385a842e779198960bGeorge Mount
15110960eb5f73fd587c2f8d18cfc61873c04017512George Mount    @BindingAdapter({"android:drawableLeft"})
1523561e3e665698843b1c664385a842e779198960bGeorge Mount    public static void setDrawableLeft(TextView view, Drawable drawable) {
15343af89d9798bf5d3f2fccaf0ed38735407b06b10George Mount        setIntrinsicBounds(drawable);
1543561e3e665698843b1c664385a842e779198960bGeorge Mount        Drawable[] drawables = view.getCompoundDrawables();
1553561e3e665698843b1c664385a842e779198960bGeorge Mount        view.setCompoundDrawables(drawable, drawables[1], drawables[2], drawables[3]);
1563561e3e665698843b1c664385a842e779198960bGeorge Mount    }
1573561e3e665698843b1c664385a842e779198960bGeorge Mount
15810960eb5f73fd587c2f8d18cfc61873c04017512George Mount    @BindingAdapter({"android:drawableRight"})
1593561e3e665698843b1c664385a842e779198960bGeorge Mount    public static void setDrawableRight(TextView view, Drawable drawable) {
16043af89d9798bf5d3f2fccaf0ed38735407b06b10George Mount        setIntrinsicBounds(drawable);
1613561e3e665698843b1c664385a842e779198960bGeorge Mount        Drawable[] drawables = view.getCompoundDrawables();
16243af89d9798bf5d3f2fccaf0ed38735407b06b10George Mount        view.setCompoundDrawables(drawables[0], drawables[1], drawable,
16343af89d9798bf5d3f2fccaf0ed38735407b06b10George Mount                drawables[3]);
1643561e3e665698843b1c664385a842e779198960bGeorge Mount    }
1653561e3e665698843b1c664385a842e779198960bGeorge Mount
16610960eb5f73fd587c2f8d18cfc61873c04017512George Mount    @BindingAdapter({"android:drawableTop"})
1673561e3e665698843b1c664385a842e779198960bGeorge Mount    public static void setDrawableTop(TextView view, Drawable drawable) {
16843af89d9798bf5d3f2fccaf0ed38735407b06b10George Mount        setIntrinsicBounds(drawable);
1693561e3e665698843b1c664385a842e779198960bGeorge Mount        Drawable[] drawables = view.getCompoundDrawables();
17043af89d9798bf5d3f2fccaf0ed38735407b06b10George Mount        view.setCompoundDrawables(drawables[0], drawable, drawables[2],
17143af89d9798bf5d3f2fccaf0ed38735407b06b10George Mount                drawables[3]);
1723561e3e665698843b1c664385a842e779198960bGeorge Mount    }
1733561e3e665698843b1c664385a842e779198960bGeorge Mount
17410960eb5f73fd587c2f8d18cfc61873c04017512George Mount    @BindingAdapter({"android:drawableStart"})
1753561e3e665698843b1c664385a842e779198960bGeorge Mount    public static void setDrawableStart(TextView view, Drawable drawable) {
1763561e3e665698843b1c664385a842e779198960bGeorge Mount        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
1773561e3e665698843b1c664385a842e779198960bGeorge Mount            setDrawableLeft(view, drawable);
1783561e3e665698843b1c664385a842e779198960bGeorge Mount        } else {
17943af89d9798bf5d3f2fccaf0ed38735407b06b10George Mount            setIntrinsicBounds(drawable);
1803561e3e665698843b1c664385a842e779198960bGeorge Mount            Drawable[] drawables = view.getCompoundDrawablesRelative();
18171eb6908f2689bd17000237eb645896c36da0138George Mount            view.setCompoundDrawablesRelative(drawable, drawables[1], drawables[2], drawables[3]);
1823561e3e665698843b1c664385a842e779198960bGeorge Mount        }
1833561e3e665698843b1c664385a842e779198960bGeorge Mount    }
1843561e3e665698843b1c664385a842e779198960bGeorge Mount
18510960eb5f73fd587c2f8d18cfc61873c04017512George Mount    @BindingAdapter({"android:drawableEnd"})
1863561e3e665698843b1c664385a842e779198960bGeorge Mount    public static void setDrawableEnd(TextView view, Drawable drawable) {
1873561e3e665698843b1c664385a842e779198960bGeorge Mount        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
1883561e3e665698843b1c664385a842e779198960bGeorge Mount            setDrawableRight(view, drawable);
1893561e3e665698843b1c664385a842e779198960bGeorge Mount        } else {
19043af89d9798bf5d3f2fccaf0ed38735407b06b10George Mount            setIntrinsicBounds(drawable);
1913561e3e665698843b1c664385a842e779198960bGeorge Mount            Drawable[] drawables = view.getCompoundDrawablesRelative();
19271eb6908f2689bd17000237eb645896c36da0138George Mount            view.setCompoundDrawablesRelative(drawables[0], drawables[1], drawable, drawables[3]);
1933561e3e665698843b1c664385a842e779198960bGeorge Mount        }
1943561e3e665698843b1c664385a842e779198960bGeorge Mount    }
1953561e3e665698843b1c664385a842e779198960bGeorge Mount
19610960eb5f73fd587c2f8d18cfc61873c04017512George Mount    @BindingAdapter({"android:imeActionLabel"})
1973561e3e665698843b1c664385a842e779198960bGeorge Mount    public static void setImeActionLabel(TextView view, CharSequence value) {
1983561e3e665698843b1c664385a842e779198960bGeorge Mount        view.setImeActionLabel(value, view.getImeActionId());
1993561e3e665698843b1c664385a842e779198960bGeorge Mount    }
2003561e3e665698843b1c664385a842e779198960bGeorge Mount
20110960eb5f73fd587c2f8d18cfc61873c04017512George Mount    @BindingAdapter({"android:imeActionId"})
2023561e3e665698843b1c664385a842e779198960bGeorge Mount    public static void setImeActionLabel(TextView view, int value) {
2033561e3e665698843b1c664385a842e779198960bGeorge Mount        view.setImeActionLabel(view.getImeActionLabel(), value);
2043561e3e665698843b1c664385a842e779198960bGeorge Mount    }
2053561e3e665698843b1c664385a842e779198960bGeorge Mount
20610960eb5f73fd587c2f8d18cfc61873c04017512George Mount    @BindingAdapter({"android:inputMethod"})
2073561e3e665698843b1c664385a842e779198960bGeorge Mount    public static void setInputMethod(TextView view, CharSequence inputMethod) {
2083561e3e665698843b1c664385a842e779198960bGeorge Mount        try {
2093561e3e665698843b1c664385a842e779198960bGeorge Mount            Class<?> c = Class.forName(inputMethod.toString());
2103561e3e665698843b1c664385a842e779198960bGeorge Mount            view.setKeyListener((KeyListener) c.newInstance());
2113561e3e665698843b1c664385a842e779198960bGeorge Mount        } catch (ClassNotFoundException e) {
2123561e3e665698843b1c664385a842e779198960bGeorge Mount            Log.e(TAG, "Could not create input method: " + inputMethod, e);
2133561e3e665698843b1c664385a842e779198960bGeorge Mount        } catch (InstantiationException e) {
2143561e3e665698843b1c664385a842e779198960bGeorge Mount            Log.e(TAG, "Could not create input method: " + inputMethod, e);
2153561e3e665698843b1c664385a842e779198960bGeorge Mount        } catch (IllegalAccessException e) {
2163561e3e665698843b1c664385a842e779198960bGeorge Mount            Log.e(TAG, "Could not create input method: " + inputMethod, e);
2173561e3e665698843b1c664385a842e779198960bGeorge Mount        }
2183561e3e665698843b1c664385a842e779198960bGeorge Mount    }
2193561e3e665698843b1c664385a842e779198960bGeorge Mount
22010960eb5f73fd587c2f8d18cfc61873c04017512George Mount    @BindingAdapter({"android:lineSpacingExtra"})
2213561e3e665698843b1c664385a842e779198960bGeorge Mount    public static void setLineSpacingExtra(TextView view, float value) {
2223561e3e665698843b1c664385a842e779198960bGeorge Mount        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
2233561e3e665698843b1c664385a842e779198960bGeorge Mount            view.setLineSpacing(value, view.getLineSpacingMultiplier());
2243561e3e665698843b1c664385a842e779198960bGeorge Mount        } else {
2253561e3e665698843b1c664385a842e779198960bGeorge Mount            view.setLineSpacing(value, 1);
2263561e3e665698843b1c664385a842e779198960bGeorge Mount        }
2273561e3e665698843b1c664385a842e779198960bGeorge Mount    }
2283561e3e665698843b1c664385a842e779198960bGeorge Mount
22910960eb5f73fd587c2f8d18cfc61873c04017512George Mount    @BindingAdapter({"android:lineSpacingMultiplier"})
2303561e3e665698843b1c664385a842e779198960bGeorge Mount    public static void setLineSpacingMultiplier(TextView view, float value) {
2313561e3e665698843b1c664385a842e779198960bGeorge Mount        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
2323561e3e665698843b1c664385a842e779198960bGeorge Mount            view.setLineSpacing(view.getLineSpacingExtra(), value);
2333561e3e665698843b1c664385a842e779198960bGeorge Mount        } else {
2343561e3e665698843b1c664385a842e779198960bGeorge Mount            view.setLineSpacing(0, value);
2353561e3e665698843b1c664385a842e779198960bGeorge Mount        }
2363561e3e665698843b1c664385a842e779198960bGeorge Mount    }
2373561e3e665698843b1c664385a842e779198960bGeorge Mount
23810960eb5f73fd587c2f8d18cfc61873c04017512George Mount    @BindingAdapter({"android:maxLength"})
2393561e3e665698843b1c664385a842e779198960bGeorge Mount    public static void setMaxLength(TextView view, int value) {
2403561e3e665698843b1c664385a842e779198960bGeorge Mount        InputFilter[] filters = view.getFilters();
2413561e3e665698843b1c664385a842e779198960bGeorge Mount        if (filters == null) {
2423561e3e665698843b1c664385a842e779198960bGeorge Mount            filters = new InputFilter[]{
2433561e3e665698843b1c664385a842e779198960bGeorge Mount                    new InputFilter.LengthFilter(value)
2443561e3e665698843b1c664385a842e779198960bGeorge Mount            };
2453561e3e665698843b1c664385a842e779198960bGeorge Mount        } else {
2463561e3e665698843b1c664385a842e779198960bGeorge Mount            boolean foundMaxLength = false;
2473561e3e665698843b1c664385a842e779198960bGeorge Mount            for (int i = 0; i < filters.length; i++) {
2483561e3e665698843b1c664385a842e779198960bGeorge Mount                InputFilter filter = filters[i];
2493561e3e665698843b1c664385a842e779198960bGeorge Mount                if (filter instanceof InputFilter.LengthFilter) {
2503561e3e665698843b1c664385a842e779198960bGeorge Mount                    foundMaxLength = true;
2513561e3e665698843b1c664385a842e779198960bGeorge Mount                    boolean replace = true;
2523561e3e665698843b1c664385a842e779198960bGeorge Mount                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
2533561e3e665698843b1c664385a842e779198960bGeorge Mount                        replace = ((InputFilter.LengthFilter) filter).getMax() != value;
2543561e3e665698843b1c664385a842e779198960bGeorge Mount                    }
2553561e3e665698843b1c664385a842e779198960bGeorge Mount                    if (replace) {
2563561e3e665698843b1c664385a842e779198960bGeorge Mount                        filters[i] = new InputFilter.LengthFilter(value);
2573561e3e665698843b1c664385a842e779198960bGeorge Mount                    }
2583561e3e665698843b1c664385a842e779198960bGeorge Mount                    break;
2593561e3e665698843b1c664385a842e779198960bGeorge Mount                }
2603561e3e665698843b1c664385a842e779198960bGeorge Mount            }
2613561e3e665698843b1c664385a842e779198960bGeorge Mount            if (!foundMaxLength) {
2623561e3e665698843b1c664385a842e779198960bGeorge Mount                // can't use Arrays.copyOf -- it shows up in API 9
2633561e3e665698843b1c664385a842e779198960bGeorge Mount                InputFilter[] oldFilters = filters;
2643561e3e665698843b1c664385a842e779198960bGeorge Mount                filters = new InputFilter[oldFilters.length + 1];
2653561e3e665698843b1c664385a842e779198960bGeorge Mount                System.arraycopy(oldFilters, 0, filters, 0, oldFilters.length);
2663561e3e665698843b1c664385a842e779198960bGeorge Mount                filters[filters.length - 1] = new InputFilter.LengthFilter(value);
2673561e3e665698843b1c664385a842e779198960bGeorge Mount            }
2683561e3e665698843b1c664385a842e779198960bGeorge Mount        }
2693561e3e665698843b1c664385a842e779198960bGeorge Mount        view.setFilters(filters);
2703561e3e665698843b1c664385a842e779198960bGeorge Mount    }
2713561e3e665698843b1c664385a842e779198960bGeorge Mount
27210960eb5f73fd587c2f8d18cfc61873c04017512George Mount    @BindingAdapter({"android:password"})
2733561e3e665698843b1c664385a842e779198960bGeorge Mount    public static void setPassword(TextView view, boolean password) {
2743561e3e665698843b1c664385a842e779198960bGeorge Mount        if (password) {
2753561e3e665698843b1c664385a842e779198960bGeorge Mount            view.setTransformationMethod(PasswordTransformationMethod.getInstance());
2763561e3e665698843b1c664385a842e779198960bGeorge Mount        } else if (view.getTransformationMethod() instanceof PasswordTransformationMethod) {
2773561e3e665698843b1c664385a842e779198960bGeorge Mount            view.setTransformationMethod(null);
2783561e3e665698843b1c664385a842e779198960bGeorge Mount        }
2793561e3e665698843b1c664385a842e779198960bGeorge Mount    }
2803561e3e665698843b1c664385a842e779198960bGeorge Mount
28110960eb5f73fd587c2f8d18cfc61873c04017512George Mount    @BindingAdapter({"android:shadowColor"})
2823561e3e665698843b1c664385a842e779198960bGeorge Mount    public static void setShadowColor(TextView view, int color) {
2833561e3e665698843b1c664385a842e779198960bGeorge Mount        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
2843561e3e665698843b1c664385a842e779198960bGeorge Mount            float dx = view.getShadowDx();
2853561e3e665698843b1c664385a842e779198960bGeorge Mount            float dy = view.getShadowDy();
2863561e3e665698843b1c664385a842e779198960bGeorge Mount            float r = view.getShadowRadius();
2873561e3e665698843b1c664385a842e779198960bGeorge Mount            view.setShadowLayer(r, dx, dy, color);
2883561e3e665698843b1c664385a842e779198960bGeorge Mount        }
2893561e3e665698843b1c664385a842e779198960bGeorge Mount    }
2903561e3e665698843b1c664385a842e779198960bGeorge Mount
29110960eb5f73fd587c2f8d18cfc61873c04017512George Mount    @BindingAdapter({"android:shadowDx"})
2923561e3e665698843b1c664385a842e779198960bGeorge Mount    public static void setShadowDx(TextView view, float dx) {
2933561e3e665698843b1c664385a842e779198960bGeorge Mount        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
2943561e3e665698843b1c664385a842e779198960bGeorge Mount            int color = view.getShadowColor();
2953561e3e665698843b1c664385a842e779198960bGeorge Mount            float dy = view.getShadowDy();
2963561e3e665698843b1c664385a842e779198960bGeorge Mount            float r = view.getShadowRadius();
2973561e3e665698843b1c664385a842e779198960bGeorge Mount            view.setShadowLayer(r, dx, dy, color);
2983561e3e665698843b1c664385a842e779198960bGeorge Mount        }
2993561e3e665698843b1c664385a842e779198960bGeorge Mount    }
3003561e3e665698843b1c664385a842e779198960bGeorge Mount
30110960eb5f73fd587c2f8d18cfc61873c04017512George Mount    @BindingAdapter({"android:shadowDy"})
3023561e3e665698843b1c664385a842e779198960bGeorge Mount    public static void setShadowDy(TextView view, float dy) {
3033561e3e665698843b1c664385a842e779198960bGeorge Mount        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
3043561e3e665698843b1c664385a842e779198960bGeorge Mount            int color = view.getShadowColor();
3053561e3e665698843b1c664385a842e779198960bGeorge Mount            float dx = view.getShadowDx();
3063561e3e665698843b1c664385a842e779198960bGeorge Mount            float r = view.getShadowRadius();
3073561e3e665698843b1c664385a842e779198960bGeorge Mount            view.setShadowLayer(r, dx, dy, color);
3083561e3e665698843b1c664385a842e779198960bGeorge Mount        }
3093561e3e665698843b1c664385a842e779198960bGeorge Mount    }
3103561e3e665698843b1c664385a842e779198960bGeorge Mount
31110960eb5f73fd587c2f8d18cfc61873c04017512George Mount    @BindingAdapter({"android:shadowRadius"})
3123561e3e665698843b1c664385a842e779198960bGeorge Mount    public static void setShadowRadius(TextView view, float r) {
3133561e3e665698843b1c664385a842e779198960bGeorge Mount        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
3143561e3e665698843b1c664385a842e779198960bGeorge Mount            int color = view.getShadowColor();
3153561e3e665698843b1c664385a842e779198960bGeorge Mount            float dx = view.getShadowDx();
3163561e3e665698843b1c664385a842e779198960bGeorge Mount            float dy = view.getShadowDy();
3173561e3e665698843b1c664385a842e779198960bGeorge Mount            view.setShadowLayer(r, dx, dy, color);
3183561e3e665698843b1c664385a842e779198960bGeorge Mount        }
3193561e3e665698843b1c664385a842e779198960bGeorge Mount    }
3203561e3e665698843b1c664385a842e779198960bGeorge Mount
32110960eb5f73fd587c2f8d18cfc61873c04017512George Mount    @BindingAdapter({"android:textSize"})
3223561e3e665698843b1c664385a842e779198960bGeorge Mount    public static void setTextSize(TextView view, float size) {
3233561e3e665698843b1c664385a842e779198960bGeorge Mount        view.setTextSize(TypedValue.COMPLEX_UNIT_PX, size);
3243561e3e665698843b1c664385a842e779198960bGeorge Mount    }
325716ba89e7f459f49ea85070d4710c1d79d715298George Mount
3263b920788e90bb0abe615a5d5c899915f0014444bGeorge Mount    private static boolean haveContentsChanged(CharSequence str1, CharSequence str2) {
3273b920788e90bb0abe615a5d5c899915f0014444bGeorge Mount        if ((str1 == null) != (str2 == null)) {
3283b920788e90bb0abe615a5d5c899915f0014444bGeorge Mount            return true;
3293b920788e90bb0abe615a5d5c899915f0014444bGeorge Mount        } else if (str1 == null) {
3303b920788e90bb0abe615a5d5c899915f0014444bGeorge Mount            return false;
3313b920788e90bb0abe615a5d5c899915f0014444bGeorge Mount        }
3323b920788e90bb0abe615a5d5c899915f0014444bGeorge Mount        final int length = str1.length();
3333b920788e90bb0abe615a5d5c899915f0014444bGeorge Mount        if (length != str2.length()) {
3343b920788e90bb0abe615a5d5c899915f0014444bGeorge Mount            return true;
3353b920788e90bb0abe615a5d5c899915f0014444bGeorge Mount        }
3363b920788e90bb0abe615a5d5c899915f0014444bGeorge Mount        for (int i = 0; i < length; i++) {
3373b920788e90bb0abe615a5d5c899915f0014444bGeorge Mount            if (str1.charAt(i) != str2.charAt(i)) {
3383b920788e90bb0abe615a5d5c899915f0014444bGeorge Mount                return true;
3393b920788e90bb0abe615a5d5c899915f0014444bGeorge Mount            }
3403b920788e90bb0abe615a5d5c899915f0014444bGeorge Mount        }
3413b920788e90bb0abe615a5d5c899915f0014444bGeorge Mount        return false;
3423b920788e90bb0abe615a5d5c899915f0014444bGeorge Mount    }
3433b920788e90bb0abe615a5d5c899915f0014444bGeorge Mount
34496b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount    @BindingAdapter(value = {"android:beforeTextChanged", "android:onTextChanged",
3453b920788e90bb0abe615a5d5c899915f0014444bGeorge Mount            "android:afterTextChanged", "android:textAttrChanged"}, requireAll = false)
34696b22e7bbbf942aea1079dc8e8d0c4657663e5a7George Mount    public static void setTextWatcher(TextView view, final BeforeTextChanged before,
3473b920788e90bb0abe615a5d5c899915f0014444bGeorge Mount            final OnTextChanged on, final AfterTextChanged after,
3483b920788e90bb0abe615a5d5c899915f0014444bGeorge Mount            final InverseBindingListener textAttrChanged) {
349716ba89e7f459f49ea85070d4710c1d79d715298George Mount        final TextWatcher newValue;
3503b920788e90bb0abe615a5d5c899915f0014444bGeorge Mount        if (before == null && after == null && on == null && textAttrChanged == null) {
351716ba89e7f459f49ea85070d4710c1d79d715298George Mount            newValue = null;
352716ba89e7f459f49ea85070d4710c1d79d715298George Mount        } else {
353716ba89e7f459f49ea85070d4710c1d79d715298George Mount            newValue = new TextWatcher() {
354716ba89e7f459f49ea85070d4710c1d79d715298George Mount                @Override
355716ba89e7f459f49ea85070d4710c1d79d715298George Mount                public void beforeTextChanged(CharSequence s, int start, int count, int after) {
356716ba89e7f459f49ea85070d4710c1d79d715298George Mount                    if (before != null) {
357716ba89e7f459f49ea85070d4710c1d79d715298George Mount                        before.beforeTextChanged(s, start, count, after);
358716ba89e7f459f49ea85070d4710c1d79d715298George Mount                    }
359716ba89e7f459f49ea85070d4710c1d79d715298George Mount                }
360716ba89e7f459f49ea85070d4710c1d79d715298George Mount
361716ba89e7f459f49ea85070d4710c1d79d715298George Mount                @Override
362716ba89e7f459f49ea85070d4710c1d79d715298George Mount                public void onTextChanged(CharSequence s, int start, int before, int count) {
363716ba89e7f459f49ea85070d4710c1d79d715298George Mount                    if (on != null) {
364716ba89e7f459f49ea85070d4710c1d79d715298George Mount                        on.onTextChanged(s, start, before, count);
365716ba89e7f459f49ea85070d4710c1d79d715298George Mount                    }
3663b920788e90bb0abe615a5d5c899915f0014444bGeorge Mount                    if (textAttrChanged != null) {
3673b920788e90bb0abe615a5d5c899915f0014444bGeorge Mount                        textAttrChanged.onChange();
3683b920788e90bb0abe615a5d5c899915f0014444bGeorge Mount                    }
369716ba89e7f459f49ea85070d4710c1d79d715298George Mount                }
370716ba89e7f459f49ea85070d4710c1d79d715298George Mount
371716ba89e7f459f49ea85070d4710c1d79d715298George Mount                @Override
372716ba89e7f459f49ea85070d4710c1d79d715298George Mount                public void afterTextChanged(Editable s) {
373716ba89e7f459f49ea85070d4710c1d79d715298George Mount                    if (after != null) {
374716ba89e7f459f49ea85070d4710c1d79d715298George Mount                        after.afterTextChanged(s);
375716ba89e7f459f49ea85070d4710c1d79d715298George Mount                    }
376716ba89e7f459f49ea85070d4710c1d79d715298George Mount                }
377716ba89e7f459f49ea85070d4710c1d79d715298George Mount            };
378716ba89e7f459f49ea85070d4710c1d79d715298George Mount        }
379716ba89e7f459f49ea85070d4710c1d79d715298George Mount        final TextWatcher oldValue = ListenerUtil.trackListener(view, newValue, R.id.textWatcher);
380716ba89e7f459f49ea85070d4710c1d79d715298George Mount        if (oldValue != null) {
381716ba89e7f459f49ea85070d4710c1d79d715298George Mount            view.removeTextChangedListener(oldValue);
382716ba89e7f459f49ea85070d4710c1d79d715298George Mount        }
383716ba89e7f459f49ea85070d4710c1d79d715298George Mount        if (newValue != null) {
384716ba89e7f459f49ea85070d4710c1d79d715298George Mount            view.addTextChangedListener(newValue);
385716ba89e7f459f49ea85070d4710c1d79d715298George Mount        }
386716ba89e7f459f49ea85070d4710c1d79d715298George Mount    }
387716ba89e7f459f49ea85070d4710c1d79d715298George Mount
388716ba89e7f459f49ea85070d4710c1d79d715298George Mount    public interface AfterTextChanged {
389716ba89e7f459f49ea85070d4710c1d79d715298George Mount        void afterTextChanged(Editable s);
390716ba89e7f459f49ea85070d4710c1d79d715298George Mount    }
391716ba89e7f459f49ea85070d4710c1d79d715298George Mount
392716ba89e7f459f49ea85070d4710c1d79d715298George Mount    public interface BeforeTextChanged {
393716ba89e7f459f49ea85070d4710c1d79d715298George Mount        void beforeTextChanged(CharSequence s, int start, int count, int after);
394716ba89e7f459f49ea85070d4710c1d79d715298George Mount    }
395716ba89e7f459f49ea85070d4710c1d79d715298George Mount
396716ba89e7f459f49ea85070d4710c1d79d715298George Mount    public interface OnTextChanged {
397716ba89e7f459f49ea85070d4710c1d79d715298George Mount        void onTextChanged(CharSequence s, int start, int before, int count);
398716ba89e7f459f49ea85070d4710c1d79d715298George Mount    }
3993561e3e665698843b1c664385a842e779198960bGeorge Mount}
400