Kotlin_android知识点

--kotlin中变量和函数非空和可空的处理

Kotlin——初级篇(六):空类型、空安全、非空断言、类型转换等特性总结

在kotlin中,所有类型变量都是非空变量,也就是说,默认是不会空指针的

但是如果我们需要赋值一个变量为空,就需要在变量类型后添加?

var isRunning:Boolean=false
//报错
isRunning=null

var isRunning:Boolean?=false
//编译通过
isRunning=null

操作可空变量,调用可空变量的方法/属性时,编译器就会提醒我们必须使用安全操作符

var value:String?=null
var length:Int?=0
//value为空时,会中断调用,直接返回null,适合链式调用
length=value?.length.toString().toInt()
//value为空时会抛出空指针异常
length=value!!.length

那么如果我们希望把收到的可空变量变成非空变量,这样之后操作时,就可以不用担心空指针或者添加非空判断,

        var value:String?=null
        var length:Int=0
//        报错,Int?类型不能赋值给Int类型
        length=value?.length
//        通过,?:操作符会在左边为空时,直接返回右边的0,否则返回左侧本身
//        ?:可以看作是java版本的三元操作符,条件是?左侧不为空
//        length=value!=null?value.length:0
        length=value?.length?:0

--kotlin实现android dataBinding

1.添加kotlin插件

根目录build.gradle

buildscript {
    ext.kotlin_version = '1.5.20'
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath "com.android.tools.build:gradle:4.1.2"
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

app目录下build.gradle

...
//kotlin插件
apply plugin: 'kotlin-android'

...
dependencies {
    //kotlin_android依赖核心库
    implementation "androidx.core:core-ktx:+"
    //kotlin_java核心依赖库
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    ...
}

2.打开dataBinding,添加kotlin编译器

在app目录下build.gradle

...
//kotlin注解插件
apply plugin: 'kotlin-kapt'

...
android{
    ...
    //启用dataBinding
    buildFeatures{
        dataBinding=true
    }
    ...
}

dependencies {
    ...
    //kotlin注解插件库
     kapt "com.android.databinding:compiler:3.2.0-alpha10"
    ...
}

3.参考单向绑定(待完成)

在viewModel中实现liveData

class MainViewModel : ViewModel() {
    /**
     * 保存文件路径
     */
    private val mStorePath: MutableLiveData<String> = MutableLiveData("")

    /**
     * 绑定服务
     */
    private val mServiceConnected: MutableLiveData<Boolean> = MutableLiveData(false)


    fun setStorePath(path: String) {
        mStorePath.value = path
    }

    fun getStorePath(): MutableLiveData<String> {
        return mStorePath
    }

    fun setServiceConnected(connected: Boolean) {
        mServiceConnected.value = connected
    }

    fun getServiceConnected(): MutableLiveData<Boolean> {
        return mServiceConnected
    }
}

在xml中传入viewmodel

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <data>

        <variable
            name="viewModel"
            type="com.npt.filereceiver.MainViewModel" />

    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/cardview_light_background"
        tools:context=".MainActivity">

        <TextView
            android:id="@+id/textView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginEnd="16dp"
            android:background="@drawable/shape_content"
            android:padding="8dp"
            android:text="存储路径"
            android:textColor="@color/black"
            android:textSize="16sp"
            app:layout_constraintBottom_toBottomOf="@+id/b_dir"
            app:layout_constraintEnd_toStartOf="@+id/b_dir"
            app:layout_constraintTop_toTopOf="@+id/b_dir" />

        <TextView
            android:id="@+id/tv_path"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="16dp"
            android:layout_marginTop="16dp"
            android:layout_marginEnd="16dp"
            android:background="@drawable/shape_content"
            android:padding="8dp"
            android:textColor="@color/cardview_dark_background"
            android:textSize="16sp"
            android:text="@={viewModel.storePath}"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/textView" />

        


    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

在xml中,为需要绑定控件的属性添加数据

...
android:text="@={viewModel.storePath}"
...
这里对应的是viewModel里的get方法

 fun getStorePath(): MutableLiveData<String> {
        return mStorePath
    }

可以发现get方法返回的直接是liveData的实现类,而不是String类

在activity/fragment等控件中,设置生命周期的提供者

public class MainActivity extends AppCompatActivity{
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mViewDataBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
        mMainViewModel = new ViewModelProvider(this).get(MainViewModel.class);
        mAppViewModel = new AppViewModel(getApplication());
        mViewDataBinding.setViewModel(mMainViewModel);
        //设置生命周期的提供者,会为viewmodel中的liveData自动绑定生命周期
        mViewDataBinding.setLifecycleOwner(this);

    }
}

这里需要注意的是,liveData和ObservableField

liveData会根据生命周期是否活跃自动更新数据,也会根据生命周期来自动管理数据,ObservableField做不到这两点

具体可以参考官方

两步使用 LiveData 替换 Observable Field

java代码中引用kotlin类成员变量提示has private access

kotlin has private access in

原因是kotlin变量默认是public final,在java中引用时,会变为private,

此时在kotlin变量标注@JvmField注解,告诉jvm这个是公共变量即可

谷歌推荐:在 MVVM 架构中使用 Kotlin Flow

Kotlin Coroutines Flow 系列(五) 其他的操作符

Kotlin Flow场景化学习

Android开发者快速上手Kotlin(八) 之 协程官方框架Channel、Select和Flow的使用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值