Kotlin的属性委托:无上下文情况下Android的赋值(KAD 15)
来源:互联网 发布:删除淘宝中差评的公司 编辑:程序博客网 时间:2024/04/28 00:13
作者:Antonio Leiva
时间:Mar 9, 2017
原文链接:https://antonioleiva.com/property-delegation-kotlin/
如我们在前面文章中读到的,属性需要默认值,不能声明属性,而不给它们赋值。
由于你要存储视图到属性中,这就产生一个问题了。在对象创建期间,这赋值代码将被执行,而此时你不能访问这个内容。
那你有能做什么?
属性委托:委托属性值到另一个对象
属性委托将使用另一个对象,这个对象能够调用get和set(如果使用了var)返回结果。
目前,我们还不能控制许多对象的创建,如Android框架,在许多情况下,这委托将挽救我们的生命。
我将向你展示三个例子,我认为它们在Android中非常有用。
设置视图到属性
对于这个例子,我们用委托有两个选项,且禁止用null(如果你能够避免它,有些事情不建议使用)。
这是我最喜欢的,因为它迫使你对于不可变的、不太安全的属性使用var。
用保留字lateinit,说明属性不能为空,但是我们仍然没有final价值:
1 lateinit var textView:TextView
在onCreate,我们能够赋值给final值:
1 setContentView(R.layout.activity_main)2 textView = findView(R.id.welcomeMessage)3 toast(textView.text)
尽管它与委托notNull做相同的操作、被归入第一喜欢,但这不是真正的委托。
第二个选择则更加优雅。它由Lazy委托组成,直至属性第一次被调用,相关代码是不会执行:
1 val textView by lazy { findView(R.id.welcomeMessage) }
在textView的get被第一次调用之前,findView是不能运行的。由于你不能错误的修改其值所以它更安全,并且它不会强制我们在setContentView之后记得设置它。
此刻,我们做:
1 toast(textView.text)
这行代码将在lazy形式下被执行。
如你所见,委托的方式用by保留字表示。
我们来看另一个例子。
通知适配器变更
在适配器中,我们有items属性,每次自动启动adapter时更新。
1 var items: List by Delegates.observable(emptyList()) {2 _, _, _ -> notifyDataSetChanged()3 }
它简单地设置初始值,然后在每次更改后调用定义的函数。
在这种情况下,我只是调用notifyDataSetChanged,但是,如你所见,函数收到的新旧两个值,所以在技术上你可以检查变化是什么,只更新其区别。
如果你对这个例子有兴趣,我在另一篇文章更广泛的描述它。
声明Lazy方法的Dagger图
这是我发现的非常有用的另一个情形。
返回到lazy,你能够在属性声明期间,用它声明应用的component:
1 val component: AppComponent by lazy { 2 DaggerAppComponent3 .builder()4 .appModule(AppModule(this))5 .build() 6 }
这个方法,你不需要用lateinit,属性则为不可变的。
如果在Activity中,用subcomponents,你能够做相同的事:
1 class HomeActivity : AppCompatActivity(), HomePresenter.View {2 val component by lazy { app.component.plus(HomeModule(this)) }3 ...4 }
新Kotlin 1.1版本:局部委托属性
我们已经见到怎样用委托是给我们类属性的额外能力。而例如lazy,对变量也真的有帮助吗?Kotlin是缺乏这一特性的。
现在,用局部委托属性,我们做:
1 fun testLocalDelegation() { 2 val database by lazy { createDatabase() } 3 val cache by lazy { createMemoryCache() } 4 5 if (mustUseDatabase()) { 6 database.use { ... } 7 } else { 8 cache.use { ... } 9 }10 }
尽管不使用lazy委托,这个例子能够解决,但它还是有助于理解这些概念。
我们有几个可能会或不会被使用的“笨重”对象。通过用lazy,我们能够推迟它们的实例化,直到我们确信要使用它们。
在首次使用时,花括号内的代码被执行,且被缓存起来,以备以后再使用。
结论
属性委托将帮助你属性更强大,更简化,且代码可重用。
这里我们仅仅看到Kotlin库的标准属性,而你能够创建你自己的属性。
例如在这本书中,我有实现从SharedPreference存储和取回数据。
如果你要学习更多这些内容,足够流畅创建自己的Android应用程序,我建议你获取这本免费指南,学习怎样创建你的第一个项目,或直接获取这本书,学习怎样从头开始创建一个完整的应用程序。
- Kotlin的属性委托:无上下文情况下Android的赋值(KAD 15)
- Kotlin的属性委托:无上下文情况下Android的赋值(KAD 15)
- Kotlin的属性委托:无上下文情况下Android的赋值(KAD 15)
- Kotlin的属性委托:无上下文情况下Android的赋值(KAD 15)
- Kotlin的属性委托:无上下文情况下Android的赋值(KAD 15)
- android自定义无上下padding的textview
- Kotlin的委托属性和区间
- Kotlin的数据类:节省很多行代码(KAD 10)
- Kotlin的数据类:节省很多行代码(KAD 10)_0
- Kotlin-Android世界的一股清流-委托
- Kotlin开发Android笔记11:Kotlin中属性委托
- 无上边框出现的问题
- Kotlin-委托属性
- Winform窗体传值的几种方式(属性赋值,委托,事件)
- 委托的使用情况
- 剑道独尊 无上剑意(下)
- Kotlin中功能操作与集合(KAD 11)
- Kotlin中功能操作与集合(KAD 11)
- python使用pip安装一个module时报错:RuntimeError: maximum recursion depth exceeded
- 根据先序,中序求一棵树
- 关于Struts2和ajax的登录验证问题
- delphi oracle odac
- hdfs回顾总结(3)---使用hadoopRpc模拟namenode元数据的查询
- Kotlin的属性委托:无上下文情况下Android的赋值(KAD 15)
- jsp静态化和伪静态化《转载》
- SSH框架开发Java web项目遇到的细节问题。
- ubuntu firfox has prevented the outdated plugin 'adobe flash'...
- 菜鸟学IT之IP基础
- Java路径问题最终解决方案—可定位所有资源的相对路径寻址(沈东良)
- linux 工具集合
- 2017.3.11 NOIP2017赛前模拟考试总结
- HTTP状态码