Android Jatpack基础学习2
2019-02-18 本文已影响5人
进击的包籽
Android Jatpack基础学习1
本文Github代码
上一篇文章写了Jatpack工程的基础搭建,这篇继续写使用。dataBinding使用,ViewModel的使用。
1.ViewModel增加一个start变量,用于后面通知fragment跳转。
class MainViewModel : ViewModel() {
...
var start = MutableLiveData<Boolean>().apply { value = false }
...
fun startActivity() {
start.postValue(true)
}
}
2.xml里的控件点击事件绑定,另一个有id的Button,是dataBinding方式。
<Button
android:onClick="@{view -> viewModel.startActivity()}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="跳转" />
<Button
android:id="@+id/btn2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="跳转2" />
3.点击按钮后,在fragment中,就可以接受到ViewModel中start的变化,这里也能放网络请求,或者数据库变化,通知view更改。
//通过观察者模式,ViewModel参数变化,在此做跳转操作
viewModel.start.observe(viewLifecycleOwner, Observer {
if (it!!) {
activity?.let { activity ->
startActivity(Intent(activity, BindingActivity::class.java))
}
}
})
4.不用ViewModel通知的话,也能用dataBinding直接给控件增加点击事件,也不需要像以前写findViewById了。
//通过dataBinding找到控件,
dataBinding.btn2.setOnClickListener {
activity?.let { activity ->
startActivity(Intent(activity, BindingActivity::class.java))
}
}
两张结果是一样样的
点击
开发中,为了布局复用,我们一般会include复用布局,但是里面的参数,却只能再findViewById后设置,dataBinding可以在xml里直接复制,不用再写繁琐的代码。
1.编辑一个复用的布局,这样写,允许使用它的布局直接传参进来。
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<!-- view的visible需要View类支持 -->
<import type="android.view.View" />
<variable
name="title"
type="String" />
<variable
name="background"
type="android.graphics.drawable.Drawable" />
<variable
name="visible"
type="java.lang.Boolean" />
<variable
name="resId"
type="android.graphics.drawable.Drawable" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@{background}"
android:orientation="vertical">
<!-- default是开发时看的,真正运行时看不到 -->
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{title,default = `大包子`}"
android:textSize="30sp" />
<!-- visible属性用boolean来控制 -->
<ImageView
android:id="@+id/imgClose"
android:layout_width="50dp"
android:layout_height="50dp"
android:src="@{resId ?? @drawable/ic_star_black , default = @drawable/ic_star_black}"
android:visibility="@{visible ? View.VISIBLE : View.INVISIBLE , default = visible}" />
</LinearLayout>
</layout>
2.fragment布局里使用,传参进去,app:之前include布局对应的参数="@{}"
<include
android:id="@+id/view1"
layout="@layout/include_view"
app:background="@{@color/white}"
app:resId="@{@drawable/ic_star_black}"
app:title="@{@string/title}"
app:visible="@{true}" />
<include
android:id="@+id/view2"
layout="@layout/include_view"
app:background="@{@color/grey}"
app:resId="@{@drawable/ic_star_white}"
app:title="@{@string/title2}"
app:visible="@{true}" />
<include
layout="@layout/include_view"
app:background="@{@color/grey}"
app:resId="@{@drawable/ic_star_white}"
app:title="@{@string/title3}"
app:visible="@{false}" />
include
3.include中控件要动态变化的方法,需要在使用include的时候设置对应的id。
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
dataBinding.view1.imgClose.setOnClickListener {
activity?.let {
it.finish()
}
}
dataBinding.view2.imgClose.setOnClickListener {
activity?.let {
it.finish()
}
}
}
有很多时候,基础类型不够用,那我们也能通过BindAdapter自定义类型。
class BindAdapter {
//设置字体颜色
@BindingAdapter("app:textColor")
fun setTextColor(textView: TextView, color: Int?) {
color?.let {
textView.setTextColor(ContextCompat.getColor(textView.context, color))
}
}
//手机号隐藏
@BindingAdapter("app:hidePhone")
fun hidePhone(textView: TextView, phone: String?) {
phone?.let {
if (phone.length > 7) {
var stringBuffer = StringBuffer(phone)
for (i in 3..6) {
stringBuffer.setCharAt(i, '*')
}
textView.text = stringBuffer.toString()
}
}
}
}
如果出现错误Cannot find the setter for attribute
错误解决
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="30sp"
app:hidePhone="@{`17600331122`}"
app:textColor="@{@color/blue}" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="30sp"
app:hidePhone="@{viewModel.phone}"
app:textColor="@{@color/colorAccent}" />
运行效果
跟多细节,可以看demo哦。