Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
双方向DataBinding
Search
takaaki7
July 15, 2016
Technology
1
1.2k
双方向DataBinding
shibuya.apk #9 2016/07/15
takaaki7
July 15, 2016
Tweet
Share
Other Decks in Technology
See All in Technology
dbtとBigQuery MLで実現する リクルートの営業支援基盤のモデル開発と保守運用
recruitengineers
PRO
3
100
CoRL 2025 Survey
harukiabe
1
210
LLMアプリの地上戦開発計画と運用実践 / 2025.10.15 GPU UNITE 2025
smiyawaki0820
1
630
ソースを読むプロセスの例
sat
PRO
15
9.2k
Geospatialの世界最前線を探る [2025年版]
dayjournal
1
230
Wasmのエコシステムを使った ツール作成方法
askua
0
210
いまからでも遅くない!SSL/TLS証明書超入門(It's not too late to start! SSL/TLS Certificates: The Absolute Beginner's Guide)
norimuraz
0
270
AWS Top Engineer、浮いてませんか? / As an AWS Top Engineer, Are You Out of Place?
yuj1osm
2
220
20251014_Pythonを実務で徹底的に使いこなした話
ippei0923
0
210
All About Sansan – for New Global Engineers
sansan33
PRO
1
1.2k
Performance Insights 廃止から Database Insights 利用へ/transition-from-performance-insights-to-database-insights
emiki
0
300
それでも私が品質保証プロセスを作り続ける理由 #テストラジオ / Why I still continue to create QA process
pineapplecandy
0
130
Featured
See All Featured
XXLCSS - How to scale CSS and keep your sanity
sugarenia
248
1.3M
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
48
9.7k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
33
2.5k
Done Done
chrislema
185
16k
Code Review Best Practice
trishagee
72
19k
Scaling GitHub
holman
463
140k
Learning to Love Humans: Emotional Interface Design
aarron
274
41k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
30
2.9k
How to train your dragon (web standard)
notwaldorf
97
6.3k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
37
2.6k
Git: the NoSQL Database
bkeepers
PRO
431
66k
Statistics for Hackers
jakevdp
799
220k
Transcript
ํDataBinding 2016/07/15 @tnakama7 shibuya.apk #9
DataBinding <layout> <data> <variable name="user" type="com.example.User"/> </data> <LinearLayout …> <TextView
android:text="@{user.name}" …/> </LinearLayout> </layout> public class User { public final ObservableField<String> name = new ObservableField<String>(); }
MVVM • Model-View-ViewModel • ViewModel: ViewΛඳը͢ΔͨΊͷঢ়ଶͷอ࣋ͱɺ View͔Βड͚औͬͨೖྗΛదͳܗʹมͯ͠Model ʹୡ͢ΔΛ࣋ͭɻ(Wikipedia)
ํ(2-way)DataBinding • ී௨ͷDataBindingɿ ViewModelͷΛมߋ͢Δ -> ViewʹࣗಈͰө͞ΕͯΔʂ • ํDataBindingɿ ී௨ͷόΠϯσΟϯάʹՃ͑ͯɺ Ϣʔβ͕View͔Βೖྗ
-> ࣗಈͰViewModelʹ͕ηοτ ͞ΕͯΔʂ
AndroidͷํDataBinding • https://halfthought.wordpress.com/2016/03/23/2- way-data-binding-on-android/ • Android Studio 2.1 • gradle
2.1.0
@={vm.name}
ྫ: EditText (TextView) <variable type="com.example.app.SignUpViewModel" name="viewModel"/> <EditText android:text="@={viewModel.name}" …/> <Button
android:enabled="@{viewModel.btnEnabled}" …/> public class SignUpViewModel extends BaseObservable { @Bindable private String name; public boolean getBtnEnabled() { return !TextUtils.isEmpty(name); } public String getName() { return name; } public void setName() { this.name = name; notifyPropertyChanged(BR.name); notifyPropertyChanged(BR.btnEnabled); } … }
RadioGroup <RadioGroup android:checkedButton="@={viewModel.gender}" …> <RadioButton android:id="@+id/male" …/> <RadioButton android:id="@+id/female" …/>
</RadioGroup> public class SignUpViewModel{ public final ObservableInt gender = new ObservableInt(); ... }
ࣗͰͰ͖Δ͠
ࣗͰΖ͏ͱ͢Δ public class SignUpViewModel extends BaseObservable{ @Bindable public String getName()
{ return name; } public void setName(String name) { this.name = name; notifyPropertyChanged(BR.name); } // Ͳ͔͜ͰnameEditTextʹηοτ͢Δ public SimpleTextWatcher nameWatcher = new SimpleTextWatcher() { @Override public void onTextChanged(String value) { setName(value); } }; /*……*/ }
ແݶϧʔϓൃੜͯ͠͠·͏ͷͰ ੍ޚ͢Δॲཧ͕ඞཁ public void setName(String name) { this.name = name;
if (!isEditMode) { notifyPropertyChanged(BR.name); } } public SimpleTextWatcher firstNameWatcher = new SimpleTextWatcher() { @Override public void onTextChanged(String value) { isEditMode = true; setName(value); isEditMode = false; } };
ଞͷView
• AbsListView android:selectedItemPosition • CalendarView android:date • CompoundButton android:checked •
DatePicker android:year, android:month, android:day • NumberPicker android:value • RatingBar android:rating • SeekBar android:progress • TabHost android:currentTab • TimePicker android:hour, android:minute
@InverseBindingMethods({ @InverseBindingMethod(type = ColorPicker.class, attribute = "color"), }) public class
ColorPicker extends View { public void setColor(int color) { /* ... */ } public int getColor() { /* ... */ } public interface OnColorChangeListener { void onColorChange(ColorPicker view, int color); } @BindingAdapter("colorAttrChanged") public static void setColorListener(ColorPicker view, final InverseBindingListener lister) { if (colorChange == null) { view.setOnColorChangeListener(null); } else { view.setOnColorChangeListener((view1, color) -> lister.onChange()); } } } <ColorPicker app:color="@={viewModel.myColor}" …/> ࣗ࡞View
ςετ @RunWith(JUnit4.class) public class SignUpViewModelTest { private SignUpViewModel viewModel;
@Before public void setUp() { viewModel = new SignUpViewModel(null); } @Test public void setNames_FullNameIsCorrect() { viewModel.setFirstName("ࢁా"); //@BindableʹΑΔϑΟʔϧυOK viewModel.lastName.set("ଠ"); //ObservableFieldOK assertEquals(viewModel.getFullName(), "ࢁాଠ"); } }
ݒ೦(ํʹݶΒͣ) • μΠΞϩάΛͬͨೖྗॲཧɺτʔετදࣔͷViewૢ ࡞ͷॲཧͳͲɺશͯͷUIϩδοΫʹ (ํʣDataBinding͕దͳΘ͚Ͱͳ͍ͷͰɺ֤ʑ Ͱॲཧͷॻ͖ํ͕·ͪ·ͪʹͳΓҰ؏ੑ͕ͳ͘Θ͔Γͮ Β͘ͳΔ͔ɻ • XMLʹ৭ʑॻ͖͗ͯ͢ͳΜͰಈ͍ͯΔ͔Θ͔Μͳ͍ •
IDEͷػೳඍົʹͳΔ
͜Μͳػೳ͔ͳ͍͔ͳ BDUJWJUZ@NBJOYNM &EJU5FYUɹ BOESPJEJE! JEBHF@FEJU BOESPJEUFYU!\WNBHF^ʜ
·ͱΊ • ํDataBinding: ViewModelΛมߋͨ͠ΒViewʹө͞ΕͯΔɻ Viewʹೖྗͨ͠ΒViewModelมߋ͞ΕͯΔɻ • <EditText android:text="@={vm.name}" />Ͱํό ΠϯσΟϯάͰ͖Δ
• DataBinding/MVVM͕͍͍ײ͡ʹͳΓͦ͏