Anko 라이브러리
Kotlin 개발자가 개발한 Kotlin 전용 Android 개발 라이브러리이다. 그러나 현재는 더 이상 사용되지 않고 있다. this page로 들어가보면 Anko 라이브러리가 더 이상 쓰이지 않는 이유를 볼 수 있다. 그리고 Anko를 대신할 라이브러리들을 소개해준다.
지금은 Anko 라이브러리를 써보자...
dependency에 Anko 추가한다.
implementation "org.jetbrains.anko:anko:$anko_version"
현재 anko_version이라는 변수값이 존재한다. 이 변수값은 Project 레벨의 Module에서 값을 추가해준다.
그리고 Sync Now 버튼을 클릭한다.
Main Activity Layout
1. 키(height)를 입력할 EditText 추가
- layout_width : match_parent 또는 0dp로 설정을 한다.
- inputType : 키를 입력할 곳이기 때문에 "number"로 설정한다.
- hint : 하드코딩을 해도 좋으나, string.xml에 값을 넣어서 불러온다.
2. 몸무게(weight)를 입력할 EditText 추가
hint 값을 짧게 바꿨다 ㅎㅎ
- layout_constraintTop_toBottomOf : 키를 입력하는 EditText의 아래에 위치하도록 설정한다.
3. 계산을 실행할 Button 추가
이제 Button을 클릭했을 때 결과값을 새로운 Activity에서 보여주려 한다.
Result Ativity
1. Result Activity를 추가한다.
- Activity Name : ResultActivity
- Layout Name : activity_result
- Activity를 바로 추가한 것이기 때문에 manifests에 자동으로 추가된다.
2. Result Activity Layout에 결과값을 보여줄 TextView 추가
- textSize : 기기마다 다른 글자 크기를 대응하기 위해 sp 라는 단위를 사용한다.
- layout_constraintVertical_bias : 값을 설정하여 살짝 위쪽에 배치한다.
3. Vector Image 추가
원하는 클립아트를 선택하고 바로 추가한다.
이와 같은 방법으로 매우 불만족, 보통 표정의 클립아트를 2개 더 추가한다.
4. ImageView 추가
- tint : 이미지 위에 색상을 오버레이 해주는 기능이다.
개인적으로 민트 불호
5. Vector Image를 사용하기 위해 build.gradle 수정
Vector Image는 Vector Drawable로 따로 분류되기 때문에 build.gradle에 설정을 추가해야한다.
vectorDrawables.useSupportLibrary = true
그러면 activity_result.xml에서 오류가 발생한다.
오류 메시지에 따라 android:src="~~"
에서 app:srcCompat="~~~"
으로 바꿔주면 해결된다.
Main Activity에서 Button Click Listener 구현
1. Button의 Click Listener 추가
package com.example.bmicalculator
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
result_button.setOnClickListener {
// 버튼을 클릭했을 때 실행될 동작
}
}
}
import kotlinx.android.synthetic.main.activity_main.*
- Android Studio의 자동 완성 기능을 통해 위 import 문을 추가해준다.
- Kotlin의 Android 코드는 위 import 문을 통해 자동으로 뷰바인딩이 되기 때문에 더 간결하다.
2. Intent를 통해 ResultActivity로 이동
package com.example.bmicalculator
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_main.*
import android.content.Intent
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
result_button.setOnClickListener {
// 버튼을 클릭했을 때 실행될 동작
val intent = Intent(this, ResultActivity::class.java)
startActivity(intent)
}
}
}
위 코드를 Anko Library가 지원하는 코드로 바꿀 수 있다.
package com.example.bmicalculator
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_main.*
import android.content.Intent
import org.jetbrains.anko.startActivity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
result_button.setOnClickListener {
// 버튼을 클릭했을 때 실행될 동작
startActivity<ResultActivity>();
}
}
}
3. manifests를 수정하여 ResultActivity의 Toolbar에 Back Button 추가
android:parentActivityName=".MainActivity"
속성을 추가하여 Toolbar에 Back Button을 추가할 수 있다.
4. Intent를 통해 ResultActivity로 결과값 보내기
MainActivity
package com.example.bmicalculator
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_main.*
import android.content.Intent
import org.jetbrains.anko.startActivity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
result_button.setOnClickListener {
// 버튼을 클릭했을 때 실행될 동작
val intent = Intent(this, ResultActivity::class.java)
intent.putExtra("height", height_edittext.text.toString())
intent.putExtra("weight", weight_edittext.text.toString())
startActivity(intent)
}
}
}
ResultActivity
package com.example.bmicalculator
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Toast
class ResultActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_result)
val height = intent.getStringExtra("height").toInt()
val weight = intent.getStringExtra("weight").toInt()
Toast.makeText(this, "$height $weight", Toast.LENGTH_LONG).show()
}
}
이번엔 Anko Library를 사용해본다.
MainActivity
package com.example.bmicalculator
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_main.*
import android.content.Intent
import org.jetbrains.anko.startActivity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
result_button.setOnClickListener {
// 버튼을 클릭했을 때 실행될 동작
startActivity<ResultActivity>(
"height" to height_edittext.text.toString(),
"weight" to weight_edittext.text.toString())
}
}
}
ResultActivity
package com.example.bmicalculator
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Toast
import org.jetbrains.anko.toast
class ResultActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_result)
val height = intent.getStringExtra("height").toInt()
val weight = intent.getStringExtra("weight").toInt()
toast("$height $weight")
}
}
Logic 구현
BMI = 몸무게(weight)를 키(height)의 제곱으로 나눈 값
ResultActivity
package com.example.bmicalculator
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_result.*
import org.jetbrains.anko.toast
class ResultActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_result)
// Get Data from MainActivity
val height = intent.getStringExtra("height").toInt()
val weight = intent.getStringExtra("weight").toInt()
// Calculate BMI
val bmi = weight / Math.pow((height/100.0), 2.0)
// Show Result with TextView
when {
bmi >= 35 -> result_textview.text = "고도 비만"
bmi >= 30 -> result_textview.text = "2단계 비만"
bmi >= 25 -> result_textview.text = "1단계 비만"
bmi >= 23 -> result_textview.text = "과체중"
bmi >= 18.5 -> result_textview.text = "정상"
else -> result_textview.text = "저체중"
}
// Show Image
when {
bmi >= 23 -> result_imageview.setImageResource(R.drawable.ic_sentiment_dissatisfied_black_24dp)
bmi >= 18.5 -> result_imageview.setImageResource(R.drawable.ic_sentiment_satisfied_black_24dp)
else -> result_imageview.setImageResource(R.drawable.ic_sentiment_neutral_black_24dp)
}
toast("키: $height, 몸무게: $weight, BMI: $bmi")
}
}
결과
SharedPreference 사용
이번에는 ResultActivity에서 MainActivity로 돌아와도 값이 유지되도록 SharedPreference를 사용해서 값을 저장한다.
package com.example.bmicalculator
import android.os.Bundle
import android.preference.PreferenceManager
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_main.*
import org.jetbrains.anko.startActivity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Check Saved Data
loadData()
result_button.setOnClickListener {
// Save Data
saveData(height_edittext.text.toString().toInt(), weight_edittext.text.toString().toInt())
// Go To ResultActivity
startActivity<ResultActivity>(
"height" to height_edittext.text.toString(),
"weight" to weight_edittext.text.toString())
}
}
private fun loadData() {
val pref = PreferenceManager.getDefaultSharedPreferences(this)
val height = pref.getInt("KEY_HEIGHT", 0)
val weight = pref.getInt("KEY_WEIGHT", 0)
if(height != 0 && weight != 0) {
height_edittext.setText(height.toString())
weight_edittext.setText(weight.toString())
}
}
private fun saveData(height: Int, weight: Int) {
val pref = PreferenceManager.getDefaultSharedPreferences(this)
val editor = pref.edit()
editor.putInt("KEY_HEIGHT", height)
.putInt("KEY_WEIGHT", weight)
.apply()
}
}
SharedPreference는 Android 내부 저장소에 값을 저장해주는 기능으로, KEY&VALUE 쌍으로 데이터를 저장하고 불러온다.
코드를 입력해보면 PreferenceManager가 deprecated 된 것을 볼 수 있다.
Deprecated
위에서 PreferenceManager가 deprecated 상태인것을 확인하였다. 앱은 정상적으로 실행되지만, deprecated 된 PreferenceManager를 대신하여 어떤 것을 써야할까?
간단하게 androidx 패키지로 가서 사용하면 된다.
androidx.preference.PreferenceManager
1. implementaion 추가
Gradle에서 implementation을 추가해준다.
implementation "androidx.preference:preference-ktx:1.1.0"
2. 새로운 PreferenceManager 추가
위에서 구현했던 코드에서 import 부분을 수정하면 끝이다.
import android.preference.PreferenceManager // Before
import androidx.preference.PreferenceManager // After
이렇게 간단하게 BMI 계산기를 만들 수 있었다. 이전까지는 Java만 사용했었는데, Kotlin을 사용하니 신세계가 열린 느낌이다. Kotlin으로 얼른 완전히 환승해야겠다. ㅋㅋ
More Anko
Anko를 통해 코드만으로 UI를 만들 수 있다.(UI와 Logic을 하나로 합칠 수 있다.)
위 코드를 한 번 사용해보자.
package com.example.bmicalculator
import android.os.Bundle
import org.jetbrains.anko.*
import org.jetbrains.anko.sdk25.coroutines.onClick
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
verticalLayout {
val name = editText()
button("Say Hello") {
onClick { toast("Hello, ${name.text}!") }
}
}
}
}
결과에서 볼 수 있듯이 XML 파일을 수정하지 않고도 verticalLayout을 생성하고, editText와 button을 차례로 만들 수 있다. 다만, 위 코드를 쓰기 전까지 만들었던 코드와 같이 사용하면 이전에 사용한 코드에서 NullException이 발생한다. 따라서, Anko Layout 코드를 사용할 때는 그것만 사용하는 것이 좋을 것 같다.
'KoreaTech' 카테고리의 다른 글
[데이터베이스및실습] 데이터베이스 관리 시스템 (0) | 2020.04.03 |
---|---|
[데이터베이스및실습] 정보처리 시스템과 데이터베이스 (0) | 2020.04.02 |
[모바일 프로그래밍] string.xml을 통한 다국어 설정 + 국제화, Non-Translatable Setting (0) | 2020.03.31 |
[모바일 프로그래밍] Scratch (0) | 2020.03.30 |
[인터네트워킹] 2. 기본 네트워크 구축 (0) | 2019.09.12 |