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
Introduction to Bill One Development Engineer
sansan33
PRO
0
300
それでも私が品質保証プロセスを作り続ける理由 #テストラジオ / Why I still continue to create QA process
pineapplecandy
0
150
HR Force における DWH の併用事例 ~ サービス基盤としての BigQuery / 分析基盤としての Snowflake ~@Cross Data Platforms Meetup #2「BigQueryと愉快な仲間たち」
ryo_suzuki
0
250
ローカルLLMとLINE Botの組み合わせ その2(EVO-X2でgpt-oss-120bを利用) / LINE DC Generative AI Meetup #7
you
PRO
0
110
CoRL 2025 Survey
harukiabe
1
230
Digitization部 紹介資料
sansan33
PRO
1
5.6k
Liquid AI Hackathon Tokyo プレゼン資料
aratako
0
120
「最速」で Gemini CLI を使いこなそう! 〜Cloud Shell/Cloud Run の活用〜 / The Fastest Way to Master the Gemini CLI — with Cloud Shell and Cloud Run
aoto
PRO
0
130
WEBサービスを成り立たせるAWSサービス
takano0131
1
190
難しいセキュリティ用語をわかりやすくしてみた
yuta3110
0
340
Oracle Base Database Service 技術詳細
oracle4engineer
PRO
12
81k
AIとともに歩んでいくデザイナーの役割の変化
lycorptech_jp
PRO
0
640
Featured
See All Featured
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
36
6.1k
Raft: Consensus for Rubyists
vanstee
140
7.1k
The Cost Of JavaScript in 2023
addyosmani
55
9k
Typedesign – Prime Four
hannesfritz
42
2.8k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.5k
Documentation Writing (for coders)
carmenintech
75
5.1k
Making the Leap to Tech Lead
cromwellryan
135
9.6k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
31
9.7k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
4k
Scaling GitHub
holman
463
140k
Keith and Marios Guide to Fast Websites
keithpitt
411
23k
Visualization
eitanlees
149
16k
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͕͍͍ײ͡ʹͳΓͦ͏