零蚀
什么是Jetpack
-
前言
-
最快的学习一门技术,就是官方文档,所以首先我会贴出官方文档,(当然排除人民币玩家,和白?人员,但是这样不好,会非常依赖资源)[? Jetpack官方文档]。
-
jetpack 既然说是一个工具,它主要从事的方面在:1、兼容java和kotlin(基础),2、架构,3、行为,4、界面(官方文档上都有)。而今天我要学习的顺序是2、3、4、1。基础里面包含监听测试等内容,所以后面用到再说。这一篇学习的就是jetpack的架构内容。
-
绑定简介
-
视图绑定
-
首先它的库是存在于
google()
中的,如果项目里面没有这个,需要添加。视图绑定就是viewBinding -
这里的库的版本我选择最近的稳定版本
2.2.0
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
-
我们可以添加视图绑定功能,当然我们可以用
tools:viewBindingIgnore="true"
来忽略视图的绑定。这种绑定是通过xml中的id进行引用,如果空间是没有id也就不会android {...viewBinding {enabled = true} }
-
我们的布局会自动生成binding类比如说我的布局叫做
activity_main.xml
那么会自动生成ActivityMainBinding,我们通过它可以获取root,也就是xml的根布局,也能通过布局里面的id来获取对象的引用。class MainActivity : AppCompatActivity() { lateinit var binding: ActivityMainBinding;override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState)binding = ActivityMainBinding.inflate(layoutInflater);setContentView(binding.root)// bind引用布局id来进行调用,// binding.root 这种getRoot方法也可以调用它的根布局binding.button.text="按钮"binding.button.setOnClickListener { Toast.makeText(this@MainActivity,"a",Toast.LENGTH_SHORT).show()} } }
-
-
数据绑定
-
这里是利用dataBinding来实现数据的绑定首先我们还是要配置我们的gradle。
android {...dataBinding {enabled = true} }
-
我们准备了一个UserBean,然后xml里面的数据就直接绑定了这个数据,然后我们的布局需要在layout的标签之下的,layout里面分为两个部分,首先是的数据部分,然后是绘制的图层部分。
<layout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"><data><variablename="viewModel"type="com.example.jetpackapplication.bean.UserBean" /></data><androidx.constraintlayout.widget.ConstraintLayout....><TextView.....android:text="@{viewModel.textContent}"..... /><Button......android:text="@{viewModel.buttonName}"....../></androidx.constraintlayout.widget.ConstraintLayout></layout>
-
当然有列表的情况下我们可以直接获取对应的item
… android:text="@{list[index]}" … android:text="@{sparse[index]}" … android:text="@{map[key]}"
-
或者我们可以这么用,将type提出来。
<data><import type="com.example.jetpackapplication.bean.UserBean"/><variablename="viewModel"type="UserBean" /> </data>
-
当然我们的UserBean里面的默认值是不会直接加载到我们的布局控件里的,只有我们设置数据的时候才会传数据给布局控件(这个后面说),我们可以在布局里可以直接设置它的默认值,但是这个默认值它只支持字母,汉子,下划线。不能使用特殊符号甚至是空格,且它的作用只是在预览的时候有效,运行的时候不会提供默认值给View
android:text="@{viewModel.textContent,default=hello_jetpack}"
-
接下来就是将数据绑定到我们的应用上,就是通过binding把数据绑定到控件上。这个流程和databinding的流程一致。
// dataBean data class UserBean(val buttonName:String="new按钮",val textContent:String="jetPack") // MainActivity binding.viewModel= UserBean()
-
LiveData初涉
-
使用
-
livedata是一种可观察的数据对象,但不同的是它具有生命周期感知的能力,他只会通知生命周期活跃的观察者,那些注册非活跃的则不会被通知,它的注册对象要实现
LifecycleOwner
才可以与之匹配。当相应的Lifecycle的状态未DESTROYED的时候,可以移除观察者。 -
它的优势:1、可以动态调整数据更改的时机,2、自我清理,不会发生内存泄露,3、不会因 Activity 停止而导致崩溃,4、不再需要手动处理生命周期,5、数据始终保持最新状态,6、适当的配置更改,7、共享资源。
-
应用场景:比如我们使用计时的时候,页面突然重新创建,我们发现及时任然存在,但是页面更新了,这是因为横竖屏切换重新走了onCreate方法。
binding.button.setOnClickListener {Thread {while (index < 200) {SystemClock.sleep(1000)runOnUiThread {binding.text.text = "" + indexToast.makeText(this@MainActivity,""+index,Toast.LENGTH_SHORT).show()}}}.start() }
-
我们可以如下,将数据包含进一个LiveData且这个类必须继承自ViewMode。
class UserViewMode :ViewModel(){ // 创建一个UserBean的LiveDataval firstContent:MutableLiveData<UserBean> by lazy { MutableLiveData<UserBean>()} }
-
然后我们通过
ViewModelProvider
将数据储存的持有者设置为我们的Activity(this),然后得到我们的ViewModel,再将我们的ViewModel和控件的数值绑定。binding.button.setOnClickListener { Thread { while (index < 200) { SystemClock.sleep(1000)//子线程里可以这么调用 mode.firstContent.postValue(UserBean("",""))runOnUiThread { index++mode.firstContent.value= UserBean("按钮",""+index)}}}.start() }mode=ViewModelProvider(this).get(UserViewModel::class.java) bindObserver()/*** 绑定*/private fun bindObserver(){ val contentObserver = Observer<UserBean> { binding.text.text = it.textContentbinding.button.text = it.buttonName}mode.firstContent.observe(this, contentObserver) }
-
这里的this,不是指activity这个类,而是实现了
ViewModelStoreOwner
,而我们的AppCompactActivty早已实现了这个接口(父类)。这里的MutableLiveData
也是LiveData,但是它屏蔽了她的所有的方法,除了值的设置,有兴趣可以自己继承viewMode来看看它的生命周期是否是在acitvity监听activity的生命周期下。
-
? 前言
? Android 知识栈
? Android Jetpack 系列