android studio ver. 3.1.4
kotlin_version = 1.2.60



switchCompat 예제입니다.

아래와 같은 이미지를 구성하기 위해서 우선 xml 을 작성하였습니다.


 


<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/lay_push"
        android:padding="20dp"
        android:foreground="?android:attr/selectableItemBackground">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="start|center_vertical"
            android:text="알림설정" />

        <android.support.v7.widget.SwitchCompat
            android:id="@+id/sc_push"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="end|center_vertical"
            android:checked="true"/>

    </FrameLayout>
</android.support.constraint.ConstraintLayout>


java 코드 작성

초기화는 open 으로 작성하였습니다.
아직 코틀린 문법이 if 문을 자바 스타일로 작성하였더니 에러는 아니지만, 노란줄이 생겼어요
그래서 아래 이미지처럼 바꿔 주었어요



아래와 같이 클릭으로 토글하는 간단한 예제를 작성하여 보았습니다. 
Framelayout 을 클릭시에는 performClick 으로 토글시켜보았습니다. 
이렇게 작성을 해보니, setOnCheckedChangeListener 안에서는 워닝 메시지가 나옵니다. "RenameTo _" 
 scPush.setOnCheckedChangeListener { buttonView, isChecked -> }
 이것을 
scPush.setOnCheckedChangeListener { _, isChecked -> } 이렇게 변경을 했어요.
class SplashActivity : AppCompatActivity(), View.OnClickListener {

    private lateinit var scPush: SwitchCompat    // lateinit 지연초기화
    private var init: String = "N"

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

        // lay 클릭시 토글
        val lay: FrameLayout = findViewById(R.id.lay_push)
        lay.setOnClickListener(this)

        // 스위치 버튼
        scPush = findViewById(R.id.sc_push)
        scPush.isChecked = init == "Y"

        scPush.setOnCheckedChangeListener { buttonView, isChecked ->
            i("scPush isChecked , ", isChecked)
            init = if (isChecked) { // on
                "Y"
            } else {    // off
                "N"
            }
            i("scPush init , ", init)
        }
    }

    override fun onClick(v: View) {
        when (v.id) {
            R.id.lay_push -> {
                d("lay_push onClick , ", init)
                scPush.performClick()
                /*init = if(init == "Y") {
                    "N"
                } else {
                    "Y"
                }
                scPush.isChecked = init == "Y"*/
            }
        }
    }
}

결과 화면





android studio ver. 3.1.2
kotlin_version = 1.2.51

Util 과 같은 클래스 안에 static method 를 만들어 놓고,

전역에서 호출하여 사용할 수 있습니다. 코틀린은 static 이 없다고 하니, 펑션 만 만들어 줍니다.

public class Utils_j {

    public static void load(String value) {
        Log.i("trip_", "method load : "+ value);
    }
}

코틀린으로 변환 해 보았습니다.

object Utils {

    fun load(value: String) {
        Log.i("trip_", "method load : $value")
    }
}

// 실행
override fun onClick(v: View?) {
        when(v?.id) {
            R.id.iv -> {
                Utils_j.load("java test")

                Utils.load("kotlin test")

            }
        }
    }


결과




여기까지는 kotlin file 에서 kotlin file 을 접근했을 때이고,

만약 java file > kotlin file 로 접근 해서 fun 호출 하게 되면 좀 더 다른점을 볼수 있어요.
Logger 라는 코틀린 파일을 만들어서 테스트를 진행 해보았습니다. 


object Logger {

    private const val TAG = "trip_"

    /** Log Level Information  */
    fun i(vararg message: Any) {
        if (BuildConfig.DEBUG) Log.i(TAG, buildLogMsg(*message))
    }

    /** Log Level Debug  */
    fun d(vararg message: Any) {
        if (BuildConfig.DEBUG) Log.d(TAG, buildLogMsg(*message))
    }
}

// 자바에서 kotlin 펑션을 호출
@Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.iv:
                Logger.INSTANCE.d("kotlin input test");
            break;
        }
    }


Logger.d 이런식으로는 사용이 안되게 되어 있고, INSTANCE 가 붙어서 싱글톤 형태여야 쓸 수 있는 의미가 됩니다.

그래서 전 그냥 Logger.d 로 쓰고 싶어요 한다면 여러가지 방법이 있겠습니다.


