为了账号安全,请及时绑定邮箱和手机立即绑定

发现 关注 消息 5 搜索 Android Jatpack基础学习2

标签:
Android

上一篇文章写了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))
    }
}

两张结果是一样样的


webp

点击


开发中,为了布局复用,我们一般会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:class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="@{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}" />

webp

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}" />

webp

运行效果



作者:Good包籽
链接:https://www.jianshu.com/p/ff6aef298a18


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消