kotlin 查看模型工厂

ViewModelFactory.kt
class ViewModelFactory(private val injector: DKodein) : ViewModelProvider.Factory {

    override fun <T : ViewModel> create(modelClass: Class<T>): T {
        return injector.instanceOrNull<ViewModel>(tag = modelClass.simpleName) as T?
                ?: modelClass.newInstance()
    }
}
bindFactoryWhenInitKodein
bind<ViewModelProvider.Factory>() with singleton { ViewModelFactory(instance()) }

kotlin 绑定ViewModel

bind_view_model.kt
inline fun <reified T : ViewModel> Builder.bindViewModel(overrides: Boolean? = null): TypeBinder<T> {
    return bind<T>(T::class.java.simpleName, overrides)
}

kotlin 按钮计数器模板

buttoncounter
package wahyuros.android.buttonclickapp

import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.text.method.ScrollingMovementMethod
import android.util.Log
import android.view.View
import android.widget.Button
import android.widget.EditText
import android.widget.TextView

private const val TAG = "MainActivity"
private const val TEXT_CONTENTS = "TextContent"

class MainActivity : AppCompatActivity() {
    private var textView: TextView? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        Log.d(TAG, "onCreate: called")
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val userInput : EditText = findViewById<EditText>(R.id.editText)
        val button : Button = findViewById<Button>(R.id.button)
        textView = findViewById<TextView>(R.id.textView)
        //Add question mark if we want to access content of variable but its might be null
        textView?.text = ""
        textView?.movementMethod = ScrollingMovementMethod()
        userInput.text.clear()

        button.setOnClickListener(object : View.OnClickListener{
            override fun onClick(p0 : View){
                Log.d(TAG, "onClick: called")
                textView?.append(userInput.text)
                textView?.append("\n")
                userInput.text.clear()
            }
        })
    }

    override fun onStart() {
        Log.d(TAG, "onStart: called")
        super.onStart()
    }

    override fun onRestoreInstanceState(savedInstanceState: Bundle?) {
        Log.d(TAG, "onRestoreInstanceState: called")
        super.onRestoreInstanceState(savedInstanceState)
//        val savedString = savedInstanceState?.getString(TEXT_CONTENTS,defaultValue: "")
//        textView?.text = savedString
        textView?.text = savedInstanceState?.getString(TEXT_CONTENTS, "")
    }

    override fun onResume() {
        Log.d(TAG,  "onResume: called")
        super.onResume()
    }

    override fun onPause() {
        Log.d(TAG, "onPause: called")
        super.onPause()
    }

    override fun onSaveInstanceState(outState: Bundle?) {
        Log.d(TAG, "onSaveInstanceState: called")
        super.onSaveInstanceState(outState)
        outState?.putString(TEXT_CONTENTS, textView?.text.toString())
    }

    override fun onStop() {
        Log.d(TAG, "onStop: called")
        super.onStop()
    }

    override fun onDestroy() {
        Log.d(TAG, "onDestroy: called")
        super.onDestroy()
    }

    override fun onRestart() {
        Log.d(TAG, "onRestart: called")
        super.onRestart()
    }
}

kotlin for in .. downTo step to <br/> arrayListOf strList.withIndex()TreeMap

for in .. downTo step to <br/> arrayListOf strList.withIndex()TreeMap

for.kt
package my.demo

import java.util.*

/**
 * `downTo`, `step`, `until` 등은 모두 일반 메서드이고, `중위 호출(Infix Calls)`이라는 방식을 사용하기 때문에
 * 일반 함수 호출과 달리 키워드 처럼 사용할 수 있다.
 * 중위 호출 이란 매개변수가 하나뿐인 메서드를 호출할 때 간단하게 호출 할 수 있게 하기 위한 방법
 * 함수 선언 앞에 `infix`라는 키워드를 붙여 선언하면 사용 할 수 있다.
 */

fun main(args: Array<String>): Unit {
    for (a in 0..9) print("$a ")
    println()

    // downTo
    for (b in 10 downTo 1) print("$b ")
    println()

    for (c in 10 downTo 1 step 2) print("$c ")
    println()

    /**
     * 마지막 값은 포함 안시키고 싶을면
     */
    val array: Array<Int> = arrayOf(1, 2, 3)
    for (i in 0 until array.size) println(array[i])
    //        0 ..    3

    val strList = arrayListOf<String>("Hello", "Monguse", "welcome!")
    for (str in strList) println(str)
    for ((index, value) in strList.withIndex()) println("$index - $value")

    // Map
    val perInfo: TreeMap<String, String> = TreeMap<String, String>()
    perInfo["name"] = "Monguse"
    perInfo["age"] = "23"
    perInfo["city"] = "Daegu"
    for ((key, value) in perInfo) println("$key : $value")
}

kotlin 同时在setOf中执行

同时在setOf中执行

