Demo ứng dụng I Love You V2 bằng kotlin

Viblo

Giới thiệu

Trước đây mình có demo 1 ứng dụng I Love You bằng java , hôm nay mình sẽ nâng cấp và convert nó sang kotlin (ngôn ngữ mình đang tìm hiểu )

1. Main Activity

1.1. activity_main.xml

Chưa có gì đặc biệt , mình thiết kế giao diện đơn giản như trong hình thôi :

Code

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/background"
    tools:context="com.tuananh.iloveyouv2.MainActivity">

    <TextView
        android:id="@+id/text_i_love_you"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="@dimen/margin_padding_130"
        android:gravity="center_horizontal"
        android:padding="@dimen/margin_padding_5"
        android:text="EM CÓ YÊU ANH KHÔNG ?"
        android:textSize="@dimen/text_size_14"/>

    <Button
        android:id="@+id/buttonYes"
        android:layout_width="@dimen/size_button"
        android:layout_height="wrap_content"
        android:layout_below="@+id/text_i_love_you"
        android:layout_marginLeft="@dimen/margin_padding_30"
        android:layout_marginTop="@dimen/margin_padding_130"
        android:background="@drawable/selector_button_grey"
        android:text="Có"
        android:textAllCaps="false"/>

    <Button
        android:id="@+id/buttonNo"
        android:layout_width="@dimen/size_button"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_below="@+id/text_i_love_you"
        android:layout_marginRight="@dimen/margin_padding_30"
        android:layout_marginTop="@dimen/margin_padding_130"
        android:background="@drawable/selector_button_grey"
        android:text="Không"
        android:textAllCaps="false"/>
</RelativeLayout>

1.2. MainActivity

1.2.1. Cách khai báo listener ở kotlin

Điểm hay là tên button (buttonYes) là tên id trong xml luôn.

buttonYes.setOnClickListener {
          createDialog("Anh biết mà, <3", R.drawable.ic_oo)
      }
buttonNo.setOnTouchListener { _, event ->
          when (event.action) {
              MotionEvent.ACTION_DOWN -> {
                  move()
                  true
              }
              else -> false
          }
      }

1.2.2. Cách khởi tạo dialog với kotlin

  • Cách khai báo 1 view custom
val customDialog = CustomDialog(this, null, this) as LinearLayout
  • Truyền các tham số vào CustomDialog
customDialog.textMessage.text = message
customDialog.imageIcon.setImageResource(idIcon)

Code

private fun createDialog(message: String, idIcon: Int) {
        val builder = AlertDialog.Builder(this)
        val customDialog = CustomDialog(this, null, this) as LinearLayout
        customDialog.textMessage.text = message
        customDialog.imageIcon.setImageResource(idIcon)
        builder.setView(customDialog)
        builder.setCancelable(false)
        mAlertDialog = builder.show()
    }

1.2.3. Cách implement interface OnClickButtonListener

class MainActivity : AppCompatActivity(), OnClickButtonListener

và đây là hàm override được tạo ra khi implement interface OnClickButtonListener

override fun onDismiss() {
        mAlertDialog?.dismiss()
        mIndex = 0
        reset()
    }

Hàm trên sẽ ẩn dialog đi và thiết lập lại các thông số như ban đầu

Chú ý là : Dấu ? là cách check null

Kotlin :
mAlertDialog?.dismiss()
Java:
if(mAlertDialog != null){
    mAlertDialog.dismiss();
}

1.2.4. Function reset lại app như ban đầu

sẽ set lại tọa độ các button như lúc đầu và hiển thị lại buttonNo

private fun reset() {
        buttonYes.x = mX1
        buttonYes.y = mY
        buttonNo.x = mX2
        buttonNo.y = mY
        buttonNo.visibility = View.VISIBLE
    }

1.2.5. Function move()

1 số code bị thay đổi khi chuyển từ java sang kotlin Ví dụ như :

mIndex = mIndex < 7 ? mIndex += 1 : 1;

bị chuyển thành

 mIndex = if (mIndex < 7) mIndex + 1 else 1

Khi ấn vào buttonNo sẽ tăng index lên và thực hiện thay đổi vị trí của các buttonNo và buttonYes

  private fun move() {
//        mIndex = if (mIndex < 7) mIndex + 1 else 1
        if (mIndex < 7) {
            mIndex += 1
            if (mIndex == 7) {
                createDialog("Đã nghiện lại còn ngại !", R.drawable.ic_11)
                buttonNo.visibility = View.INVISIBLE
            }
        } else {
            mIndex = 1
        }
        when (mIndex) {
            0 -> reset()
            1 -> {
                buttonNo.y = buttonNo.y - resources.getDimensionPixelSize(R.dimen.margin_padding_100)
                mX1 = buttonYes.x
                mX2 = buttonNo.x
                mY = buttonYes.y
            }
            2 -> {
                buttonNo.y = buttonNo.y + resources.getDimensionPixelSize(R.dimen.margin_padding_100)
            }
            3 -> {
                buttonYes.x = mX2
                buttonNo.x = mX1
            }
            4 -> {
                buttonYes.x = mX1
                buttonNo.x = mX2
            }
            5 -> {
                buttonNo.y = buttonNo.y + resources.getDimensionPixelSize(R.dimen.margin_padding_100)
            }
            6 -> {
                buttonNo.y = buttonNo.y - resources.getDimensionPixelSize(R.dimen.margin_padding_200)
            }
            7 -> {
                buttonNo.y = buttonNo.y + resources.getDimensionPixelSize(R.dimen.margin_padding_100)
            }
        }
    }

