Slide 1

Slide 1 text

Advanced Data Binding kyobashi.dex #3 @kgmyshin

Slide 2

Slide 2 text

໨࣍ • ૒ํ޲Binding • ϝιουϦϑΝϨϯε • ϥϜμࣜ

Slide 3

Slide 3 text

هࣄ΋͋Γ·͢ https://tech.recruit-mp.co.jp/event/post-10069/

Slide 4

Slide 4 text

هࣄ΋͋Γ·͕͢ • هࣄ͸Google IO 2016ͷʮAdvanced Data BindingʯͷηογϣϯΛฉ͍ͨ··จࣈى͜ ͨ͠͠΋ͷ • ͜ͷLTͰ͸ηογϣϯΛฉ͍ͨޙʹࣗ෼Ͱࢼ ͨ͠ײ৮΍ੜ੒͞ΕΔϑΝΠϧͳͲ͔Βݟ͑ ͨ࢓૊ΈͳͲʹॏ͖Λஔ͖͍ͨͱࢥ͍·͢

Slide 5

Slide 5 text

ಈը΋ެ։͞Εͯ͠·ͬͨ https://www.youtube.com/watch?v=DAmMN7m3wLU

Slide 6

Slide 6 text

૒ํ޲ Binding

Slide 7

Slide 7 text

૒ํ޲Binding • ࠓ·ͰΰϦΰϦॻ͔ͳ͚Ε͹ͳΒͳ͔ͬͨ૒ํ޲ Binding͕ҰߦͰॻ͚ΔΑ͏ʹͳͬͨɻ

Slide 8

Slide 8 text

࢓૊Έ(1) // ࣗಈੜ੒͞ΕΔ private InverseBindingListener editTextandroidTextA = new InverseBindingListener() { @Override public void onChange() { String callbackArg_0 = android.databinding.adapters.TextViewBindingAdapter.getTextString(editText); String nameUser = null; User user = mUser; if (user != null) { user.setName(callbackArg_0); } } }; • ಺෦ͰInverseBindingListenerΛ࡞੒

Slide 9

Slide 9 text

࢓૊Έ(2) // ϑϨʔϜϫʔΫ಺ @BindingAdapter(value = {"android:beforeTextChanged", "android:onTextChanged", "android:afterTextChanged", "android:textAttrChanged"}, requireAll = false) public static void setTextWatcher(TextView view, --- , final InverseBindingListener textAttrChanged) { final TextWatcher newValue; if (before == null && after == null && on == null && textAttrChanged == null) { newValue = null; } else { newValue = new TextWatcher() { @Override public void onTextChanged(CharSequence s, int start, int before, int count) { if (on != null) { on.onTextChanged(s, start, before, count); } if (textAttrChanged != null) { textAttrChanged.onChange(); } } : }; } if (newValue != null) { view.addTextChangedListener(newValue); } } • Ϧεφʔ͕ηοτ͞ΕΔɻ

Slide 10

Slide 10 text

࢓૊Έ(3) // ϑϨʔϜϫʔΫ಺ @BindingAdapter("android:text") public static void setText(TextView view, CharSequence text) { final CharSequence oldText = view.getText(); if (text == oldText || (text == null && oldText.length() == 0)) { return; } if (text instanceof Spanned) { if (text.equals(oldText)) { return; // No change in the spans, so don't set anything. } } else if (!haveContentsChanged(text, oldText)) { return; // No content changes, so don't set anything. } view.setText(text); } • ແݶϧʔϓ͠ͳ͍Α͏ʹɺoldTextͱ৽͍͠஋ Λ֬ೝ͍ͯ͠Δɻ

Slide 11

Slide 11 text

ࣗ࡞BindingAdapterͰ૒ํ޲ͯ͠ΈΔ • ·ͣ͸͍ͭ΋௨ΓBindingAdapterΛ࡞੒ɻ • ࣮͸͜Ε͸NGɻແݶϧʔϓͯ͠͠·͏ɻsetDateText ͕ݺ͹ΕͯɺsetCreatedAt͕ݺ͹ΕͯɺsetDateText ͕ݺ͹ΕͯɺsetCreatedAt͕ݺ͹Εͯɺɺɺ @BindingAdapter("dateText") public static void setDateText(EditText editText, long date) { editText.setText(String.valueOf(date)); }

Slide 12

Slide 12 text