우선 아래 코드 처럼 object Logger { } 부분을 지우면
LoggerKt.d() 로 사용할 수가 있어요.

//object Logger {

    private const val TAG = "trip_"

    /** Log Level Information  */
    fun i(vararg message: Any) {
        if (BuildConfig.DEBUG) Log.i(TAG, buildLogMsg(*message))
    }

    /** Log Level Debug  */
    fun d(vararg message: Any) {
        if (BuildConfig.DEBUG) Log.d(TAG, buildLogMsg(*message))
    }
//}

// 자바에서 kotlin 펑션을 호출
@Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.iv:
                //Logger.INSTANCE.d("kotlin input test");
                LoggerKt.d("kotlin input test");
            break;
        }
    }


LoggerKt.d() 로 사용하는 것이 불편할 수 있습니다. 제가 그래요.


Logger.d() 로 쓰고 싶다면
아래 코드 처럼 @file:JvmName("Logger") 라고 추가 해주면 Logger.d() 의 형태로 사용 할 수 있게 되었습니다.

@file:JvmName("Logger")

package example.kr.myapplication

//object Logger {

    private const val TAG = "trip_"

    /** Log Level Information  */
    fun i(vararg message: Any) {
        if (BuildConfig.DEBUG) Log.i(TAG, buildLogMsg(*message))
    }

    /** Log Level Debug  */
    fun d(vararg message: Any) {
        if (BuildConfig.DEBUG) Log.d(TAG, buildLogMsg(*message))
    }
//}

// 자바에서 kotlin 펑션을 호출
@Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.iv:
                //Logger.INSTANCE.d("kotlin input test");
                //LoggerKt.d("kotlin input test");
                Logger.d("kotlin input test");
            break;
        }
    }





android studio ver. 3.1.2
kotlin_version = 1.2.51


변수 정의에 대해 알아보겠습니다.

먼저 java로 다음과 같이 int, String 변수를 만들었습니다.

public class Global_j {

    static int num = 3456;
    static String name = "trip";
}
코틀린으로 변환 하였습니다.

object Global {
    internal var num = 3456
    internal var name = "trip"
}

// 실행 코드
override fun onClick(v: View?) {
        when(v?.id) {
            R.id.iv -> {
                Log.d("trip_", "java num : "+ Global_j.num + " , name : "+ Global_j.name)
                Log.i("trip_", "kotlin num : "+ Global.num + " , name : "+Global.name)

            }
        }
    }
결과 화면은 다음과 같습니다.



internal 은 접근 제어자 이며, 이외에 public, private, protected 로 쓸수 있습니다. 아무것도 없으면 public 으로 인식합니다.

이외에 변수 앞에 var, val 의 차이는 아래의 이미지 처럼
var 는 수정 가능 (변수로 사용)
val 은 수정 불가 (상수로 사용) 다른 값을 넣어보려고 시도 하면 에러가 발생합니다.




val 만 적었을 경우, 원하는 동작은 하지만 warring 메시지가 나오게 됩니다.




java 호환 어쩌구 저쩌구 ...

그래서 const 를 붙여주라네요.


아래는 추가적인 부분을 출력해보았어요
var name4 에서 보면 null을 넣기 위해서는 ? 따로 추가해줘야 됩니다

object Global { internal val num = 3456 internal val name = "trip" val num2 = 5678 val name2 = "store" const val name3:String = "ts" const val num3:Int = 8888 const val num3f:Float = 1.0F const val num3d:Double = 2.0 const val type:Boolean = true //var name4:String = null var name4:String? = null } // 실행 override fun onClick(v: View?) { when(v?.id) { R.id.iv -> { Log.d("trip_", "java num : "+ Global_j.num + " , name : "+ Global_j.name) Log.i("trip_", "kotlin num : "+ Global.num + " , name : "+Global.name) Log.i("trip_", "kotlin2 num : "+ Global.num2 + " , name : "+Global.name2) //Global.num = 9999 //Global.name2 = "trip_store" Log.i("trip_", "kotlin3 num : "+ Global.num3 + " , name : "+Global.name3) Log.i("trip_", "kotlin3 num3f : "+ Global.num3f + " , num3d : "+Global.num3d) Log.i("trip_", "kotlin3 type : "+ Global.type+ " , name4 : "+Global.name4) } } }

출력


+ Recent posts