티스토리 뷰
-새로은 모듈에서 작업 : file - New Module : phone&tablet / lab06 / empty activity
터치 이벤트, 클릭 이벤트 차이
-터치 : 액티비티 단위. up/down/touch. 드래그(drag)할 수 있음
-Keypad 이벤트 : 하드웨어. 자판기 키보드. Keyboard 이벤트 : 하드웨어적인 것. 전원버튼, 볼륨조절버튼, 네이게이션바
└프로그램적으로 올라오는 키패드는 Keyboard 이벤트가 아님(텍스트 에디터)
1. 터치 이벤트 - onTouchEvent()
(1) 터치 이벤트 종류
-Java의 case문과 동일 : when
-log.d()는 로그캣에 출력
-rawX, rawY는 화면 좌표
(1-1) MainActivity.kt
package com.example.lab06
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.MotionEvent
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
override fun onTouchEvent(event: MotionEvent?): Boolean { //Null 허용, 리턴형 boolean
when(event?.action){ //위에서 event Null허용해줬기 때문에 같이 맞춰줘야함.
MotionEvent.ACTION_DOWN -> {
Log.d("Android", "Touch down Event")
}
MotionEvent.ACTION_UP -> {
Log.d("Android", "Touch up Event")
}
}
return super.onTouchEvent(event)
}
}
>> 실행(pLay) : MainActivity 우클릭 실행
실행된 화면을 터치(클릭)하면 아래의 내용이 logcat에 찍힘.
2022-04-18 12:32:25.655 6831-6831/com.example.lab06 D/Android: Touch down Event 2022-04-18 12:32:25.758 6831-6831/com.example.lab06 D/Android: Touch up Event |
(1-2) 뷰바인딩(viewBinding) 설정
-build.gradle
viewBinding{
enabled=true
}
>> 저장 후 싱크(sync) 해줘야 적용됨.
-MainActivity.kt
package com.example.lab06
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.MotionEvent
import com.example.lab06.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val binder = ActivityMainBinding.inflate(layoutInflater)
setContentView(binder.root)
}
override fun onTouchEvent(event: MotionEvent?): Boolean { //Null 허용, 리턴형 boolean
when(event?.action){ //위에서 event Null허용해줬기 때문에 같이 맞춰줘야함.
MotionEvent.ACTION_DOWN -> {
Log.d("Android", "Touch down Event")
}
MotionEvent.ACTION_UP -> {
Log.d("Android", "Touch up Event")
}
MotionEvent.ACTION_MOVE -> {
Log.d("Android", "Touch Move Event x : ${event.x}, y:${event.y}")
}
}
return super.onTouchEvent(event)
}
}
└드래그했을 때, 좌표가 로그캣에 뜸.
(1-3) (1-1)와 똑같은 효과
-res/layout/activity_main.xml
textView의 아이디 tvResult
package com.example.lab06
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.MotionEvent
import com.example.lab06.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
lateinit var binding: ActivityMainBinding //★
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// setContentView(R.layout.activity_main)
val binder = ActivityMainBinding.inflate(layoutInflater)
setContentView(binder.root)
}
override fun onTouchEvent(event: MotionEvent?): Boolean { //Null 허용, 리턴형 boolean
when(event?.action){ //위에서 event Null허용해줬기 때문에 같이 맞춰줘야함.
MotionEvent.ACTION_DOWN -> {
Log.d("Android", "Touch down Event")
}
MotionEvent.ACTION_UP -> {
Log.d("Android", "Touch up Event")
}
MotionEvent.ACTION_MOVE -> {
binding.tvResult.text="Touch Move Event x : ${event.x}, y:${event.y}" //★
//Log.d("Android", "Touch Move Event x : ${event.x}, y:${event.y}")
}
}
return super.onTouchEvent(event)
}
}
└raw x, raw y : 화면 좌표
(2) 키(Key) 이벤트
-사용자가 폰의 키를 누르는 순간 발생. 텍스트에디터는 키(Key) 아님.
-키 이벤트에 해당하는 뒤로 가기 버튼(KEYCODE_BACK), 볼륨 버튼(KEYCODE_VOLUME_UP/DOWN), 전원 버튼 등등
(2-1) 콜백함수
onKeyDown | onKeyUp | onKeyLongPress |
키를 누른 순간 | 키를 떼는 순간 | 키를 오래 누르는 순간 |
볼륨 업/ 볼륨 다운 / 뒤로가기(Back) / 홈(Home) / 오버뷰(Overview)
>> New Project : Application06
-MainActivity.kt
package com.example.application06
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.KeyEvent
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
when(keyCode){
KeyEvent.KEYCODE_BACK -> Log.d("wsy", "Back Button을 눌렀습니다.")
KeyEvent.KEYCODE_VOLUME_UP -> Log.d("wsy", "Volume_up 버튼을 눌렀습니다.")
KeyEvent.KEYCODE_VOLUME_DOWN -> Log.d("wsy", "Volume_down 버튼을 눌렀습니다.")
}
return super.onKeyDown(keyCode, event)
}
}
-Log.d에 wsy 태그 넣은 것만 로그캣에서 출력하겠다는 뜻.
-MainActivity.kt
뒤로 가기 버튼(Back)만 따로 설정하려고 할 때,
package com.example.application06
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.KeyEvent
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
when(keyCode){
KeyEvent.KEYCODE_BACK -> Log.d("wsy", "Back Button을 눌렀습니다.")
KeyEvent.KEYCODE_VOLUME_UP -> Log.d("wsy", "Volume_up 버튼을 눌렀습니다.")
KeyEvent.KEYCODE_VOLUME_DOWN -> Log.d("wsy", "Volume_down 버튼을 눌렀습니다.")
}
return super.onKeyDown(keyCode, event)
}
override fun onBackPressed() {
Log.d("wsy", "Back Button Down")
super.onBackPressed()
}
}
(3) 뷰 이벤트 - 이벤트 소스 / 이벤트 핸들러
-이벤트 소스 : 이벤트가 발생한 객체
-이벤트 핸들러 : 이벤트 발생 시 실행할 로직이 구현된 객체. 이벤트 처리.
-리스터 : 이벤트 소스와 이벤트 핸들러를 연결해주는 함수 ex) setOnClickListener
리스너 연결을 어떤 형식으로 하는가??
(3-1) 리스너 연결 방식 1 : 익명 리스너
인터페이스 구현하는 클래스 만들지 않고, 인터페이스를 통해 클래스 생성 및 객체 생성까지 대체
간단하게 쓰기에는 편함. 버튼 1, 2개 정도?
// 이벤트소스.리스너(이벤트 핸들러 등록)(이벤트 핸들러:
binding.button.setOnClickListener(Object : View.OnClickListener {
binding.textView.setText("Button 1 클릭!")
})
-build.gradle : viewBinding
viewBinding{
enabled = true
}
>> sync(코끼리 아이콘) 해줘야 적용 됨.
-activity_main.xml
-버튼 클릭시 해당하는 버튼이 클리되었다는 문구 출력
<?xml version="1.0" encoding="utf-8"?>
<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:orientation="vertical"
tools:context=".MainActivity">
<Button
android:id="@+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button 1" />
<Button
android:id="@+id/button2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button 2" />
<Button
android:id="@+id/button3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button 3" />
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="TextView" />
</LinearLayout>
-mainactivity.kt
package com.example.application06
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.KeyEvent
import android.view.View
import com.example.application06.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
//binding
lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// setContentView(R.layout.activity_main)
//binding
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
//익명 리스너 : 구현과 동시에 객체 생성
binding.button.setOnClickListener(View.OnClickListener {
binding.textView.setText("Button 1 클릭!")
})
binding.button2.setOnClickListener(View.OnClickListener {
binding.textView.setText("Button 2 클릭!")
})
binding.button3.setOnClickListener(View.OnClickListener {
binding.textView.setText("Button 3 클릭!")
})
}
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
when(keyCode){
KeyEvent.KEYCODE_BACK -> Log.d("wsy", "Back Button을 눌렀습니다.")
KeyEvent.KEYCODE_VOLUME_UP -> Log.d("wsy", "Volume_up 버튼을 눌렀습니다.")
KeyEvent.KEYCODE_VOLUME_DOWN -> Log.d("wsy", "Volume_down 버튼을 눌렀습니다.")
}
return super.onKeyDown(keyCode, event)
}
override fun onBackPressed() {
Log.d("wsy", "Back Button Down")
super.onBackPressed()
}
}
>> 실행(play)
버튼 눌렀을 때, 해당하는 버튼에 따라 text 변경됨
<체크박스>
-activity_main.xml
체크박스 입력(디자인에서 드래그)
<?xml version="1.0" encoding="utf-8"?>
<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:orientation="vertical"
tools:context=".MainActivity">
...
<CheckBox
android:id="@+id/checkBox1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="사과" />
<CheckBox
android:id="@+id/checkBox2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="배" />
</LinearLayout>
>> 실행 : 사과 체크했을 때, 안 했을 때
-MainActivity.kt
사과, 배 체크했을때, 안 했을 때 이벤트 설정
//체크박스
//CompoundButton 자동완성시켰을 때, 2번째 것!!
binding.checkBox1.setOnCheckedChangeListener(CompoundButton.OnCheckedChangeListener { compoundButton, b ->
if(b){ //그냥도 true
binding.textView.setText(binding.checkBox1.text) //바인딩된 체크박스1의 텍스트를 -하라?
}else {
binding.textView.setText("None Checked")
}
})
binding.checkBox2.setOnCheckedChangeListener(CompoundButton.OnCheckedChangeListener { compoundButton, b ->
if(b){ //그냥도 true
binding.textView.setText(binding.checkBox2.text) //바인딩된 체크박스1의 텍스트를 -하라?
}
else {
binding.textView.setText("None Checked")
}
})
-똑같은 효과를 replace로
package com.example.application06
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.KeyEvent
import android.view.View
import android.widget.CompoundButton
import com.example.application06.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
//binding
lateinit var binding: ActivityMainBinding
//
var str1 = ""
...
//체크박스
//CompoundButton 자동완성시켰을 때, 2번째 것!!
binding.checkBox1.setOnCheckedChangeListener(CompoundButton.OnCheckedChangeListener { compoundButton, b ->
if(b){ //그냥도 true
str1 += binding.checkBox1.text
}else {
str1=str1.replace(binding.checkBox1.text.toString(), "")
}
binding.textView.setText(str1)
})
binding.checkBox2.setOnCheckedChangeListener(CompoundButton.OnCheckedChangeListener { compoundButton, b ->
if(b){ //그냥도 true
str1 += binding.checkBox2.text
}else {
str1=str1.replace(binding.checkBox2.text.toString(), "")
}
binding.textView.setText(str1)
})
}
...
}
└체크(선택)했을 때, 텍스트뷰(textView)에 넣어주고 아닐 때 공백
→ 익명함수 사용할 때, 하나하나 다 만들어줘야 함. 귀찮음.
(3-2) 리스너 연결 방식 2 : 액티비티에 이벤트 리스터 인터페이스 구현
-View.OnClickListener를 상속 및 구현 → override fun onCreate() 구현
package com.example.application06
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.KeyEvent
import android.view.View
import android.widget.CompoundButton
import com.example.application06.databinding.ActivityMainBinding
//(3-2) 액티비티에 이벤트 리스너 인터페이스 구현. 이벤트 핸들러 직접 구현 ↓
class MainActivity : AppCompatActivity(), View.OnClickListener {
//binding
lateinit var binding: ActivityMainBinding
//
var str1 = ""
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// setContentView(R.layout.activity_main)
//binding
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
//(3-2)
binding.button.setOnClickListener(this) //this - Mainactivity
binding.button2.setOnClickListener(this)
binding.button3.setOnClickListener(this)
}
// 액티비티에 이벤트 리스너 인터페이스 구현
//(3-2) 버튼 눌렀을 때 설정
override fun onClick(p0: View?) { //어떤 뷰를 클릭했는가?
when(p0){ //id에 따라 -> 아래와 같이 처리하시오.
binding.button -> binding.textView.text="버튼1 클릭!"
binding.button2 -> binding.textView.text="버튼2 클릭!"
binding.button3 -> binding.textView.text="버튼3 클릭!"
}
}
}
(+) 체크박스 구현
package com.example.application06
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.KeyEvent
import android.view.View
import android.widget.CompoundButton
import com.example.application06.databinding.ActivityMainBinding
//(3-2) 액티비티에 이벤트 리스너 인터페이스 구현. 이벤트 핸들러 직접 구현
class MainActivity : AppCompatActivity(), View.OnClickListener, CompoundButton.OnCheckedChangeListener {
//binding
lateinit var binding: ActivityMainBinding
//
var str1 = ""
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// setContentView(R.layout.activity_main)
//binding
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
//(3-2-checkBox)
binding.checkBox1.setOnCheckedChangeListener(this)
binding.checkBox2.setOnCheckedChangeListener(this)
//체크박스
//CompoundButton 자동완성시켰을 때, 2번째 것!!
//익명 리스너 : 구현과 동시에 객체 생성
// binding.checkBox1.setOnCheckedChangeListener(CompoundButton.OnCheckedChangeListener { compoundButton, b ->
// if(b){ //그냥도 true
// str1 += binding.checkBox1.text
// }else {
// str1=str1.replace(binding.checkBox1.text.toString(), "")
// }
// binding.textView.setText(str1)
// })
// binding.checkBox2.setOnCheckedChangeListener(CompoundButton.OnCheckedChangeListener { compoundButton, b ->
// if(b){ //그냥도 true
// str1 += binding.checkBox2.text
// }else {
// str1=str1.replace(binding.checkBox2.text.toString(), "")
// }
// binding.textView.setText(str1)
// })
}
override fun onCheckedChanged(p0: CompoundButton?, p1: Boolean) {
when(p0){
binding.checkBox1 -> {
if (p1){
str1 += binding.checkBox1.text
}else{
str1 = str1.replace(binding.checkBox1.text.toString(), "")
}
}
binding.checkBox2 -> {
if (p1){
str1 += binding.checkBox2.text
}else{
str1 = str1.replace(binding.checkBox2.text.toString(), "")
}
}
}
binding.textView.setText(str1)
}
}
(3-3) 리스너 연결 방식 3 : 이벤트 리스너 클래스 작성_default 방법
-이걸 간단하게 하기 위해 (2)번 방법이나 (1)으로 사용.
-MainActivity 밖에 만들 수도 안에 만들 수도 있음. 바깥에보다 안에 클래스 만드는게 좋음. 뷰 바인딩을 MainActivity에 했기 때문에.
바깥에다가 클래스를 만들면 뷰바인딩을 별도로 보내줘야 함.
새 패키지 / 새 액티비티 생성
-activity_test1.xml
<?xml version="1.0" encoding="utf-8"?>
<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"
tools:context=".test1.Test1Activity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/button6"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button" />
<Button
android:id="@+id/button7"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button" />
<TextView
android:id="@+id/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="TextView" />
</LinearLayout>
</LinearLayout>
-MainActivity.kt
++++++++++++++++++++++++++++
package로 만들면 binding이 잘 안 됨....ㅠㅠ
[ New Module ] 로 하면 됨. - lab6Check
+++++++++++++++++++++++++++CheckBox 실습++++++++++++++++++++++
build.gradle(Module lab6Check)
android {
compileSdk 32
...
viewBinding{
enabled=true
}
}
-activity_test2.xml
<?xml version="1.0" encoding="utf-8"?>
<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"
tools:context=".Test2Activity"
android:orientation="vertical">
<CheckBox
android:id="@+id/checkBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="복숭아" />
<CheckBox
android:id="@+id/checkBox2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="블루베리" />
<CheckBox
android:id="@+id/checkBox3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="딸기" />
</LinearLayout>
-Test2Activity.kt
package com.example.lab6check
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.CompoundButton
import com.example.lab6check.databinding.ActivityTest2Binding
var data = 0
class Test2Activity : AppCompatActivity() {
lateinit var binding: ActivityTest2Binding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// setContentView(R.layout.activity_test2)
binding = ActivityTest2Binding.inflate(layoutInflater) //자동완성2
setContentView(binding.root)
binding.checkBox.setOnCheckedChangeListener(MyCheckedBoxEventHandler(binding))
binding.checkBox2.setOnCheckedChangeListener(MyCheckedBoxEventHandler(binding))
binding.checkBox3.setOnCheckedChangeListener(MyCheckedBoxEventHandler(binding))
}
}
class MyCheckedBoxEventHandler(binding: ActivityTest2Binding):CompoundButton.OnCheckedChangeListener{
lateinit var binding: ActivityTest2Binding
init {
this.binding = binding
}
override fun onCheckedChanged(p0: CompoundButton?, p1: Boolean) {
// TODO("Not yet implemented")
when(p0){
binding.checkBox -> {
if(p1){
data += 10000
}else{
data -= 10000
}
}
binding.checkBox2 -> {
if(p1){
data += 10000
}else{
data -= 10000
}
}
binding.checkBox3 -> {
if(p1){
data += 10000
}else{
data -= 10000
}
}
}
}
}
(3-3) 리스너 연결 방식 3 : SAM 기법으로 구현
-Single Abstract Method
-람다 방식으로 간단하게 표현. 매개변수와 실행문만 있음.
-New Module lab06_1
└뷰바인딩 먼저 : build.gradle(Module : )
android {
...
viewBinding{
enabled=true
}
}
└버튼 입력 - 위치 고정?(2방향) - textView의 id : textView
(4) 클릭 / 롱클릭 이벤트 처리
(4-1) 버튼 입력 및 textView id 설정
-[ Design ]에서 버튼 드래그, textView 아이디 입력
(4-2) MainActivity.kt
package com.example.lab06_1
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import com.example.lab06_1.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// setContentView(R.layout.activity_main)
//뷰 바인딩
val binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
//클릭과 롱클릭
binding.button.setOnClickListener {
binding.textView.setText("버튼 클릭!")
}
binding.button.setOnLongClickListener {
binding.textView.setText("Long~~~~~ Click")
true //리턴 타입이 불리언이라 리턴타입을 붙여줘야 함.
}
//롱클릭 : 단축 메뉴사용할 때
}
}
(5) 실습: 스톱워치 만들기
(5-1) drawable :img 등의 소스뿐만 아니라 xml 파일로도 만들 수 있음.
-New : drawable resource file - name : round_button(대문자 불가)
-round_button.xml 파일에서 [라운드 버튼] 만들기
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:padding="10dp"
android:shape="rectangle">
<solid android:color="#01A9DB"/>
<corners
android:bottomLeftRadius="15dp"
android:bottomRightRadius="5dp"
android:topLeftRadius="5dp"
android:topRightRadius="15dp"/>
</shape>
└30은 너무 과해서 수정했음.
-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">
<!--스톱워치-->
<Chronometer
android:id="@+id/chronemeter"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="200dp"
android:gravity="center_horizontal"
android:textSize="60dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
>> 수평 레이아웃 입력
>> 버튼 3개 입력
[ Code ]에서 수정 : layout_weight="1" 삭제 / 위치 수정 / 만든 버튼 입력
-버튼 아이디 수정 및 버튼 내용(android:text) 수정
-enabled : 활성화/비활성화 - 기본값은 true
android:enabled="true | false"
<?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">
<!--스톱워치-->
<Chronometer
android:id="@+id/chronemeter"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="200dp"
android:gravity="center_horizontal"
android:textSize="60dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="1dp"
android:layout_marginTop="60dp"
android:gravity="center_horizontal"
android:orientation="horizontal"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/chronemeter">
<Button
android:id="@+id/btnStart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/round_button"
android:textColor="#ffffff"
android:textSize="20dp"
android:text="START" />
<Button
android:id="@+id/btnStop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/round_button"
android:textColor="#ffffff"
android:textSize="20dp"
android:enabled="false"
android:text="STOP" />
<Button
android:id="@+id/btnReset"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/round_button"
android:textColor="#ffffff"
android:textSize="20dp"
android:enabled="false"
android:text="RESET" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
-MainActivity.kt
package com.example.lab06_1
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.os.SystemClock
import android.view.View
import com.example.lab06_1.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
//스톱워치를 위한 변수
var iniTime = 0L //초기시간 저장하는 것.
var pauseTime = 0L //일시정지했을 때 시간 저장하는 것
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// setContentView(R.layout.activity_main)
//뷰 바인딩
val binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
//스톱워치
//start button 눌렀을 때 설정
binding.btnStart.setOnClickListener {
binding.chronometer.base = SystemClock.elapsedRealtime()+pauseTime //베이스 시간
binding.chronometer.start()
binding.btnStop.isEnabled = true
binding.btnReset.isEnabled = true
binding.btnStart.isEnabled = false
}
//Stop button 눌렀을 때 설정
binding.btnStop.setOnClickListener {
pauseTime = binding.chronometer.base - SystemClock.elapsedRealtime() //elapsedRealtime() 1/1000초
binding.chronometer.stop()
binding.btnStop.isEnabled = false
binding.btnReset.isEnabled = true
binding.btnStart.isEnabled = true
}
//Reset button 눌렀을 때 설정
binding.btnReset.setOnClickListener {
pauseTime = 0L
binding.chronometer.base = SystemClock.elapsedRealtime()
binding.chronometer.stop()
binding.btnStop.isEnabled = false
binding.btnReset.isEnabled = false
binding.btnStart.isEnabled = true
}
}
}
(6) 실습 : 계산기
-activity_main.xml : 보여지는 것 그리기
<?xml version="1.0" encoding="utf-8"?>
<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:orientation="vertical"
android:paddingTop="30dp"
tools:context=".test1.CalcActivity">
<TextView
android:id="@+id/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="4dp"
android:gravity="right"
android:text="0.0"
android:paddingRight="15dp"
android:textSize="25dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<GridLayout
android:layout_gravity="center_horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="1dp"
android:layout_marginTop="11dp"
android:orientation="horizontal"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView2">
<Button
android:id="@+id/b1"
android:layout_marginRight="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_row="0"
android:layout_column="0"
android:textSize="20dp"
android:text="C" />
<Button
android:id="@+id/b2"
android:layout_marginRight="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_row="0"
android:layout_column="1"
android:textSize="20dp"
android:text="(" />
<Button
android:id="@+id/b3"
android:layout_marginRight="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_row="0"
android:layout_column="2"
android:textSize="20dp"
android:text=")" />
<Button
android:id="@+id/b4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_row="0"
android:layout_column="3"
android:textSize="20dp"
android:text="+" />
<Button
android:id="@+id/b5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_row="1"
android:layout_column="0"
android:textSize="20dp"
android:text="7" />
<Button
android:id="@+id/b6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_row="1"
android:layout_column="1"
android:textSize="20dp"
android:text="8" />
<Button
android:id="@+id/b7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_row="1"
android:layout_column="2"
android:textSize="20dp"
android:text="9" />
<Button
android:id="@+id/b8"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_row="1"
android:layout_column="3"
android:textSize="20dp"
android:text="-" />
<Button
android:id="@+id/b9"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_row="2"
android:layout_column="0"
android:textSize="20dp"
android:text="4" />
<Button
android:id="@+id/b10"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_row="2"
android:layout_column="1"
android:textSize="20dp"
android:text="5" />
<Button
android:id="@+id/b11"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_row="2"
android:layout_column="2"
android:textSize="20dp"
android:text="6" />
<Button
android:id="@+id/b12"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_row="2"
android:layout_column="3"
android:textSize="20dp"
android:text="*" />
<Button
android:id="@+id/b13"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_row="3"
android:layout_column="0"
android:textSize="20dp"
android:text="1" />
<Button
android:id="@+id/b14"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_row="3"
android:layout_column="1"
android:textSize="20dp"
android:text="2" />
<Button
android:id="@+id/b15"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_row="3"
android:layout_column="2"
android:textSize="20dp"
android:text="3" />
<Button
android:id="@+id/b17"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_row="3"
android:layout_column="3"
android:textSize="20dp"
android:text="/" />
<Button
android:id="@+id/b18"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_row="4"
android:layout_column="0"
android:textSize="20dp"
android:text="%" />
<Button
android:id="@+id/b19"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_row="4"
android:layout_column="1"
android:textSize="20dp"
android:text="0" />
<Button
android:id="@+id/b20"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_row="4"
android:layout_column="2"
android:textSize="20dp"
android:text="." />
<Button
android:id="@+id/b21"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_row="4"
android:layout_column="3"
android:textSize="20dp"
android:text="=" />
</GridLayout>
</LinearLayout>
-CalcActivity.kt
package com.example.lab06_1.test1
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.View
import android.widget.Button
import com.example.lab06_1.R
import com.example.lab06_1.databinding.ActivityCalcBinding
import java.util.*
class CalcActivity : AppCompatActivity() {
//view Binding
lateinit var binding: ActivityCalcBinding
//Calculator Array
lateinit var btnArray: Array<Button?>
var resultStr = ""
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// setContentView(R.layout.activity_calc)
//view Binding
binding = ActivityCalcBinding.inflate(layoutInflater)
setContentView(binding.root)
//Calculator Array
btnArray = arrayOf(binding.b1, binding.b2, binding.b3, binding.b4, binding.b5, binding.b6,
binding.b7, binding.b8, binding.b9, binding.b10, binding.b11, binding.b12, binding.b13,
binding.b14, binding.b18, binding.b19, binding.b20, binding.b21, binding.b25, binding.b27)
//for문 Event 처리
for(i in 0..19){
btnArray[i]?.setOnClickListener { //이거 빠져서 계속 값을 못 가져왔던 것.
var result = 0.0
var str1 = btnArray[i]?.text //전역 변수 btnArray 바로 가져와서 사용?
when(str1){
"=" -> {
//먼저 토큰 생성
val tokStr = StringTokenizer(resultStr, "+-*/", true) //토크나이저, 구분자(로 문자열을 구분)
Log.d("parkA","tokStr:${tokStr.countTokens()}")
val num1 = tokStr.nextToken().toDouble()
var op = tokStr.nextToken()
var num2 = tokStr.nextToken().toDouble()
when(op){
"+" -> result = num1 + num2
"-" -> result = num1 - num2
"*" -> result = num1 * num2
"/" -> result = num1 / num2
}
binding.textView2.setText(result.toString()) //결과를 문자열로 바꿔서 넣음
resultStr = result.toString()
}
"C" -> {
resultStr=""
binding.textView2.setText("0.0")
}else -> {
resultStr += btnArray[i]?.text
binding.textView2.setText(resultStr)
}
}
}
}
}
}
>> 버튼 만들 때, 빵꾸나서 다시 만들었는데
그로 인해서 nullPoint 때문에 계속 안 되는 듯. 한번 만들 때, 충돌이 발생하면 계속 충돌 발생....
'수업 > └리액트(React)' 카테고리의 다른 글
[00]컴포넌트 실습 - 시간에 따라 출력문 변경 (0) | 2022.04.21 |
---|---|
[00]리액트 - 컴포넌트(component) (0) | 2022.04.20 |
[00]react 기초 개념_리액트 구성 (0) | 2022.04.20 |
[01]리액트 개념과 ES6 문법2 (0) | 2022.04.15 |
[01]리액트 개념과 ES6 문법 (0) | 2022.04.14 |
- Total
- Today
- Yesterday
- html pre
- border-spacing
- caption-side
- text formatting
- initialized
- typeof
- scanner
- css
- CascadingStyleSheet
- BAEKJOON
- 기본선택자
- html input type
- html a tag
- 변수
- 미디어 태그
- selcetor
- 입력양식
- improt
- 스크립태그
- JavaScript
- html base tag
- Java
- A%B
- html
- empty-cell
- ScriptTag
- 외부구성요소
- html layout
- input type 종류
- html atrribute
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |