原文地址:<%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20The%20user%20variable%20within%20data%20describes%20a%20property%20that%20may%20be%20used%20within%20this%20layout.%20%20%20Expressions%20within%20the%20layout%20are%20written%20in%20the%20attribute%20properties%20using%20the%20%22@%7B%7D%22%20syntax.%20Here,%20the%20TextView's%20text%20is%20set%20to%20the%20firstName%20property%20of%20user:%20%20%20Data%20Object%20Let's%20assume%20for%20now%20that%20you%20have%20a%20plain-old%20Java%20object%20(POJO)%20for%20User:%20%20public%20class%20User%20%7B%20%20%20%20public%20final%20String%20firstName;%20%20%20%20public%20final%20String%20lastName;%20%20%20%20public%20User(String%20firstName,%20String%20lastName)%20%7B%20%20%20%20%20%20%20%20this.firstName%20=%20firstName;%20%20%20%20%20%20%20%20this.lastName%20=%20lastName;%20%20%20%20%7D%20%7D%20This%20type%20of%20object%20has%20data%20that%20never%20changes.%20It%20is%20common%20in%20applications%20to%20have%20data%20that%20is%20read%20once%20and%20never%20changes%20thereafter.%20It%20is%20also%20possible%20to%20use%20a%20JavaBeans%20objects:%20%20public%20class%20User%20%7B%20%20%20%20private%20final%20String%20firstName;%20%20%20%20private%20final%20String%20lastName;%20%20%20%20public%20User(String%20firstName,%20String%20lastName)%20%7B%20%20%20%20%20%20%20%20this.firstName%20=%20firstName;%20%20%20%20%20%20%20%20this.lastName%20=%20lastName;%20%20%20%20%7D%20%20%20%20public%20String%20getFirstName()%20%7B%20%20%20%20%20%20%20%20return%20this.firstName;%20%20%20%20%7D%20%20%20%20public%20String%20getLastName()%20%7B%20%20%20%20%20%20%20%20return%20this.lastName;%20%20%20%20%7D%20%7D%20From%20the%20perspective%20of%20data%20binding,%20these%20two%20classes%20are%20equivalent.%20The%20expression%20@%7Buser.firstName%7D%20used%20for%20the%20TextView's%20android:text%20attribute%20will%20access%20the%20firstName%20field%20in%20the%20former%20class%20and%20the%20getFirstName()%20method%20in%20the%20latter%20class.%20Alternatively,%20it%20will%20also%20be%20resolved%20to%20firstName()%20if%20that%20method%20exists.%20%20Binding%20Data%20By%20default,%20a%20Binding%20class%20will%20be%20generated%20based%20on%20the%20name%20of%20the%20layout%20file,%20converting%20it%20to%20Pascal%20case%20and%20suffixing%20%22Binding%22%20to%20it.%20The%20above%20layout%20file%20was%20main_activity.xml%20so%20the%20generate%20class%20was%20MainActivityBinding.%20This%20class%20holds%20all%20the%20bindings%20from%20the%20layout%20properties%20(e.g.%20the%20user%20variable)%20to%20the%20layout's%20Views%20and%20knows%20how%20to%20assign%20values%20for%20the%20binding%20expressions.The%20easiest%20means%20for%20creating%20the%20bindings%20is%20to%20do%20it%20while%20inflating:%20%20@Override%20protected%20void%20onCreate(Bundle%20savedInstanceState)%20%7B%20%20%20%20super.onCreate(savedInstanceState);%20%20%20%20MainActivityBinding%20binding%20=%20DataBindingUtil.setContentView(this,%20R.layout.main_activity);%20%20%20%20User%20user%20=%20new%20User(%22Test%22,%20%22User%22);%20%20%20%20binding.setUser(user);%20%7D%20You're%20done!%20Run%20the%20application%20and%20you'll%20see%20Test%20User%20in%20the%20UI.%20Alternatively,%20you%20can%20get%20the%20view%20via:%20%20MainActivityBinding%20binding%20=%20MainActivityBinding.inflate(getLayoutInflater());%20If%20you%20are%20using%20data%20binding%20items%20inside%20a%20ListView%20or%20RecyclerView%20adapter,%20you%20may%20prefer%20to%20use:%20%20ListItemBinding%20binding%20=%20ListItemBinding.inflate(layoutInflater,%20viewGroup,%20false);%20/or%20ListItemBinding%20binding%20=%20DataBindingUtil.inflate(layoutInflater,%20R.layout.list_item,%20viewGroup,%20false);%20Event%20Handling%20Data%20Binding%20allows%20you%20to%20write%20expressions%20handling%20events%20that%20are%20dispatched%20from%20the%20views%20(e.g.%20onClick).%20Event%20attribute%20names%20are%20governed%20by%20the%20name%20of%20the%20listener%20method%20with%20a%20few%20exceptions.%20For%20example,%20View.OnLongClickListener%20has%20a%20method%20onLongClick(),%20so%20the%20attribute%20for%20this%20event%20is%20android:onLongClick.%20There%20are%20two%20ways%20to%20handle%20an%20event.%20%20Method%20References:%20In%20your%20expressions,%20you%20can%20reference%20methods%20that%20conform%20to%20the%20signature%20of%20the%20listener%20method.%20When%20an%20expression%20evaluates%20to%20a%20method%20reference,%20Data%20Binding%20wraps%20the%20method%20reference%20and%20owner%20object%20in%20a%20listener,%20and%20sets%20that%20listener%20on%20the%20target%20view.%20If%20the%20expression%20evaluates%20to%20null,%20Data%20Binding%20does%20not%20create%20a%20listener%20and%20sets%20a%20null%20listener%20instead.%20Listener%20Bindings:%20These%20are%20lambda%20expressions%20that%20are%20evaluated%20when%20the%20event%20happens.%20Data%20Binding%20always%20creates%20a%20listener,%20which%20it%20sets%20on%20the%20view.%20When%20the%20event%20is%20dispatched,%20the%20listener%20evaluates%20the%20lambda%20expression.%20Method%20References%20Events%20can%20be%20bound%20to%20handler%20methods%20directly,%20similar%20to%20the%20way%20android:onClick%20can%20be%20assigned%20to%20a%20method%20in%20an%20Activity.%20One%20major%20advantage%20compared%20to%20the%20View#onClick%20attribute%20is%20that%20the%20expression%20is%20processed%20at%20compile%20time,%20so%20if%20the%20method%20does%20not%20exist%20or%20its%20signature%20is%20not%20correct,%20you%20receive%20a%20compile%20time%20error.%20%20The%20major%20difference%20between%20Method%20References%20and%20Listener%20Bindings%20is%20that%20the%20actual%20listener%20implementation%20is%20created%20when%20the%20data%20is%20bound,%20not%20when%20the%20event%20is%20triggered.%20If%20you%20prefer%20to%20evaluate%20the%20expression%20when%20the%20event%20happens,%20you%20should%20use%20listener%20binding.%20%20To%20assign%20an%20event%20to%20its%20handler,%20use%20a%20normal%20binding%20expression,%20with%20the%20value%20being%20the%20method%20name%20to%20call.%20For%20example,%20if%20your%20data%20object%20has%20two%20methods:%20%20public%20class%20MyHandlers%20%7B%20%20%20%20%20public%20void%20onClickFriend(View%20view)%20%7B%20...%20%7D%20%7D%20The%20binding%20expression%20can%20assign%20the%20click%20listener%20for%20a%20View:%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Note%20that%20the%20signature%20of%20the%20method%20in%20the%20expression%20must%20exactly%20match%20the%20signature%20of%20the%20method%20in%20the%20Listener%20object.%20%20Listener%20Bindings%20Listener%20Bindings%20are%20binding%20expressions%20that%20run%20when%20an%20event%20happens.%20They%20are%20similar%20to%20method%20references,%20but%20they%20let%20you%20run%20arbitrary%20data%20binding%20expressions.%20This%20feature%20is%20available%20with%20Android%20Gradle%20Plugin%20for%20Gradle%20version%202.0%20and%20later.%20%20In%20method%20references,%20the%20parameters%20of%20the%20method%20must%20match%20the%20parameters%20of%20the%20event%20listener.%20In%20Listener%20Bindings,%20only%20your%20return%20value%20must%20match%20the%20expected%20return%20value%20of%20the%20listener%20(unless%20it%20is%20expecting%20void).%20For%20example,%20you%20can%20have%20a%20presenter%20class%20that%20has%20the%20following%20method:%20%20public%20class%20Presenter%20%7B%20%20%20%20%20public%20void%20onSaveClick(Task%20task)%7B%7D%20%7D%20Then%20you%20can%20bind%20the%20click%20event%20to%20your%20class%20as%20follows:%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Listeners%20are%20represented%20by%20lambda%20expressions%20that%20are%20allowed%20only%20as%20root%20elements%20of%20your%20expressions.%20When%20a%20callback%20is%20used%20in%20an%20expression,%20Data%20Binding%20automatically%20creates%20the%20necessary%20listener%20and%20registers%20for%20the%20event.%20When%20the%20view%20fires%20the%20event,%20Data%20Binding%20evaluates%20the%20given%20expression.%20As%20in%20regular%20binding%20expressions,%20you%20still%20get%20the%20null%20and%20thread%20safety%20of%20Data%20Binding%20while%20these%20listener%20expressions%20are%20being%20evaluated.%20%20Note%20that%20in%20the%20example%20above,%20we%20haven't%20defined%20the%20view%20parameter%20that%20is%20passed%20into%20onClick(android.view.View).%20Listener%20bindings%20provide%20two%20choices%20for%20listener%20parameters:%20you%20can%20either%20ignore%20all%20parameters%20to%20the%20method%20or%20name%20all%20of%20them.%20If%20you%20prefer%20to%20name%20the%20parameters,%20you%20can%20use%20them%20in%20your%20expression.%20For%20example,%20the%20expression%20above%20could%20be%20written%20as:%20%20%20%20android:onClick=%22@%7B(view)%20->%20presenter.onSaveClick(task)%7D%22%20Or%20if%20you%20wanted%20to%20use%20the%20parameter%20in%20the%20expression,%20it%20could%20work%20as%20follows:%20public%20class%20Presenter%20%7B%20%20%20%20%20public%20void%20onSaveClick(View%20view,%20Task%20task)%7B%7D%20%7D%20%20%20android:onClick=%22@%7B(theView)%20->%20presenter.onSaveClick(theView,%20task)%7D%22%20You%20can%20use%20a%20lambda%20expression%20with%20more%20than%20one%20parameter:%20public%20class%20Presenter%20%7B%20%20%20%20%20public%20void%20onCompletedChanged(Task%20task,%20boolean%20completed)%7B%7D%20%7D%20%20%20%20presenter.completeChanged(task,%20isChecked)%7D%22%20/>%20If%20the%20event%20you%20are%20listening%20to%20returns%20a%20value%20whose%20type%20is%20not%20void,%20your%20expressions%20must%20return%20the%20same%20type%20of%20value%20as%20well.%20For%20example,%20if%20you%20want%20to%20listen%20for%20the%20long%20click%20event,%20your%20expression%20should%20return%20boolean.%20%20public%20class%20Presenter%20%7B%20%20%20%20%20public%20boolean%20onLongClick(View%20view,%20Task%20task)%7B%7D%20%7D%20%20%20android:onLongClick=%22@%7B(theView)%20->%20presenter.onLongClick(theView,%20task)%7D%22%20If%20the%20expression%20cannot%20be%20evaluated%20due%20to%20null%20objects,%20Data%20Binding%20returns%20the%20default%20Java%20value%20for%20that%20type.%20For%20example,%20null%20for%20reference%20types,%200%20for%20int,%20false%20for%20boolean,%20etc.%20%20If%20you%20need%20to%20use%20an%20expression%20with%20a%20predicate%20(e.g.%20ternary),%20you%20can%20use%20void%20as%20a%20symbol.%20%20%20%20android:onClick=%22@%7B(v)%20->%20v.isVisible()%20?%20doSomething()%20:%20void%7D%22%20Avoid%20Complex%20Listeners%20Listener%20expressions%20are%20very%20powerful%20and%20can%20make%20your%20code%20very%20easy%20to%20read.%20On%20the%20other%20hand,%20listeners%20containing%20complex%20expressions%20make%20your%20layouts%20hard%20to%20read%20and%20unmaintainable.%20These%20expressions%20should%20be%20as%20simple%20as%20passing%20available%20data%20from%20your%20UI%20to%20your%20callback%20method.%20You%20should%20implement%20any%20business%20logic%20inside%20the%20callback%20method%20that%20you%20invoked%20from%20the%20listener%20expression.%20Some%20specialized%20click%20event%20handlers%20exist%20and%20they%20need%20an%20attribute%20other%20than%20android:onClick%20to%20avoid%20a%20conflict.%20The%20following%20attributes%20have%20been%20created%20to%20avoid%20such%20conflicts:%20%20Class%09Listener%20Setter%09Attribute%20SearchView%09setOnSearchClickListener(View.OnClickListener)%09android:onSearchClick%20ZoomControls%09setOnZoomInClickListener(View.OnClickListener)%09android:onZoomIn%20ZoomControls%09setOnZoomOutClickListener(View.OnClickListener)%09android:onZoomOut%20Layout%20Details%20Imports%20Zero%20or%20more%20import%20elements%20may%20be%20used%20inside%20the%20data%20element.%20These%20allow%20easy%20reference%20to%20classes%20inside%20your%20layout%20file,%20just%20like%20in%20Java.%20%20%20%20%20%20%20%20%20Now,%20View%20may%20be%20used%20within%20your%20binding%20expression:%20%20%20When%20there%20are%20class%20name%20conflicts,%20one%20of%20the%20classes%20may%20be%20renamed%20to%20an%20%22alias:%22%20%20%20%20Now,%20Vista%20may%20be%20used%20to%20reference%20the%20com.example.real.estate.View%20and%20View%20may%20be%20used%20to%20reference%20android.view.View%20within%20the%20layout%20file.%20Imported%20types%20may%20be%20used%20as%20type%20references%20in%20variables%20and%20expressions:%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Note:%20Android%20Studio%20does%20not%20yet%20handle%20imports%20so%20the%20autocomplete%20for%20imported%20variables%20may%20not%20work%20in%20your%20IDE.%20Your%20application%20will%20still%20compile%20fine%20and%20you%20can%20work%20around%20the%20IDE%20issue%20by%20using%20fully%20qualified%20names%20in%20your%20variable%20definitions.%20%20%20Imported%20types%20may%20also%20be%20used%20when%20referencing%20static%20fields%20and%20methods%20in%20expressions:%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%80%A6%20%20Just%20as%20in%20Java,%20java.lang.*%20is%20imported%20automatically.%20%20Variables%20Any%20number%20of%20variable%20elements%20may%20be%20used%20inside%20the%20data%20element.%20Each%20variable%20element%20describes%20a%20property%20that%20may%20be%20set%20on%20the%20layout%20to%20be%20used%20in%20binding%20expressions%20within%20the%20layout%20file.%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20The%20variable%20types%20are%20inspected%20at%20compile%20time,%20so%20if%20a%20variable%20implements%20Observable%20or%20is%20an%20observable%20collection,%20that%20should%20be%20reflected%20in%20the%20type.%20If%20the%20variable%20is%20a%20base%20class%20or%20interface%20that%20does%20not%20implement%20the%20Observable*%20interface,%20the%20variables%20will%20not%20be%20observed!%20%20When%20there%20are%20different%20layout%20files%20for%20various%20configurations%20(e.g.%20landscape%20or%20portrait),%20the%20variables%20will%20be%20combined.%20There%20must%20not%20be%20conflicting%20variable%20definitions%20between%20these%20layout%20files.%20%20The%20generated%20binding%20class%20will%20have%20a%20setter%20and%20getter%20for%20each%20of%20the%20described%20variables.%20The%20variables%20will%20take%20the%20default%20Java%20values%20until%20the%20setter%20is%20called%20%E2%80%94%20null%20for%20reference%20types,%200%20for%20int,%20false%20for%20boolean,%20etc.%20%20A%20special%20variable%20named%20context%20is%20generated%20for%20use%20in%20binding%20expressions%20as%20needed.%20The%20value%20for%20context%20is%20the%20Context%20from%20the%20root%20View's%20getContext().%20The%20context%20variable%20will%20be%20overridden%20by%20an%20explicit%20variable%20declaration%20with%20that%20name.%20%20Custom%20Binding%20Class%20Names%20By%20default,%20a%20Binding%20class%20is%20generated%20based%20on%20the%20name%20of%20the%20layout%20file,%20starting%20it%20with%20upper-case,%20removing%20underscores%20(%20_%20)%20and%20capitalizing%20the%20following%20letter%20and%20then%20suffixing%20%22Binding%22.%20This%20class%20will%20be%20placed%20in%20a%20databinding%20package%20under%20the%20module%20package.%20For%20example,%20the%20layout%20file%20contact_item.xml%20will%20generate%20ContactItemBinding.%20If%20the%20module%20package%20is%20com.example.my.app,%20then%20it%20will%20be%20placed%20in%20com.example.my.app.databinding.%20%20Binding%20classes%20may%20be%20renamed%20or%20placed%20in%20different%20packages%20by%20adjusting%20the%20class%20attribute%20of%20the%20data%20element.%20For%20example:%20%20%20%20%20%20%20...%20%20This%20generates%20the%20binding%20class%20as%20ContactItem%20in%20the%20databinding%20package%20in%20the%20module%20package.%20If%20the%20class%20should%20be%20generated%20in%20a%20different%20package%20within%20the%20module%20package,%20it%20may%20be%20prefixed%20with%20%22.%22:%20%20%20%20%20%20%20...%20%20In%20this%20case,%20ContactItem%20is%20generated%20in%20the%20module%20package%20directly.%20Any%20package%20may%20be%20used%20if%20the%20full%20package%20is%20provided:%20%20%20%20%20%20%20...%20%20Includes%20Variables%20may%20be%20passed%20into%20an%20included%20layout's%20binding%20from%20the%20containing%20layout%20by%20using%20the%20application%20namespace%20and%20the%20variable%20name%20in%20an%20attribute:%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Here,%20there%20must%20be%20a%20user%20variable%20in%20both%20the%20name.xml%20and%20contact.xml%20layout%20files.%20%20Data%20binding%20does%20not%20support%20include%20as%20a%20direct%20child%20of%20a%20merge%20element.%20For%20example,%20the%20following%20layout%20is%20not%20supported:%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Expression%20Language%20Common%20Features%20The%20expression%20language%20looks%20a%20lot%20like%20a%20Java%20expression.%20These%20are%20the%20same:%20%20Mathematical%20+%20-%20/%20*%20%%20String%20concatenation%20+%20Logical%20&&%20%7C%7C%20Binary%20&%20%7C%20%5E%20Unary%20+%20-%20!%20~%20Shift%20>>%20>>>%20<<%20Comparison%20==%20>%20<%20>=%20<=%20instanceof%20Grouping%20()%20Literals%20-%20character,%20String,%20numeric,%20null%20Cast%20Method%20calls%20Field%20access%20Array%20access%20%5B%5D%20Ternary%20operator%20?:%20Examples:%20%20android:text=%22@%7BString.valueOf(index%20+%201)%7D%22%20android:visibility=%22@%7Bage%20<%2013%20?%20View.GONE%20:%20View.VISIBLE%7D%22%20android:transitionName='@%7B%22image_%22%20+%20id%7D'%20Missing%20Operations%20A%20few%20operations%20are%20missing%20from%20the%20expression%20syntax%20that%20you%20can%20use%20in%20Java.%20%20this%20super%20new%20Explicit%20generic%20invocation%20Null%20Coalescing%20Operator%20The%20null%20coalescing%20operator%20(??)%20chooses%20the%20left%20operand%20if%20it%20is%20not%20null%20or%20the%20right%20if%20it%20is%20null.%20%20android:text=%22@%7Buser.displayName%20??%20user.lastName%7D%22%20This%20is%20functionally%20equivalent%20to:%20%20android:text=%22@%7Buser.displayName%20!=%20null%20?%20user.displayName%20:%20user.lastName%7D%22%20Property%20Reference%20The%20first%20was%20already%20discussed%20in%20the%20Writing%20your%20first%20data%20binding%20expressions%20above:%20short%20form%20JavaBean%20references.%20When%20an%20expression%20references%20a%20property%20on%20a%20class,%20it%20uses%20the%20same%20format%20for%20fields,%20getters,%20and%20ObservableFields.%20%20android:text=%22@%7Buser.lastName%7D%22%20Avoiding%20NullPointerException%20Generated%20data%20binding%20code%20automatically%20checks%20for%20nulls%20and%20avoid%20null%20pointer%20exceptions.%20For%20example,%20in%20the%20expression%20@%7Buser.name%7D,%20if%20user%20is%20null,%20user.name%20will%20be%20assigned%20its%20default%20value%20(null).%20If%20you%20were%20referencing%20user.age,%20where%20age%20is%20an%20int,%20then%20it%20would%20default%20to%200.%20%20Collections%20Common%20collections:%20arrays,%20lists,%20sparse%20lists,%20and%20maps,%20may%20be%20accessed%20using%20the%20%5B%5D%20operator%20for%20convenience.%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%80%A6%20android:text=%22@%7Blist%5Bindex%5D%7D%22%20%E2%80%A6%20android:text=%22@%7Bsparse%5Bindex%5D%7D%22%20%E2%80%A6%20android:text=%22@%7Bmap%5Bkey%5D%7D%22%20String%20Literals%20When%20using%20single%20quotes%20around%20the%20attribute%20value,%20it%20is%20easy%20to%20use%20double%20quotes%20in%20the%20expression:%20%20android:text='@%7Bmap%5B%22firstName%22%5D%7D'%20It%20is%20also%20possible%20to%20use%20double%20quotes%20to%20surround%20the%20attribute%20value.%20When%20doing%20so,%20String%20literals%20should%20either%20use%20the%20'%20or%20back%20quote%20(%60).%20%20android:text=%22@%7Bmap%5B%60firstName%60%7D%22%20android:text=%22@%7Bmap%5B'firstName'%5D%7D%22%20Resources%20It%20is%20possible%20to%20access%20resources%20as%20part%20of%20expressions%20using%20the%20normal%20syntax:%20%20android:padding=%22@%7Blarge?%20@dimen/largePadding%20:%20@dimen/smallPadding%7D%22%20Format%20strings%20and%20plurals%20may%20be%20evaluated%20by%20providing%20parameters:%20%20android:text=%22@%7B@string/nameFormat(firstName,%20lastName)%7D%22%20android:text=%22@%7B@plurals/banana(bananaCount)%7D%22%20When%20a%20plural%20takes%20multiple%20parameters,%20all%20parameters%20should%20be%20passed:%20%20%20%20%20Have%20an%20orange%20%20%20Have%20%d%20oranges%20%20android:text=%22@%7B@plurals/orange(orangeCount,%20orangeCount)%7D%22%20Some%20resources%20require%20explicit%20type%20evaluation.%20%20Type%09Normal%20Reference%09Expression%20Reference%20String%5B%5D%09@array%09@stringArray%20int%5B%5D%09@array%09@intArray%20TypedArray%09@array%09@typedArray%20Animator%09@animator%09@animator%20StateListAnimator%09@animator%09@stateListAnimator%20color%20int%09@color%09@color%20ColorStateList%09@color%09@colorStateList%20Data%20Objects%20Any%20plain%20old%20Java%20object%20(POJO)%20may%20be%20used%20for%20data%20binding,%20but%20modifying%20a%20POJO%20will%20not%20cause%20the%20UI%20to%20update.%20The%20real%20power%20of%20data%20binding%20can%20be%20used%20by%20giving%20your%20data%20objects%20the%20ability%20to%20notify%20when%20data%20changes.%20There%20are%20three%20different%20data%20change%20notification%20mechanisms,%20Observable%20objects,%20observable%20fields,%20and%20observable%20collections.%20%20When%20one%20of%20these%20observable%20data%20object%20is%20bound%20to%20the%20UI%20and%20a%20property%20of%20the%20data%20object%20changes,%20the%20UI%20will%20be%20updated%20automatically.%20%20Observable%20Objects%20A%20class%20implementing%20the%20Observable%20interface%20will%20allow%20the%20binding%20to%20attach%20a%20single%20listener%20to%20a%20bound%20object%20to%20listen%20for%20changes%20of%20all%20properties%20on%20that%20object.%20%20The%20Observable%20interface%20has%20a%20mechanism%20to%20add%20and%20remove%20listeners,%20but%20notifying%20is%20up%20to%20the%20developer.%20To%20make%20development%20easier,%20a%20base%20class,%20BaseObservable,%20was%20created%20to%20implement%20the%20listener%20registration%20mechanism.%20The%20data%20class%20implementer%20is%20still%20responsible%20for%20notifying%20when%20the%20properties%20change.%20This%20is%20done%20by%20assigning%20a%20Bindable%20annotation%20to%20the%20getter%20and%20notifying%20in%20the%20setter.%20%20private%20static%20class%20User%20extends%20BaseObservable%20%7B%20%20%20%20private%20String%20firstName;%20%20%20%20private%20String%20lastName;%20%20%20%20@Bindable%20%20%20%20public%20String%20getFirstName()%20%7B%20%20%20%20%20%20%20%20return%20this.firstName;%20%20%20%20%7D%20%20%20%20@Bindable%20%20%20%20public%20String%20getLastName()%20%7B%20%20%20%20%20%20%20%20return%20this.lastName;%20%20%20%20%7D%20%20%20%20public%20void%20setFirstName(String%20firstName)%20%7B%20%20%20%20%20%20%20%20this.firstName%20=%20firstName;%20%20%20%20%20%20%20%20notifyPropertyChanged(BR.firstName);%20%20%20%20%7D%20%20%20%20public%20void%20setLastName(String%20lastName)%20%7B%20%20%20%20%20%20%20%20this.lastName%20=%20lastName;%20%20%20%20%20%20%20%20notifyPropertyChanged(BR.lastName);%20%20%20%20%7D%20%7D%20The%20Bindable%20annotation%20generates%20an%20entry%20in%20the%20BR%20class%20file%20during%20compilation.%20The%20BR%20class%20file%20will%20be%20generated%20in%20the%20module%20package.%20If%20the%20base%20class%20for%20data%20classes%20cannot%20be%20changed,%20the%20Observable%20interface%20may%20be%20implemented%20using%20the%20convenient%20PropertyChangeRegistry%20to%20store%20and%20notify%20listeners%20efficiently.%20%20ObservableFields%20A%20little%20work%20is%20involved%20in%20creating%20Observable%20classes,%20so%20developers%20who%20want%20to%20save%20time%20or%20have%20few%20properties%20may%20use%20ObservableField%20and%20its%20siblings%20ObservableBoolean,%20ObservableByte,%20ObservableChar,%20ObservableShort,%20ObservableInt,%20ObservableLong,%20ObservableFloat,%20ObservableDouble,%20and%20ObservableParcelable.%20ObservableFields%20are%20self-contained%20observable%20objects%20that%20have%20a%20single%20field.%20The%20primitive%20versions%20avoid%20boxing%20and%20unboxing%20during%20access%20operations.%20To%20use,%20create%20a%20public%20final%20field%20in%20the%20data%20class:%20%20private%20static%20class%20User%20%7B%20%20%20%20public%20final%20ObservableField%20firstName%20=%20%20%20%20%20%20%20%20new%20ObservableField<>();%20%20%20%20public%20final%20ObservableField%20lastName%20=%20%20%20%20%20%20%20%20new%20ObservableField<>();%20%20%20%20public%20final%20ObservableInt%20age%20=%20new%20ObservableInt();%20%7D%20That's%20it!%20To%20access%20the%20value,%20use%20the%20set%20and%20get%20accessor%20methods:%20%20user.firstName.set(%22Google%22);%20int%20age%20=%20user.age.get();%20Observable%20Collections%20Some%20applications%20use%20more%20dynamic%20structures%20to%20hold%20data.%20Observable%20collections%20allow%20keyed%20access%20to%20these%20data%20objects.%20ObservableArrayMap%20is%20useful%20when%20the%20key%20is%20a%20reference%20type,%20such%20as%20String.%20%20ObservableArrayMap%20user%20=%20new%20ObservableArrayMap<>();%20user.put(%22firstName%22,%20%22Google%22);%20user.put(%22lastName%22,%20%22Inc.%22);%20user.put(%22age%22,%2017);%20In%20the%20layout,%20the%20map%20may%20be%20accessed%20through%20the%20String%20keys:%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%80%A6%20%20%20ObservableArrayList%20is%20useful%20when%20the%20key%20is%20an%20integer:%20%20ObservableArrayList
Data Binding Library
In this document:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-