৽͍͠஋ͱݹ͍஋Λ֬ೝ • ಉ͡஋ͳΒset͠ͳ͍Α͏ʹ͢Δ @BindingAdapter("dateText") public static void setDateText(EditText editText, long date) { String oldValue = view.getText().toString(); String newValue = String.valueOf(date); if (oldValue.equals(newValue)) { return; // ಉ͡஋ͳΒset͠ͳ͍Α͏ʹ͢Δɻ } editText.setText(newValue); }

Slide 13

Slide 13 text

InverseBindingAdapterΛ࡞੒͢Δ • InverseBindingAdapterΛ࡞੒͢Δ • ͜ΕΛ΋ͱʹ InverseBindingListener ͕ࣗಈੜ੒͞ ΕΔ @InverseBindingAdapter(attribute = "dateText", event = "android:textAttrChanged") public static long getDateText(EditText view) { String text = view.getText().toString(); return Long.parseLong(text); }

Slide 14

Slide 14 text

͜ΕͰ૒ํ޲Bindingͷ׬੒ public class User extends BaseObservable { @Bindable private long createdAt; : public long getCreatedAt() { return createdAt; } public void setCreatedAt(long createdAt) { this.createdAt = createdAt; notifyPropertyChanged(BR.createdAt); }

Slide 15

Slide 15 text

ϝιουϦϑΝϨϯε

Slide 16

Slide 16 text

ϝιουϦϑΝϨϯε • onClick΍onLongClickʹؔ਺ΛࢦఆͰ͖ΔΑ͏ ʹͳͬͨɻ

Slide 17

Slide 17 text

ͲͷΠϕϯτʹରԠ͍ͯ͠Δ͔ android:onDrag android:onClick android:onApplyWindowInsets android:onCreateContextMenu android:onFocusChange android:onGenericMotion android:onHover android:onKey android:onLongClick android:onSystemUiVisibilityChange android:onTouch • ͪΐͬͱυΩϡϝϯτ͕ݟ౰ͨΒͳ͔͕ͬͨ android.databinding.adapters.ViewBindingAdapterΛݟͨײ͡ɺView ʹݶͬͯ͸ԼهͷΠϕϯτʹରԠ͍ͯ͠Δ͜ͱ͕Θ͔Δɻ

Slide 18

Slide 18 text

• ଞʹ΋͍Ζ͍Ζ͋Γͦ͏ɻ • ͨͩશ෦Ͱ͸ͳ͍ͱݴ͍ͬͯͨɻ

Slide 19

Slide 19 text

ϝιουϦϑΝϨϯεͰࢦఆ͢ Δϝιου @BindingMethod(type = View.class, attribute = "android:onClick", method = "setOnClickListener"), • ಺෦ͰԼهͷΑ͏ʹఆٛ͞Ε͍ͯΔɻ • methodͷฦΓ஋ͱҾ਺(+ view)ʹ߹ΘͤΔඞཁ ͕͋Δɻ

Slide 20

Slide 20 text

࢓૊Έ public static class OnLongClickListenerI implements OnLongClickListener{ private Presenter value; public OnLongClickListenerI setValue(com.kgmyshin.databindingsample.Presenter value) { this.value = value; return value == null ? null : this; } @Override public boolean onLongClick(View arg0) { return this.value.onLongClickButton1(arg0); } } : private OnLongClickListenerI mAndroidViewViewOnLo; : this.button1.setOnLongClickListener(mAndroidViewViewOnLo); : • ListenerΛࣗಈੜ੒ͯ͠set͍ͯ͠Δ͚ͩɻ

Slide 21

Slide 21 text

ͪΐͬͱ·ͩόΪʔ • ؔ਺ͷͱ͜ΖͰ੺ઢͰΔ͠ɺonLongClick͸࣮ࡍ ʹ͸͋Δ͠ಈ͘ͷʹʮͦΜͳͷ஌Βͳ͍ʯͬͯݴ ΘΕΔɻ

Slide 22

Slide 22 text

ϥϜμࣜ

Slide 23

Slide 23 text

ϥϜμࣜ • onClick΍onLongClickʹϥϜμࣜΛࢦఆͰ͖Δ Α͏ʹͳͬͨɻ

Slide 24

Slide 24 text

ϥϜμࣜͰࢦఆ͢Δϝιου @BindingMethod(type = View.class, attribute = "android:onFocusChange", method = "setOnFocusChangeListener"), • ϝιουϦϑΝϨϯεಉ༷ • methodͷฦΓ஋ͱҾ਺(+ view)ʹ߹ΘͤΔඞཁ ͕͋Δɻ

Slide 25

Slide 25 text

͜Μͳײ͡ View.OnFocusChangeListener() { public void onFocusChange(View v, boolean hasFocus) { : } }

Slide 26

Slide 26 text

ϥϜμࣜͰࢦఆ͢Δϝιου • ϥϜμࣜͷ৔߹͚ͩҾ਺ΛলུͰ͖Δ(Ұ෦লུͱ͍͏ͷ͸Ͱ͖ͳ͍) presenter.showToast(user.name)}" />

Slide 27

Slide 27 text

࢓૊Έ public final void _internalCallbackOnClick(int sourceId , android.view.View callbackArg_0) { com.kgmyshin.databindingsample.User user = mUser; com.kgmyshin.databindingsample.Presenter presenter = mPresenter; if (mPresenter != null) { if (mUser != null) { nameUser = user.getName(); presenter.showToast(nameUser); } } } • ී௨ͷjava͕ੜ੒͞ΕΔɻ

Slide 28

Slide 28 text

Ҏ্Ͱ͢