InWhileDoWhile.kt
package my.demo

fun isLetter(c: Char) = c in 'a'..'z' || c in 'A'..'Z'
fun isNotDigit(c: Char) = c !in '0'..'9'

fun main(args: Array<String>): Unit {
    var x = 10
    val oneToTen: IntRange = 1..10
    println(oneToTen)

    while (x > 0) print("${x--} ")

    println()
    do {
        print("${x++} ")
    } while (x < 10)
    println()

    /**
     * `in` 연산자 조합은 숫자나 문자 범위에만 국한되지 않는다.
     * 비교가 가능한 (java.lang.Comparable 인터페이스를 구현한) 클래스라면
     * 그 객체로 범위를 만들 수 있다.
     */
    println("kotlin" in "Hello".."Monguse")
    println()

    /**
     * `in` 연산자는 컬렉션에도 사용될 수 있다.
     */
    val coll = setOf("Hello", "Monguse", "Welcome")
    println(coll)
    println("Kotlin" in coll)
    println("Monguse" in coll)
}

kotlin 如果是范围功能

如果是范围功能

IfWhen.kt
package my.demo

fun getMax(a: Int, b: Int): Int {
    var max = 0
    if (a < b) max = b else max = a
    return max
}

fun getMaxShort(a: Int, b: Int): Int = if (a < b) b else a

/**
 * 코틀린은 함수형 프로그래밍을 지원한다.
 *
 * 함수형 프로그래밍이란, 함수를 일반 값처럼 다룰 수 있도록 한 것이다.
 * 함수를 변수에 저장 할 수 있고, 함수를 매개 변수로 전달할 수도 있으며,
 * 함수에서 새로운 함수를 만들어 반환할 수도 있다.
 */
fun getMaxFuncType(a: Int, b: Int): Int {
    return if (a < b) {
        println("b bigger than a")
        b
    } else {
        println("a bigger than b")
        a // 블럭의 맨 마지막 식이 블럭의 반환 값이 된다. if 함수가 값을 만들어 반환 할 수 있기 때문에 코틀린에는 삼항 연산자가 없다.
    }
}

/**
 * when 함수
 */
fun printValue(a: Int): Unit {
    when (a) {
        1 -> println("value: 1")
        2 -> println("value: 2")
        3, 4 -> println("value is 3 or 4")
        else -> println("value is neither 1 nor 2") // default
    }
}

fun printValue(a: Int, str: String) {
    when (a) {
        str.toInt() -> println("str is a")
        else -> println("str is not a")
    }
}

fun printValue2(a: Int) {
    when (a) {
        in 1..10 -> println("1~10")
        in 11..20 -> println("11~20")
        else -> println("none of the above")
    }
}

// 코틀린은 함수형 프로그래밍 이므로 when 함수의 결과 값 역시 반환 값으로 사용될 수 있다.
fun hasPrefix(x: Any) = when (x) {
    /**
     * Smart Cast
     */
    is String -> x.startsWith("prefix")
    else -> false
}

/**
 * when 함수는 매개변수 없이도 사용할 수 있는데, 이 경우 조건문이 true 일 경우 해당 구문을 실행한다.
 */
fun checkValue(a: Int) {
    when {
//        a.isOdd() -> println("$a is odd")
//        a.isEven() -> println("$a is even")
//        else -> println("$a is funny")
    }
}

fun main(argv: Array<String>): Unit {
    printValue2(10)
}

kotlin kotlin?.let연산자

kotlin?.let연산자

let.kt
package my.demo

/**
 * let 함수
 */

fun DrawBitmap(bitmap: Bitmap) {
    println("DrawBitmap")
}

fun main(argv: Array<String>): Unit {
    var bitmap: Bitmap? = CreateBitmap(10, 10)

    /**
     * DrawBitmap 첫 번째 인자가 null이 될 수 있으므로 컴파일 오류
     *
     * http://blog.naver.com/PostView.nhn?blogId=yuyyulee&logNo=221232944884&parentCategoryNo=&categoryNo=22&viewDate=&isShowPopularPosts=true&from=search
     */
//    DrawBitmap(bitmap)

    bitmap?.let {
        DrawBitmap(it)
    }
}

kotlin 。? <br/> !! <br/>?:<br/>猫王运营商

。? <br/> !! <br/>?:<br/>猫王运营商

NullPointer.kt
package my.demo

/**
 * 모든 참조 변수가 Null 값을 가질 수 있는 자바와 달리, 코틀린의 참조 변수는 기본적으로 null 값을 가질 수 없는 `Non-null` 타입!
 *
 * ### null이 반활 되는 경우가 더 자연스러운 경우
 *
 * 비트맵 이미지를 만들어 반환하는 CreateBitmap() 함수의 경우, 반환 값이 생성된 Bitmap 객체여야 하겠지만,
 * 내부적으로 이미지 생성에 실패한 경우 생성되지 않은 Bitmap 객체를 반환하는 것 보다 Null을 반환하는 것이
 * 대응하기에 훨씬 유리하다.
 */