Full code

package com.tuananh.iloveyouv2

import android.os.Bundle
import android.support.v7.app.AlertDialog
import android.support.v7.app.AppCompatActivity
import android.view.MotionEvent
import android.view.View
import android.widget.LinearLayout
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.dialog_message.view.*

class MainActivity : AppCompatActivity(), OnClickButtonListener {
    private var mAlertDialog: AlertDialog? = null
    private var mIndex = 0
    private var mX1 = 0.0f
    private var mX2 = 0.0f
    private var mY = 0.0f
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        buttonYes.setOnClickListener {
            createDialog("Anh biết mà, <3", R.drawable.ic_oo)
        }

        buttonNo.setOnTouchListener { _, event ->
            when (event.action) {
                MotionEvent.ACTION_DOWN -> {
                    move()
                    true
                }
                else -> false
            }
        }
    }

    private fun createDialog(message: String, idIcon: Int) {
        val builder = AlertDialog.Builder(this)
        val customDialog = CustomDialog(this, null, this) as LinearLayout
        customDialog.textMessage.text = message
        customDialog.imageIcon.setImageResource(idIcon)
        builder.setView(customDialog)
        builder.setCancelable(false)
        mAlertDialog = builder.show()
    }

    private fun move() {
//        mIndex = if (mIndex < 7) mIndex + 1 else 1
        if (mIndex < 7) {
            mIndex += 1
            if (mIndex == 7) {
                createDialog("Đã nghiện lại còn ngại !", R.drawable.ic_11)
                buttonNo.visibility = View.INVISIBLE
            }
        } else {
            mIndex = 1
        }
        when (mIndex) {
            0 -> reset()
            1 -> {
                buttonNo.y = buttonNo.y - resources.getDimensionPixelSize(R.dimen.margin_padding_100)
                mX1 = buttonYes.x
                mX2 = buttonNo.x
                mY = buttonYes.y
            }
            2 -> {
                buttonNo.y = buttonNo.y + resources.getDimensionPixelSize(R.dimen.margin_padding_100)
            }
            3 -> {
                buttonYes.x = mX2
                buttonNo.x = mX1
            }
            4 -> {
                buttonYes.x = mX1
                buttonNo.x = mX2
            }
            5 -> {
                buttonNo.y = buttonNo.y + resources.getDimensionPixelSize(R.dimen.margin_padding_100)
            }
            6 -> {
                buttonNo.y = buttonNo.y - resources.getDimensionPixelSize(R.dimen.margin_padding_200)
            }
            7 -> {
                buttonNo.y = buttonNo.y + resources.getDimensionPixelSize(R.dimen.margin_padding_100)
            }
        }
    }

    private fun reset() {
        buttonYes.x = mX1
        buttonYes.y = mY
        buttonNo.x = mX2
        buttonNo.y = mY
        buttonNo.visibility = View.VISIBLE
    }

    override fun onDismiss() {
        mAlertDialog?.dismiss()
        mIndex = 0
        reset()
    }
}

2. interface OnClickButtonListener

Dùng để bắt sự kiên click button "hi hi" của dialog

package com.tuananh.iloveyouv2

/**
 * Created by FRAMGIA\vu.tuan.anh on 23/10/2017.
 */
interface OnClickButtonListener {
    fun onDismiss()
}

3. CustomDialog

3.1 dialog_message.xml

Giao diện khi ấn button

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal"
        android:orientation="horizontal"
        android:paddingBottom="@dimen/margin_padding_10"
        android:paddingLeft="@dimen/margin_padding_5"
        android:paddingRight="@dimen/margin_padding_5"
        android:paddingTop="@dimen/margin_padding_20">

        <ImageView
            android:id="@+id/imageIcon"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>

        <TextView
            android:id="@+id/textMessage"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:layout_marginLeft="@dimen/margin_padding_10"
            android:textSize="@dimen/text_size_14"/>
    </LinearLayout>

    <Button
        android:id="@+id/buttonHiHi"
        android:layout_width="wrap_content"
        android:layout_height="30dp"
        android:layout_gravity="right"
        android:layout_marginBottom="@dimen/margin_padding_10"
        android:layout_marginRight="@dimen/margin_padding_20"
        android:background="@drawable/bg_button_white"
        android:text="Hi hi"
        android:textAllCaps="false"/>
</LinearLayout>

3.2. CustomDialog

Chú ý : Cách khai báo để dữ liệu truyền vào có thể null

 attrs: AttributeSet? 
onClickButtonListener: OnClickButtonListener? 

Full code

package com.tuananh.iloveyouv2

import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.widget.LinearLayout
import kotlinx.android.synthetic.main.dialog_message.view.*

/**
 * Created by FRAMGIA\vu.tuan.anh on 20/10/2017.
 */
class CustomDialog : LinearLayout {
    constructor(context: Context) : this(context, null)
    constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0, null)
    constructor(context: Context, attrs: AttributeSet?, onClickButtonListener: OnClickButtonListener?) : this(context, attrs, 0, onClickButtonListener)
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int, onClickButtonListener: OnClickButtonListener?) : super(context, attrs, defStyleAttr) {
        LayoutInflater.from(context).inflate(R.layout.dialog_message, this, true)
        buttonHiHi.setOnClickListener {
            onClickButtonListener?.onDismiss()
        }
    }
}

Hình ảnh

Hình ảnh

Source Code

Link

Tham khảo

https://www.programiz.com/kotlin-programming/interfaces https://kotlinlang.org/docs/reference/interfaces.html https://kotlinlang.org/docs/reference/object-declarations.html