This commit is contained in:
luyao 2019-05-31 16:58:42 +08:00
parent fb389e716c
commit abed1a9e39
14 changed files with 301 additions and 27 deletions

View File

@ -8,7 +8,7 @@ android {
compileSdkVersion 28
defaultConfig {
applicationId "luyao.ktx"
minSdkVersion 15
minSdkVersion 16
targetSdkVersion 28
versionCode 1
versionName "1.0"

View File

@ -9,13 +9,14 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<activity android:name="luyao.util.ktx.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name="luyao.util.ktx.mvvm.MvvmActivity"/>
</application>
</manifest>

View File

@ -1,12 +0,0 @@
package luyao.ktx
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}

View File

@ -0,0 +1,17 @@
package luyao.util.ktx
import kotlinx.android.synthetic.main.activity_main.*
import luyao.ktx.R
import luyao.ktx.base.BaseActivity
import luyao.util.ktx.mvvm.MvvmActivity
class MainActivity : BaseActivity() {
override fun getLayoutResId() = R.layout.activity_main
override fun initView() {}
override fun initData() {
btMvvm.setOnClickListener { startActivity(MvvmActivity::class.java) }
}
}

View File

@ -0,0 +1,37 @@
package luyao.util.ktx.mvvm
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.Observer
import kotlinx.android.synthetic.main.activity_mvvm_demo.*
import luyao.ktx.R
import luyao.ktx.base.BaseVMActivity
import luyao.ktx.ext.toast
/**
* Created by luyao
* on 2019/5/31 16:28
*/
class MvvmActivity : BaseVMActivity<MvvmModel>(), LifecycleOwner {
override fun providerVMClass() = MvvmModel::class.java
override fun getLayoutResId() = R.layout.activity_mvvm_demo
override fun initView() {
mvvm.setOnClickListener { mViewModel.getMessage() }
}
override fun initData() {
}
override fun startObserve() {
mViewModel.run {
mMessage.observe(this@MvvmActivity, Observer {
it?.run {
toast(it)
}
})
}
}
}

View File

@ -0,0 +1,29 @@
package luyao.util.ktx.mvvm
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.MutableLiveData
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.delay
import luyao.ktx.base.BaseViewModel
/**
* Created by luyao
* on 2019/5/31 16:28
*/
class MvvmModel : BaseViewModel() {
val mMessage: MutableLiveData<String> = MutableLiveData()
fun getMessage() {
launch {
val deferred = async(Dispatchers.IO) {
delay(2000) // network request
"success"
}
mMessage.value = deferred.await()
}
}
}

View File

@ -1,19 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
tools:context="luyao.util.ktx.MainActivity"
android:orientation="vertical"
android:gravity="center_horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<Button
android:id="@+id/btMvvm"
android:layout_width="100dp"
android:layout_height="50dp"
android:text="MVVM"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/mvvm"
android:layout_width="100dp"
android:layout_height="80dp"
android:layout_centerInParent="true"
android:text="Click"/>
</RelativeLayout>

View File

@ -1,4 +1,6 @@
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-android'
android {
compileSdkVersion 28
@ -30,4 +32,15 @@ dependencies {
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
api "androidx.core:core-ktx:1.2.0-alpha01"
api "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
api 'com.afollestad.material-dialogs:core:3.0.0-beta2'
api "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.1.1"
api "androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0-alpha01"
api 'androidx.lifecycle:lifecycle-extensions:2.2.0-alpha01'
}
repositories {
mavenCentral()
}

View File

@ -1,2 +1,2 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="luyao.util.ktx"/>
package="luyao.ktx"/>

View File

@ -0,0 +1,34 @@
package luyao.ktx.base
import android.content.Intent
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
/**
* Created by luyao
* on 2019/5/31 15:44
*/
abstract class BaseActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(getLayoutResId())
initView()
// setSupportActionBar(mToolbar)
initData()
}
abstract fun getLayoutResId(): Int
abstract fun initView()
abstract fun initData()
protected fun startActivity(z: Class<*>) {
startActivity(Intent(this, z))
}
protected fun startActivity(z: Class<*>, name: String, value: Boolean) {
val intent = Intent(this, z).putExtra(name, value)
startActivity(intent)
}
}

View File

@ -0,0 +1,39 @@
package luyao.ktx.base
import android.os.Bundle
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.ViewModelProviders
/**
* Created by luyao
* on 2019/5/31 16:16
*/
abstract class BaseVMActivity<VM : BaseViewModel> : BaseActivity(),LifecycleObserver {
lateinit var mViewModel: VM
override fun onCreate(savedInstanceState: Bundle?) {
initVM()
super.onCreate(savedInstanceState)
startObserve()
}
private fun initVM() {
providerVMClass()?.let {
mViewModel = ViewModelProviders.of(this).get(it)
mViewModel.let(lifecycle::addObserver)
}
}
open fun providerVMClass(): Class<VM>? = null
open fun startObserve() {}
override fun onDestroy() {
mViewModel.let {
lifecycle.removeObserver(it)
}
super.onDestroy()
}
}

View File

@ -0,0 +1,76 @@
package luyao.ktx.base
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.*
/**
* Created by luyao
* on 2019/5/31 16:06
*/
open class BaseViewModel : ViewModel(), LifecycleObserver {
private val mException: MutableLiveData<Exception> = MutableLiveData()
private fun launchOnUI(block: suspend CoroutineScope.() -> Unit) {
viewModelScope.launch { block() }
}
suspend fun <T> launchIO(block: suspend CoroutineScope.() -> T) {
withContext(Dispatchers.IO) {
block
}
}
fun launch(tryBlock: suspend CoroutineScope.() -> Unit) {
launchOnUI {
tryCatch(tryBlock, {}, {}, true)
}
}
fun launchOnUITryCatch(tryBlock: suspend CoroutineScope.() -> Unit,
catchBlock: suspend CoroutineScope.(Throwable) -> Unit,
finallyBlock: suspend CoroutineScope.() -> Unit,
handleCancellationExceptionManually: Boolean
) {
launchOnUI {
tryCatch(tryBlock, catchBlock, finallyBlock, handleCancellationExceptionManually)
}
}
fun launchOnUITryCatch(tryBlock: suspend CoroutineScope.() -> Unit,
handleCancellationExceptionManually: Boolean = false
) {
launchOnUI {
tryCatch(tryBlock, {}, {}, handleCancellationExceptionManually)
}
}
private suspend fun tryCatch(
tryBlock: suspend CoroutineScope.() -> Unit,
catchBlock: suspend CoroutineScope.(Throwable) -> Unit,
finallyBlock: suspend CoroutineScope.() -> Unit,
handleCancellationExceptionManually: Boolean = false) {
coroutineScope {
try {
tryBlock()
} catch (e: Exception) {
if (e !is CancellationException || handleCancellationExceptionManually) {
mException.value = e
catchBlock(e)
} else {
throw e
}
} finally {
finallyBlock()
}
}
}
}

View File

@ -0,0 +1,27 @@
package luyao.ktx.ext
import android.content.Context
import android.widget.Toast
import androidx.annotation.StringRes
/**
* Created by luyao
* on 2019/5/31 16:42
*/
var showToast: Toast? = null
fun Context.toast(content: String, duration: Int = Toast.LENGTH_SHORT) {
showToast?.apply {
setText(content)
show()
} ?: run {
Toast.makeText(this.applicationContext, content, Toast.LENGTH_SHORT).apply {
showToast = this
}.show()
}
}
fun Context.toast(@StringRes id: Int, duration: Int = Toast.LENGTH_SHORT) {
toast(getString(id), duration)
}