class Bitmap(val width: Int, val height: Int) {
    val size: Int
    get() = width * height

//    init {
//        size = width * height
//    }
    val map = ByteArray(size)
}

fun CreateBitmap(width: Int, height: Int): Bitmap? {
    if (width > 0 && height > 0) return Bitmap(width, height)
    else return null
}

/**
 * Safe Call의 장점 예시
 */
class Address(val st: String, val zipCode: Int, var city: String)
class Company(val name: String, val addr: Address?)
class Person(val name: String, val company: Company?)

fun main(argv: Array<String>) : Unit {
    val bitmap: Bitmap? = CreateBitmap(-1, 10)

    println(bitmap?.size)

    if (bitmap != null) {
        println(bitmap.size)
        println(bitmap.map)
    }

    /**
     * 절대 null이 아니야 `!!` 연산자
     */
    println(bitmap!!.size)

    // 안전한 호출(Safe Calls) 연산자
    // 안전한 호출 연산자는 `?.`로 표시하며 아래와 같이 사용한다
    fun Person.cityName(): String {
        val city: String? = this.company?.addr?.city
//        if (city != null) return city else "Unknown"
//        return city ?: "Unknown"

        return this.company?.addr?.city ?: "Unknown"
    }

    /**
     * Elvis Operator (?:)
     *
     * 왼쪽값이 null 이면 오른쪽 값
     */
    fun Person.cityName2(): String = this.company?.addr?.city ?: "Unknown"

    val person = Person("monguse", null)
    person.company?.addr?.city = "Seoul" // 안전한 호출의 연산자는 식의 왼쪽에도 사용될 수 있다.
}

kotlin 코틀린의NullPointer

코틀린의NullPointer

NullPointer.kt
package my.demo

/**
 * 모든 참조 변수가 Null 값을 가질 수 있는 자바와 달리, 코틀린의 참조 변수는 기본적으로 null 값을 가질 수 없는 `Non-null` 타입!
 *
 * ### null이 반활 되는 경우가 더 자연스러운 경우
 *
 * 비트맵 이미지를 만들어 반환하는 CreateBitmap() 함수의 경우, 반환 값이 생성된 Bitmap 객체여야 하겠지만,
 * 내부적으로 이미지 생성에 실패한 경우 생성되지 않은 Bitmap 객체를 반환하는 것 보다 Null을 반환하는 것이
 * 대응하기에 훨씬 유리하다.
 */

class Bitmap(val width: Int, val height: Int) {
    val size: Int
    get() = width * height

//    init {
//        size = width * height
//    }
    val map = ByteArray(size)
}

fun CreateBitmap(width: Int, height: Int): Bitmap? {
    if (width > 0 && height > 0) return Bitmap(width, height)
    else return null
}

fun main(argv: Array<String>) : Unit {
    val bitmap: Bitmap? = CreateBitmap(10, 10)
    if (bitmap != null) println(bitmap.size)
}

kotlin 확장함수의정이

확장함수의정이

ExtensionFunction.kt
package my.demo

/**
 * 확장 함수의 정의
 *
 * 어떤 클래스 밖에서, 마치 그 클래스의 멤버인 것 처럼 선언된 메서드를 말한다.
 * 클래스 내부에 있지 않지만 그 클래스 내부 멤버에 접근할 수 있고, 클래스 멤버 메서드와 동일한 방식으로 호출할 수 있다.
 */

class Calculator {
    var lastResult: Int = 0
    fun sum(a: Int, b: Int) = a + b
    fun minus(a: Int, b: Int) = a - b
}

// Calculator 클래스에 바로 접근 할 수 없다는 가정을 두고..
fun Calculator.sum(a: Int, b: Int, c: Int) = sum(a, b) + c // private 멤버나 protected 멤버에는 접근 할 수 없다.
fun Calculator.minus(a: Int) = -a

/**
 * 확장 프로퍼티
 *
 * 프로퍼티 역시 확장해서 사용할 수 있다.
 * 하지만 확장 프로퍼티는 필드를 가질 수 없기 때문에 값을 저장 할 수 없다.
 * 필드가 없기 때문에 기본 게터를 제공할 수 없으므로 반드시 커스텀 게터를 정의해 줘야 한다.
 */
val Calculator.signResult: Char
    get() = if (lastResult < 0) '-' else '+'

fun main(argv: Array<String>) : Unit {
    val calc = Calculator()
    println("1 + 2 = ${calc.sum(1, 2)}")
    println("2 - 1 = ${calc.minus(2, 1)}")
    println("1 + 2 + 3 = ${calc.sum(1, 2, 3)}")
    println("minus 1 = ${calc.minus(1)}")
}