사실 공식문서에서 안내하는 방법에서는 아주 기본적인 것만을 다루기 때문에 그렇게 어렵지는 않았다. 그러나 내가 주목한 점은 kotlin이 제공해주는 함수(?) 같은것을 사용하여 코드를 간결하게 작성하는 것과, 안드로이드 스튜디오의 기능을 활용해서 onClick에 대해서 별도로 정의하지 않고 사용했다는 것에 주목했다. 또 저번 프로젝트에서는 findViewById를 사용하지 않고 ViewBinding을 이용했는데, 공식문서의 첫 튜툐리얼에서는 findViewById로 사용하도록 안내했다. 이점도 주목해서 생각해 볼 필요가 있을 것 같았다.
# 완성된 앱 미리보기
위와 같이 첫 xml에서는 메시지를 입력받고, 그 메시지를 Send하게 되면 다음 레이아웃으로 그 메시지를 전달시키는 로직이다.
# Layout 작성하기 (xml)
## Layout의 구조
레이아웃은 View로 구성한다 View는 화면상에서 보이는거와 같은 버튼이나 텍스트 입력창 등등 유저가 상호작용하며 보이는 것들인데, 이러한 것들을 ViewGroup으로 또 묶을 수 있다. ViewGroup은 쉽게 말해 컨테이너 와 같은 역할을 하고 이것들이 바로 Layout이다. 즉 Layout은 View를 담는데 어떤식으로 정렬시킬지 속성을 가지고 있다.
## ConstraintLayout
해당 레이아웃은 요소간에 제약조건을 걸어 배치할 수 있도록 하는 것이다. 저번에 ConstraintLayout에 정확한 사용법을 모르고 야매로 보여지는대로 막 연결시켰는데 이번에는 그렇게 하지 않고, 차근차근 하나씩 알아갈 생각이다.
## activity_main.xml에 위젯 추가하기
해당 xml에서는 입력을 받는 EditText위젯과 전송을 담당할 Button위젯이 필요하기 때문에 Palette에서 두개의 위젯을 추가해준다.
그리고 EditText위젯은 왼쪽과 위쪽에 16dp로 제약조건을 걸어준다.
Button위젯은 왼쪽을 EditText오른쪽에 제약조건을 걸어준 후, 마우스 오른쪽 버튼을 눌러 Show Baseline을 클릭 후 EditText와 연결시켜준다. 이렇게 하면 글자를 기준으로 정렬시킬 수 있다. 아래 그림과 같게 된다.
## string.xml
각 위젯에 들어가는 string들에 대해서는 해당파일에서 일괄적으로 관리시킨다. 아직 정확하게 어떤 규칙을 따르는지는 잘 모르겠다.
//string.xml
<string name="app_name">MyFirstApp</string>
이제껏 저렇게 그냥 타이핑 했었는데, 공식문서는 Translations Editor을 사용해서 string을 추가 시켰다. 뭔가 번역에 관련되서 자동화를 할 수 있는거 같았다.
Open editor을 눌러서
왼쪽 상단의 ' + ' 을 누른 후
Key 와 Value에 각각 값을 넣어주면 된다. Key는 해당 string을 찾아올때 사용되는 이름이고, value는 안에 들어가는 내용이 된다.
# Activity작성하기
해당 액티비티에서 할 일은, Send버튼을 누르는 것에 대한 정의가 필요하고, 버튼을 눌렀다면 EditText에 있는 값을 불러와 다음 액티비티로 넘겨주는 일을 한다.
## onClick 정의하기
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
/** Called when the user taps the Send button */
fun sendMessage(view: View) {
// Do something in response to button
}
}
난 여기서 onClick을 정의하는 방법에 신선함을 느꼈다. 내부적으로 어떻게 처리되는지 의문이긴 했다.
저렇게 sendMessage함수를 정의시킨후 버튼을 정의한 xml로 가서 attribute에서 onClick을 찾아 선택해주면, 해당 함수와 버튼이 연결 됐다.
## sendMessage함수 작성
fun sendMessage(view: View) {
val editText = findViewById<EditText>(R.id.editTextTextPersonName)
val message = editText.text.toString()
val intent = Intent(this, DisplayMessageActivity::class.java).apply {
putExtra("EXTRA_MESSAGE", message) // 키-값 형태로 데이터 전달
}
startActivity(intent)
}
Intent는 액티비티간의 연결을 도모한다고 설명할 수 있다. Intent의 인자로는 보내지는 액티비티에서-> 받는액티비티를 위와같이 인자르 지정해준다. putExtra로는 키-값 형태로 값을 보내면, 받는 액티비티에서 키값을 사용하여 받아서 사용할 수 있게 된다.
나는 그냥 string형식으로 키값을 지정해줬지만
const val EXTRA_MESSAGE = "com.example.myfirstapp.MESSAGE"
이렇게 상수로 정의시키는게 더 좋은 것 같다.
### apply{...}
또 여기서 .apply {...}에 대해서 처음 알게 됐다. 저렇게 한 후 안에다가 코드를 바로 지정해줘서 적용시키는 모습이다. 찾아본 결과 Kotiln의 문법중 하나인데 객체이름을 생성과 동시에 초기화 할때 사용한다고 한다.
굉장히 잘 정리해주셨다. 코드를 복잡하지 않고 잘 줄일 수 있는 방법이 될 거 같다.
# DisplayMessage
파일명 DisplayMessageActivity를 Empty Activity를 선택하여 만들어준다. 그러면 자동으로 activity_display_message.xml이 생성될 것이다. 이제 전달받은 message를 띄우는 액티비티를 만들어 보자.
## activity_display_message.xml
이번엔 마우스 우클릭하여 자동으로 수평정렬해 주는 기능을 사용해 봤다. 그리고 위에 제약관계를 16만큼 준다.
## DisplayMessageActivity.kt
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_display_message)
// Get the Intent that started this activity and extract the string
val message = intent.getStringExtra("EXTRA_MESSAGE")
// Capture the layout's TextView and set the string as its text
val textView = findViewById<TextView>(R.id.textView).apply {
text = message
}
}
이제 키를 가져와 textView에 띄어주도록하자. 여기서도 apply가 쓰이는데 상당히 코드를 간결하게 만들어주는 좋은 도구 같다.
# 상향 탐색 추가
//AndroidManifest.xml
<activity android:name=".DisplayMessageActivity"
android:parentActivityName=".MainActivity">
<!-- The meta-data tag is required if you support API level 15 and lower -->
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".MainActivity" />
</activity>
이제 앱 실행을 해보고 확인해 보면 정상적으로 작동 함 을 알 수 있다.
공식문서의 FirstApp을 따라해보면서 아주 간단한 예제였지만 사용방법들에 대해서 어느정도 다시 떠올릴 수 있었다. 이번에는 야매가 아니라 조금 차근차근 공부해보보면서 체계적으로 알아보고싶다. 아키텍쳐나 생명주기를 준수하면서 말이다.