- 뷰: UI 구성요소의 기본 클래스이면서 화면을 구성하는 기본 단위이다. 뷰의 종류로는 버튼, 텍스트뷰, 이ㅂ미지뷰 같은 위젯과 컨스트레인트 레이아웃, 리니어 레이아웃과 같은 뷰 그룹이 있다.
- 위젯(뷰): 위젯은 화면에 직접적으로 보이고 사용자와 상호작용하는 구성요소이다. 위젯은 뷰 그룹에 속해야 한다. 텍스트뷰, 버튼, 에디트텍스트 등의 위젯을 통해 사용자의 이벤트를 처리하고 정보를 보여준다. 위젯을 편의상 뷰라고 부르다.
- 뷰 그룹(레이아웃): 뷰 그룹은 한 개 이상의 뷰 혹은 다른 뷰 그룹을 담고 뷰들을 배치하는 역할을 한다. 뷰 그룹을 레이아웃이라고도 부른다. 뷰 그룹을 레이아웃으로 부르겠다.
activity_patch9.xml
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:background="@drawable/ic_launcher_background"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="안녕하세요"/>
<Button
android:background="@drawable/ic_launcher_background"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="안녕하세요"/>
<Button
android:background="@drawable/ic_launcher_background"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="안녕하세요"/>
<Button
android:background="@drawable/ic_launcher_background"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="안녕하세요"/>
<Button
android:background="@drawable/ic_launcher_background"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="안녕하세요"/>
<Button
android:background="@drawable/ic_launcher_background"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="안녕하세요"/>
<Button
android:background="@drawable/ic_launcher_background"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="안녕하세요"/>
<Button
android:background="@drawable/ic_launcher_background"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="안녕하세요"/>
</LinearLayout>
</ScrollView>
activity_padding_and_margin.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#D7FAEA"
android:text="패딩, 마진 둘 다 없음"
android:textSize="20sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#4B653B"
android:text="패딩, 마진 둘 다 없음"
android:textColor="#FFFFFF"
android:textSize="20sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="15dp"
android:background="#D7FAEA"
android:text="마진만 있음"
android:textSize="20sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="15dp"
android:background="#4B653B"
android:text="마진만 있음"
android:textColor="#FFFFFF"
android:textSize="20sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#D7FAEA"
android:padding="10dp"
android:text="패딩만 있음"
android:textSize="20sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="15dp"
android:background="#D7FAEA"
android:padding="10dp"
android:text="패딩, 마진 둘 다 있음"
android:textSize="20sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="15dp"
android:background="#D7FAEA"
android:padding="10dp"
android:text="패딩, 마진 둘 다 있음"
android:textColor="#FFFFFF"
android:textSize="20sp" />
</LinearLayout>
sample_textview.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="안녕하세요. 조이스입니다."
android:textColor="#000000"
android:textSize="20sp"
android:textStyle="bold" />
</LinearLayout>
values/colors.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorMain">#000000</color>
<color name="colorSub">#25A632</color>
</resources>
values/strings.xml
<resources>
<string name="app_name">LearningViews</string>
<string name="greeting">안녕하세요 조이스입니다.</string>
</resources>
sample_textview.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/greeting"
android:textColor="@color/colorMain"
android:textSize="20sp"
android:textStyle="bold" />
</LinearLayout>
activity_value_text.xml
<?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="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/greeting"
android:textColor="@color/colorMain"
android:textSize="20sp"
android:textStyle="bold" />
</LinearLayout>
values/strings.xml
<resources>
<string name="app_name">LearningViews</string>
<string name="greeting">Hello, My name is Joyce.</string>
</resources>
values-ja/string.xml
<resources>
<string name="app_name">学習ビュー</string>
<string name="greeting">こんにちは、ジョイスです。</string>
</resources>
values-ko/string.xml
<resources>
<string name="app_name">뷰를 배웁니다.</string>
<string name="greeting">안녕하세요 조이스입니다.</string>
</resources>
sample_imageview.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/sample_img"
android:scaleType="center"
/>
</LinearLayout>
activity_matrix.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center">
<ImageView
android:id="@+id/imageView"
android:src="@drawable/katz"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="matrix"/>
</FrameLayout>
MatrixActivity.kt
package com.example.learningviews
import android.graphics.Matrix
import android.graphics.Outline
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.view.ViewOutlineProvider
import android.view.animation.Animation
import android.view.animation.RotateAnimation
import android.widget.ImageView
class MatrixActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_matrix)
// ImageView 참조
val imageView = findViewById<ImageView>(R.id.imageView)
imageView.post {
// 이미지의 중심점을 계산
val pivotX = imageView.width / 2f
val pivotY = imageView.height / 2f
// 이미지 회전을 위한 Matrix 객체 생성
val matrix = Matrix().apply {
postRotate(45f, pivotX, pivotY)
}
// Matrix 적용
imageView.imageMatrix = matrix
}
// 원형 모양으로 이미지 뷰 설정
imageView.outlineProvider = object : ViewOutlineProvider() {
override fun getOutline(view: View, outline: Outline) {
// 이미지 크기에 맞는 원형 영역 정의
val size = Math.min(view.width, view.height)
outline.setOval(0, 0, size, size)
}
}
imageView.clipToOutline = true
imageView.setOnClickListener {
// 360도 회전 애니메이션
val rotateAnimation = RotateAnimation(
0f, 360f,
Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f
).apply {
duration = 1000
repeatCount = 0
}
imageView.startAnimation(rotateAnimation)
}
}
}
sample_edittext.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Hello World라고 입력해주세요."
android:padding="10dp"
android:layout_margin="10dp"
/>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="비밀번호를 입력해주세요."
android:inputType="textPassword"
android:padding="10dp"
android:layout_margin="10dp"
/>
</LinearLayout>
- 리니어 레이아웃: 수직 방향 혹은 수평 방향 차례로 주어진 뷰를 정렬한다.
- 상대적 레이아웃: 상대적 레이아웃을 사용하면 뷰들이 다른 뷰들로부터 위치를 지정하거나 자신이 속한 레이앙수을 기준으로 위치를 정한다. 예를 들면 'A 뷰의 오른쪽에 위치', '부모 레이아웃의 정중아에 위치'와 같이 지정할 수 있다.
- 컨스트레인트 레이아웃: 뷰 사이에 수평, 수직 방향의 제약을 주어 뷰들을 위치시킨다.
- 테이블 레이아웃: 뷰를 행과 열로 구성하여 표의 형태로 표현한다.
- 프레임 레이아웃: 뷰들을 액자처럼 쌓아놓는다. 여러 뷰들을 추가하더라도 가장 나중에 추가한 뷰가 가장 위에 위치하게 되는 것이다. 레이아웃 내에 여러 뷰들을 배치시키는데는 적합하지 않고 주로 화면에 표시될 하나의 뷰를 바꿔가며 표시하는데 적합하다.
linear_layout_1.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="button1" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="button2" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="button3" />
</LinearLayout>
linear_layout_2.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:text="button1" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="button2" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:text="button3" />
</LinearLayout>
linear_layout_3.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:text="button1" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="button2" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:text="button3" />
</LinearLayout>
linear_layout_4.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="4">
<Button
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:text="1" />
<Button
android:layout_width="0dp"
android:layout_weight="2"
android:layout_height="wrap_content"
android:text="2" />
<Button
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:text="1" />
</LinearLayout>
relative_layout_1.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:text="parent/nstart" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:text="parent/nend" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:text="parent bottom" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:text="parent bottom\n + parent end" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="parent/ncenter" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:text="center/nhorizontal" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:text="center/nvertical" />
</RelativeLayout>
relative_layout_2.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/standard_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:text="기준 1" />
<Button
android:id="@+id/standard_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="기준 2" />
<Button
android:id="@+id/standard_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:text="기준 3" />
</RelativeLayout>
constraint_layout_1.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<Button
android:id="@+id/button_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="32dp"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="100dp"
android:text="Button 1"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toEndOf="@id/button_1"
app:layout_constraintBotton_toBottomOf="@id/button_1"
app:layout_constraintTop_toTopOf="@id/button_1"
android:layout_marginStart="32dp"
android:text="버튼을 클릭해주세요!"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
constraint_layout_2.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<Button
android:id="@+id/button_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="100dp"
android:text="Button 1"/>
<Button
android:id="@+id/button_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toEndOf="@id/button_1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/button_1"
android:text="Button 2" />
</androidx.constraintlayout.widget.ConstraintLayout>
constraint_layout_3.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<TextView
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#ff7e67"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@id/vertical"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/horizontal"
android:text="LEFT"
android:gravity="center"
android:textSize="30dp" />
<TextView
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#006a71"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@+id/vertical"
app:layout_constraintTop_toTopOf="@+id/horizontal"
android:text="RIGHT"
android:gravity="center"
android:textSize="30dp" />
<TextView
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="#A0CAC7"
app:layout_constraintBottom_toBottomOf="@id/horizontal"
app:layout_constraintTop_toTopOf="parent"
android:text="TOP"
android:gravity="center"
android:textSize="30dp" />
<androidx.constraintlayout.widget.Guideline
android:id="@id/horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.3" />
<androidx.constraintlayout.widget.Guideline
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@id/vertical"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.4" />
</androidx.constraintlayout.widget.ConstraintLayout>
colors.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="purple_200">#FFBB86FC</color>
<color name="purple_500">#FF6200EE</color>
<color name="purple_700">#FF3700B3</color>
<color name="teal_200">#FF03DAC5</color>
<color name="teal_700">#FF018786</color>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
<color name="blue">#603CFF</color>
<color name="red">#FF6767</color>
<color name="yellow">#E1BF5A</color>
</resources>
strings.xml
<resources>
<string name="app_name">StopWatch</string>
<string name="start">시작</string>
<string name="pause">일시정지</string>
<string name="refresh">초기화</string>
</resources>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
tools:context=".MainActivity">
<TextView
android:id="@+id/tv_minute"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="00"
android:textSize="45sp"
/>
<TextView
android:id="@+id/tv_second"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=":00"
android:textSize="45sp"
/>
<TextView
android:id="@+id/tv_millisecond"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=".00"
android:textSize="30sp"
/>
<Button
android:id="@+id/btn_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginBottom="80dp"
android:padding="20dp"
android:backgroundTint="@color/blue"
android:text="@string/start"
android:textColor="@color/white"
android:textSize="16sp"
android:textStyle="bold"
/>
<Button
android:id="@+id/btn_refresh"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="@+id/btn_start"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:layout_margin="50dp"
android:padding="20dp"
android:backgroundTint="@color/yellow"
android:text="@string/refresh"
android:textColor="@color/white"
android:textSize="16sp"
android:textStyle="bold"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
MainActivity.kt
package com.example.stopwatch
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.widget.Button
import android.widget.TextView
class MainActivity : AppCompatActivity(), View.OnClickListener {
var isRunning = false
private lateinit var btn_start: Button
private lateinit var btn_refresh: Button
private lateinit var tv_millisecond: TextView
private lateinit var tv_second: TextView
private lateinit var tv_minute: TextView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
btn_start = findViewById(R.id.btn_start)
btn_refresh = findViewById(R.id.btn_refresh)
tv_millisecond = findViewById(R.id.tv_millisecond)
tv_second = findViewById(R.id.tv_second)
tv_minute = findViewById(R.id.tv_minute)
btn_start = findViewById(R.id.btn_start)
btn_refresh = findViewById(R.id.btn_refresh)
tv_millisecond = findViewById(R.id.tv_millisecond)
tv_second = findViewById(R.id.tv_second)
tv_minute = findViewById(R.id.tv_minute)
btn_start.setOnClickListener(this)
btn_refresh.setOnClickListener(this)
}
override fun onClick(v: View?) {
when(v?.id) {
R.id.btn_start -> {
if(isRunning) {
pause()
} else {
start()
}
}
R.id.btn_refresh -> {
refresh()
}
}
}
private fun start() {
}
private fun pause() {
}
private fun refresh() {
}
}
MainActivity.kt
package com.example.stopwatch
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.widget.Button
import android.widget.TextView
import java.util.Timer
class MainActivity : AppCompatActivity(), View.OnClickListener {
var isRunning = false
var timer : Timer? = null
var time = 0
private lateinit var btn_start: Button
private lateinit var btn_refresh: Button
private lateinit var tv_millisecond: TextView
private lateinit var tv_second: TextView
private lateinit var tv_minute: TextView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
btn_start = findViewById(R.id.btn_start)
btn_refresh = findViewById(R.id.btn_refresh)
tv_millisecond = findViewById(R.id.tv_millisecond)
tv_second = findViewById(R.id.tv_second)
tv_minute = findViewById(R.id.tv_minute)
btn_start = findViewById(R.id.btn_start)
btn_refresh = findViewById(R.id.btn_refresh)
tv_millisecond = findViewById(R.id.tv_millisecond)
tv_second = findViewById(R.id.tv_second)
tv_minute = findViewById(R.id.tv_minute)
btn_start.setOnClickListener(this)
btn_refresh.setOnClickListener(this)
}
override fun onClick(v: View?) {
when(v?.id) {
R.id.btn_start -> {
if(isRunning) {
pause()
} else {
start()
}
}
R.id.btn_refresh -> {
refresh()
}
}
}
private fun start() {
btn_start.text = "일시정지"
btn_start.setBackgroundColor(getColor(R.color.red))
isRunning = true
timer = timer(period = 10) {
time++
val milli_second = time % 100
val second = (time % 6000) / 100
val minute = time / 6000
runOnUiThread {
if(isRunning) {
tv_millisecond.text = if (milli_second < 10)
".0${milli_second}" else ".${milli_second}"
tv_second.text = if(second < 10) ":0${second}" else ":${second}"
tv_minute.text = "${minute}"
}
};
tv_millisecond.text =
if (milli_second < 10) ".0${milli_second}" else ".${milli_second}"
tv_second.text = if(second < 10) ":0${second}" else ":${second}"
tv_minute.text = "${minute}"
}
}
private fun pause() {
}
private fun refresh() {
}
}
MainActivity.kt 일부
private fun pause() {
btn_start.text = "시작"
btn_start.setBackgroundColor(getColor(R.color.blue))
isRunning = false
timer?.cancel()
}
MainActivity.kt 일부
private fun refresh() {
timer?.cancel()
btn_start.text = "시작"
btn_start.setBackgroundColor(getColor(R.color.blue))
isRunning = false
time = 0
tv_millisecond.text = ".00"
tv_second.text = ":00"
tv_minute.text = "00"
}
MainActivity.kt
package com.example.stopwatch
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import android.view.View
import android.widget.Button
import android.widget.TextView
import java.util.Timer
import kotlin.concurrent.timer
class MainActivity : AppCompatActivity(), View.OnClickListener {
var isRunning = false
var timer: Timer? = null // O timer 변수 추가
var time = 0
private lateinit var btn_start: Button
private lateinit var btn_refresh: Button
private lateinit var tv_minute: TextView
private lateinit var tv_second: TextView
private lateinit var tv_millisecond: TextView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
btn_start = findViewById(R.id.btn_start)
btn_refresh = findViewById(R.id.btn_refresh)
tv_minute = findViewById(R.id.tv_minute)
tv_second = findViewById(R.id.tv_second)
tv_millisecond = findViewById(R.id.tv_millisecond)
btn_start.setOnClickListener(this)
btn_refresh.setOnClickListener(this)
}
override fun onClick(view: View?) {
when (view?.id) {
R.id.btn_start -> {
if (isRunning) {
pause()
} else {
start()
}
}
R.id.btn_refresh -> {
refresh()
}
}
}
private fun start() {
btn_start.text = resources.getText(R.string.pause)
btn_start.setBackgroundColor(getColor(R.color.red))
isRunning = true // 실행 상태 변경
// 스톱워치를 시작하는 로직
timer = timer(period = 10) {
time++ // 10 밀리초 단위 타이머
/*
e. 01:15:15 ==> 75.15초
ms --> 7515 % 100 = 15 ms
second --> 7515 / 100 % 60 = 15 second
minutes --> 7515 / 100 / 60 = 1 minutes
*/
// 시간 계산
val milli_second = time % 100
val second = time / 100 % 60
val minute = time / 100 / 60
runOnUiThread {
if (isRunning) {
tv_millisecond.text = ",%02d".format(milli_second)
tv_second.text = ":%02d".format(second)
tv_minute.text = "%02d".format(minute)
}
}
}
}
private fun refresh() {
timer?.cancel()
btn_start.text = resources.getText(R.string.start)
btn_start.setBackgroundColor(getColor(R.color.blue))
isRunning = false // 멈춤 상태로 변경
// 타이머 초기화
time = 0
tv_millisecond.text = ",00"
tv_second.text = ":00"
tv_minute.text = "00"
}
private fun pause() {
btn_start.text = resources.getText(R.string.start)
btn_start.setBackgroundColor(getColor(R.color.blue))
isRunning = false
timer?.cancel()
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
tools:context=".MainActivity">
<TextView
android:id="@+id/tv_minute"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:text="00"
android:textSize="45sp"
app:layout_constraintBaseline_toBaselineOf="@+id/tv_second"
app:layout_constraintEnd_toStartOf="@+id/tv_second"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="parent" />
<TextView
android:id="@+id/tv_second"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="219dp"
android:text=":00"
android:textSize="45sp"
app:layout_constraintEnd_toStartOf="@+id/tv_millisecond"
app:layout_constraintStart_toEndOf="@+id/tv_minute"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_millisecond"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="9dp"
android:text=".00"
android:textSize="30sp"
app:layout_constraintBottom_toBottomOf="@+id/tv_second"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/tv_second" />
<Button
android:id="@+id/btn_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="80dp"
android:backgroundTint="@color/blue"
android:padding="20dp"
android:text="@string/start"
android:textColor="@color/white"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="@+id/btn_refresh"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="50dp"
android:backgroundTint="@color/yellow"
android:padding="20dp"
android:text="@string/refresh"
android:textColor="@color/white"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintBottom_toTopOf="@+id/btn_start"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>