Android 第一行代码 jetpack 入门版

1.ViewModel

导入依赖

//认准extensions
    implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'

简单使用:

创建一个ViewModel,直接继承

class MainViewModel : ViewModel() {

    var counter = 0

}

使用:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/tvNum"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="1"
        android:textSize="20sp" />

    <Button
        android:id="@+id/butAdd"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="加1" />

</LinearLayout>
class MainActivity : AppCompatActivity() {

    lateinit var viewModel: MainViewModel
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        viewModel = ViewModelProviders.of(this).get(MainViewModel::class.java)
        butAdd.setOnClickListener {
            viewModel.counter++
            tvNum.text=viewModel.counter.toString()
        }
        tvNum.text=viewModel.counter.toString()


    }
}

这里获取viewmodel实例的方法是通过

ViewModelProviders.of(this).get(MainViewModel::class.java)

版本问题这里已经过时了,然而我搜的最新版本竟然已经去掉了这个方法......

因为ViewModel 的有自己独立的生命周期,并且生命周期要长于Activity,如果通过new ()来创建的话,那么内存泄露是一方面,另外当屏幕旋转或其他导致屏幕重新创建,就不能保存当前的状态了....

 


如何传递参数:

由于获取方式不是 new ,所以通过构造方法传递参数是个问题

ViewModelProvider.Factory

 

class MainViewModelFactory(private val countReversed: Int) : ViewModelProvider.Factory {

    override fun <T : ViewModel?> create(modelClass: Class<T>): T {
        return MainViewModel(countReversed) as T
    }
}

App退出之后重新打开,状态会重置,利用Sp

class MainActivity : AppCompatActivity() {

    lateinit var viewModel: MainViewModel
    lateinit var sp: SharedPreferences
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // 获取Sp 实例
        sp = getPreferences(Context.MODE_PRIVATE)
        val count_reserved = sp.getInt("count_reserved", 0)

        viewModel = ViewModelProviders.of(this,MainViewModelFactory(count_reserved)).get(MainViewModel::class.java)
        butAdd.setOnClickListener {
            viewModel.counter++
            tvNum.text = viewModel.counter.toString()
        }

        butClear.setOnClickListener {
            viewModel.counter = 0
            tvNum.text = viewModel.counter.toString()

        }

        tvNum.text = viewModel.counter.toString()
    }

    override fun onPause() {
        super.onPause()

        sp.edit {
            putInt("count_reserved",viewModel.counter)
        }

    }

}

这里我在使用sp.edit{}时.出现了please specify proper '-jvm',需要在builkd.gradle里添加

//新增如下配置
    kotlinOptions {
        jvmTarget = "1.8"
    }

 

 

2.Lifecycles

可以在一个非Activity  的 类中去感知Activity 的生命周期.

class MyObserver : LifecycleObserver {


    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    fun activityStart() {
        println("   activityStart   ")
    }


    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    fun activityStop() {
        println("   activityStop   ")
    }


}

可以看到是通过注解的方式

在Activity里边进行添加就可以了

]lifecycle.addObserver(MyObserver())

主动获取状态

class MyObserver(val lifecycle: Lifecycle) : LifecycleObserver {


    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    fun activityStart() {
        val currentState = lifecycle.currentState
        println("  currentState  :" + currentState)
    }


    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    fun activityStop() {
        println("   activityStop   ")
    }

}
lifecycle.addObserver(MyObserver(lifecycle))

3.LiveData

响应式编程,一种高级的观察者模式

结合ViewModel 的一个例子:

class MainActivity : AppCompatActivity() {

    lateinit var viewModel: MainViewModel
    lateinit var sp: SharedPreferences


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        sp = getPreferences(Context.MODE_PRIVATE)
        val count_reserved = sp.getInt("count_reserved", 0)

        viewModel = ViewModelProviders.of(this, MainViewModelFactory(count_reserved))
            .get(MainViewModel::class.java)


        butAdd.setOnClickListener {
            viewModel.add()
        }


        butClear.setOnClickListener {
            viewModel.clear()
        }


        viewModel.counter.observe(this, Observer {

            tvNum.text = it.toString()

        })
    }


    override fun onPause() {
        super.onPause()
        sp.edit {
            putInt("count_reserved", viewModel.counter.value ?: 0)
        }

    }
}
class MainViewModel(countReserved: Int) : ViewModel() {

    //  Mitable 为可变的
    val counter = MutableLiveData<Int>()

    init {
        counter.value = countReserved
    }

    /**
     * 加1
     */
    fun add() {
        //意思是默认为0     如果 对象是空的?  则:为0
        val count = counter.value ?: 0
        counter.value = count + 1
    }

    /**
     * 清零
     */
    fun clear() {
        counter.value = 0
    }


}
class MainViewModelFactory(private val countReversed: Int) : ViewModelProvider.Factory {

    override fun <T : ViewModel?> create(modelClass: Class<T>): T {
        return MainViewModel(countReversed) as T
    }
}

效果不变

这里只有一个Int,

可以自定义个Bean


这里换成子线程里进行.value 就报错了

换成postValue() 就可以了

然后作者又写了一个规范写法 :.....我指定是不懂的

class MainViewModel(countReserved: Int) : ViewModel() {

    //  Mitable 为可变的
    val counter : LiveData<Int>
    get() = _counter

    private val _counter  =MutableLiveData<Int>()
    init {
        _counter.value = countReserved
    }

    /**
     * 加1
     */
    fun add() {
        Thread() {
            //意思是默认为0     如果 对象是空的?  则:为0
            val count = counter.value ?: 0
            _counter.postValue( count + 1)
        }
            .start()
    }

    /**
     * 清零
     */
    fun clear() {
        _counter.value = 0
    }

}

照着粘把.....

map 和 switchMap

主要是为了防止暴露

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值