데이터 바인딩 & 두 번 눌러 종료하기

변현섭·2023년 8월 10일
0
post-thumbnail

이번 포스팅에서 만들어볼 것은 가위바위보 게임 어플리케이션입니다. 앱에 대해 간단히 소개하면, 가위바위보에서 지는 사람이 커피를 사면 되는 매우 간단한 어플리케이션입니다. 이 포스팅을 통해 학습하고자 하는 내용은 데이터 바인딩과 Back버튼 두 번 눌러 종료하기입니다.

1. 레이아웃 구성하기

① RockScissorPaper라는 이름의 프로젝트를 생성한다.

② activity_main.xml 파일의 레이아웃을 LinearLayout으로 변경한다.

③ 배경색을 검은색으로 설정해보자.

  • 색깔 표현 역시 css와 동일하다.
  • 색깔의 16진수 표현식이 궁금하면, "{원하는 색} hex"를 검색하면 된다.
<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:background="#000000"
    android:orientation="vertical"
    tools:context=".MainActivity">

④ 자식 LinearLayout을 추가한 후, TextView 태그를 넣는다.

  • 글자의 크기는 dp보다 sp를 사용하는 것이 좋다.
  • 화면의 크기에 따라 줄바꿈이 저절로 되지만, 화면 크기에 무관하게 항상 줄을 바꾸고 싶으면 \n을 쓰면 된다.
<LinearLayout
	android:layout_width="match_parent"
    android:layout_height="200dp"
    android:layout_marginTop="100dp">

    <TextView
    	android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="30sp"
        android:text="가위바위보에서 진\n 사람이 커피 사기"
        android:textColor="#ffffff"
        android:textStyle="bold"
        android:layout_margin="20dp"
        android:gravity="center"/>
</LinearLayout>

⑤ drawable 디렉토리 하위로 가위바위보 이미지를 넣은 후, 이번엔 ImageView를 포함한 자식 LinearLayout 컨테이너를 생성한다.

  • layout_weight="1"을 사용하면 이미지의 개수에 맞게 비율을 공평하게 나눌 수 있다.
<LinearLayout
	android:layout_width="match_parent"
    android:layout_height="120dp">
    <ImageView
    	android:src="@drawable/paper"
        android:layout_width="120dp"
        android:layout_height="120dp"
        android:layout_weight="1"/>
    <ImageView
        android:src="@drawable/scissors"
        android:layout_width="120dp"
        android:layout_height="120dp"
        android:layout_weight="1"/>
</LinearLayout>

⑥ 가위바위보를 시작할 버튼을 생성한다. (별도의 자식 LinearLayout 안에 둘 필요는 없다)

<Button
	android:id="@+id/startButton"
	android:layout_width="match_parent"
    android:layout_height="50dp"
    android:background="#FF0008"
    android:textColor="#ffffff"
    android:text="가위바위보 시작"
    android:layout_marginLeft="50dp"
    android:layout_marginRight="50dp"
    android:layout_marginTop="120dp"/>

2. 데이터 바인딩하기

XML 레이아웃에 정의된 요소들에 접근하는 것을 데이터 바인딩이라 하는데, 그 동안은 findViewById를 사용했었다. 이번 포스팅에서는 layout을 이용한 데이터 바인딩 방식을 사용해보기로 하자.

① build.gradle.kts(Module :app)에 들어가 kotlinOptions 아래에 코드를 추가하고, Sync Now를 클릭해주자.

kotlinOptions {
	jvmTarget = "1.8"
}
buildFeatures{
    dataBinding = true
}

② 데이터 바인딩을 사용하기 위해 activity_main.xml 파일을 layout 컨테이너로 감싼다.

  • 직접 layout 컨테이너로 감싸주지 않아도, 최상단 뷰에 우클릭 > Convert to data binding layout을 클릭하여 데이터 바인딩을 사용할 수 있다.
<?xml version="1.0" encoding="utf-8"?>
<layout>
    <LinearLayout
    ...
    </LinearLayout>
</layout>

③ MainActivity 파일에 아래의 코드를 작성한다.

private lateinit var binding : ActivityMainBinding

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

    binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
    binding.startButton.setOnClickListener {
    	Toast.makeText(this, "안내면 진거 가위바위보!", Toast.LENGTH_SHORT).show()
    }
}
  • private lateinit var binding: binding을 선언하는 방식
  • binding = DataBindingUtil.setContentView(this, R.layout.activity_main): 레이아웃과 데이터 바인딩 수행
  • DataBindingUtil.setContentView: binding 변수를 통해 레이아웃 내의 요소들에 접근 가능

④ activity_main.xml 파일에서 가위바위보 이미지에 id를 넣는다.

<ImageView
	android:id="@+id/person_1"
    android:src="@drawable/paper"
    android:layout_width="120dp"
    android:layout_height="120dp"
    android:layout_weight="1"/>
<ImageView
    android:id="@+id/person_2"
    android:src="@drawable/scissors"
    android:layout_width="120dp"
    android:layout_height="120dp"
    android:layout_weight="1"/>

⑤ MainActivity에서 person1과 person2를 바인딩하고 Random하게 가위바위보를 선택하게 하자.

val image1 = binding.person1
val image2 = binding.person2

binding.startButton.setOnClickListener {
	Toast.makeText(this, "안내면 진거 가위바위보!", Toast.LENGTH_SHORT).show()
    val number1 = Random.nextInt(1, 4)
    val number2 = Random.nextInt(1, 4)
    if(number1 == 1) {
    	image1.setImageResource(R.drawable.rock)
    }
    else if(number1 == 2) {
        image1.setImageResource(R.drawable.scissors)
    }
    else {
        image1.setImageResource(R.drawable.paper)
    }

    if(number2 == 1) {
        image2.setImageResource(R.drawable.rock)
    }
    else if(number2 == 2) {
        image2.setImageResource(R.drawable.scissors)
    }
    else {
        image2.setImageResource(R.drawable.paper)
    }
}

코드를 실행시켜보면 버튼을 누를 때마다 가위바위보를 할 수 있게 된다.

3. Back 버튼 더블 클릭 시에만 종료되도록 구현하기

지금까지는 Back 버튼을 한번만 눌러도 앱이 종료되는 형태였는데, 이제부터는 메인화면에서 Back 버튼을 두 번 눌러야만 앱이 종료되도록 변경해보겠다.

① 더블 클릭을 확인할 수 있도록 isDouble 변수를 생성한다. binding을 선언한 곳과 같은 곳에 선언하면 된다. 참고로, 값이 나중에 변경되어야 할 경우, val이 아닌 var을 써야 한다.

private lateinit var binding : ActivityMainBinding
private var isDouble = false

② 뒤로가기 버튼을 눌렀을 때 호출될 메서드를 정의한다.

override fun onBackPressed() {
	if(isDouble)
    	finish()

	isDouble = true
	Toast.makeText(this, "종료하시려면 한번 더 눌러주세요.", Toast.LENGTH_SHORT).show()
    Handler().postDelayed(Runnable {
    	isDouble = false;
    }, 2000)
}

코드를 실행해보면, 뒤로 가기 버튼을 두 번 눌러야만 앱이 종료되는 것을 확인할 수 있다.

profile
Java Spring, Android Kotlin, Node.js, ML/DL 개발을 공부하는 인하대학교 정보통신공학과 학생입니다.

0개의 댓글