[Android] - 계산기 만들기 (클론 코딩) -계산 기록 x

2022. 9. 17. 21:06· Skils/Android

 

저번에 혼자서 만들던 계산기가 DB를 연동해서 계산 기록을 저장하려고 했는데 굉장히 많은 오류가 생겨서 
새로 갈아 엎고 구글링을 하면서 코딩을 했다. 너무 슬펐다.

 

계산기의 디자인은 이렇다.[항상 느끼는 건데 디자인도 진짜 어려운 영역이다. ]

각 버튼의 기능은 계산기를 한 번이라도 써본 사람은 알 거라고 믿고 있기에 설명을 생략한다.

초기 디자인이다.

View를 사용해서 1대1로 화면을 나눴다. 

app:layout_constraintVertical_weight="num" // num:1으로 화면을 나누는 코드이다.

 

두 개의 textview를 만들어서 각각 input_text와 result_text를 입력받게끔 만들었다.

 

💻TableLayout

계산기 같이 같은 간격으로 같은 크기의 버튼을 넣어줄 때는 TableLayout이 굉장히 유용했다.

처음 계산기를 만들때는 TableLayout을 만들어주지 않고 수동으로 버튼을 생성한 다음 chain을 걸어줬지만 

이렇게 TableLayout으로 각 열마다 버튼을 붙이고 아래의 코드를 입력하면 알맞은 비율로 이쁘게 버튼이 들어간다.

android:shrinkColumns="*"

 

💡각각의 열마다 가중치를 둬서 비율을 정할수도 있다.

<TableRow android:layout_weight="1">

💡버튼의 모양은 drawble 폴더에서 xml 파일을 만들어서 바꿔줄 수 있다.

android:background="@drawble/파일경로"

💡그리고 각 버튼마다 onClick을 줘서 버튼이 클릭될 때마다 해당 함수를 실행하도록 만들 수도 있다.

android:onClick="함수명"

 

💡시계 모양의 버튼처럼 버튼 안에 이미지를 넣고 싶은 경우는 ImageButton을 사용하면 된다.

vector asset에 들어가서 넣고 싶은 이미지를 고르고 그 파일을 만든다.

android:src="@drawble/파일경로"

해당 버튼에 파일 경로에 해당하는 이미지가 버튼에 들어가게 된다.

 

🔎Button과 AppcompatButton의 차이!

일반적으로 Button을 선언하게 되면 Background 등 색깔과 모양이 안 바뀌는 오류가 생길 수도 있어서 대부분 AppcompaButton으로 Button을 선언한다고 한다!!

androidx.appcompat.widget.AppCompatButton

 

더 자세한 차이점은 아래 링크를 통해서 보면 될 것 같다.

Butotn과 AppcompatButton의 차이  

 

💡버튼의 음영을 제거하고 싶으면 아래의 코드를 입력!

 

android:stateListAnimator="@null"

 

위에서 버튼을 누르면 실행되는 함수를 android:onClick으로 줘야 한다고 설명했다.

fun buttonClicked(v: View) {
when (v.id) {
R.id.num_0_button -> numberButtonClicked("0")
R.id.num_1_button -> numberButtonClicked("1")
R.id.num_2_button -> numberButtonClicked("2")
R.id.num_3_button -> numberButtonClicked("3")
R.id.num_4_button -> numberButtonClicked("4")
R.id.num_5_button -> numberButtonClicked("5")
R.id.num_6_button -> numberButtonClicked("6")
R.id.num_7_button -> numberButtonClicked("7")
R.id.num_8_button -> numberButtonClicked("8")
R.id.num_9_button -> numberButtonClicked("9")
R.id.plus_button -> operatorButtonClicked("+")
R.id.minus_button -> operatorButtonClicked("-")
R.id.times_button -> operatorButtonClicked("X")
R.id.divide_button -> operatorButtonClicked("/")
R.id.mod_button -> operatorButtonClicked("%")
}
}

해당 버튼이 숫자인지 연산자인지를 구분해서 넣어줬다.

numberButtonClicked와 operatorButtonClicked에는 각각의 예외처리를 해줬다.

💡숫자 버튼을 눌렀을 때 실행되는 함수

private fun numberButtonClicked(number : String) {
if (isOperator) { //연산자를 입력받았는지를 체크
txtInput.append(" ")
}
isOperator = false
val itext = txtInput.text.split(" ")
if (itext.isNotEmpty() && itext.last().length >= 15) {
Toast.makeText(this, "15자리까지만 사용할수 있습니다", Toast.LENGTH_SHORT).show()
return
} else if (itext.last().isEmpty() && number == "0") {
Toast.makeText(this, "0은 제일 앞에 올수 없습니다.", Toast.LENGTH_SHORT).show()
return
}
txtInput.append(number)
txtResult.text = calculateExpression()
}

만약 연산자를 입력받았다면 4 + 5 이렇게 입력되도록 처리했다.

그래야 나중에 공백 단위로 숫자, 연산자를 넣어줄 수 있기 때문이다.

 

Toast는 간단하게 화면에 메시지를 띄우는 것이다.

뒤에 LENGTH_SHORT는 짧게 메시지를 화면에 띄우는 것이고, LENGTH_LONG은 화면에 메시지를 오래 띄우는 것이다.

예외처리를 다 통과하면 Input_text view에 숫자를 넣어줬다.

 

💡연산자 버튼을 눌렀을 때의 코드이다.

//isOperator : 연산자를 작성하고 있는지 아닌지를 체크.
//hasOperator : 내가 지금 연산자를 사용했는지 체크. 있다면 true, 없으면 false
private fun operatorButtonClicked(operator: String) {
if (txtInput.text.isEmpty()) { //연산자를 눌럿는데 숫자가 없다면 바로 return
return
}
when {
isOperator -> { //isOperator이 1이면 실행
val text = txtInput.text.toString()
txtInput.text = text.dropLast(1) + operator
}
hasOperator -> { //hasOperator이 1이면 실행
Toast.makeText(this, "연산자는 한번만 사용가능합니다", Toast.LENGTH_SHORT).show()
return
}
else -> {
txtInput.append(" $operator") //만약
}
}
val ssb= SpannableStringBuilder(txtInput.text)
ssb.setSpan(
ForegroundColorSpan(getColor(R.color.green)),
txtInput.text.length-1, txtInput.text.length,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
)
txtInput.text=ssb
isOperator = true
hasOperator = true
}

이번 계산기를 만들면서 처음 봤는데 Span은 텍스트의 스타일을 지정할 때 사용한다고 한다. 

자세한 내용은 따로 공부하면서 정리할 예정이고

간단하게 말하면 class로 하고 싶은 것을 선언하고, 적용범위와, span이 적용된 곳에 문자열이 추가될 때 어떠한 처리를 하는지를 나타낸다고 합니다.

 

💡=버튼을 눌렀을 때의 함수

fun resultButtonClicked(v:View) {
val itext = txtInput.text.split(" ") //입력받은 문자열을 공백 단위로 쪼갬
if (txtInput.text.isEmpty() || itext.size == 1) {
return
}
if (itext.size != 3 && hasOperator) {
//공백 단위로 쪼개면 무조건 itext는 3이여야한다. 그리고 연산을 하기 위해서는 연산자가 있어야 하기에 hasOperator값이 1이어야한다.
Toast.makeText(this, "수식을 완성해주세요", Toast.LENGTH_SHORT).show()
return
}
if (itext[0].isNumber().not() || itext[2].isNumber().not()) { //만약 숫자가 아니라면 오류 발생
Toast.makeText(this, "오류가 발생했습니다.", Toast.LENGTH_SHORT).show()
return
}
val input_text = txtInput.text.toString()
val result_text = calculateExpression()
Thread(Runnable {
db.historyDao().insertHistory(History(null,input_text,result_text))
}).start()
txtResult.text = " "
txtInput.text = result_text
//계산이 끝낫으므로 연산자에 대한 옵션을 다시 초기값으로 줌
isOperator = false
hasOperator = false
}

💡계산하는 함수

private fun calculateExpression() : String {
val input_text = txtInput.text.split(" ")
if (hasOperator.not() || input_text.size != 3) {
return ""
} else if (input_text[0].isNumber().not() || input_text[2].isNumber().not()) {
return ""
}
// A + B
val n1 = input_text[0].toBigInteger() //A를 의미
val n2 = input_text[2].toBigInteger() //B를 의미
val op = input_text[1] //+를 의미
return when (op) { //해당 결과를 return 해줌.
"+" -> (n1 + n2).toString()
"-" -> (n1 - n2).toString()
"X" -> (n1 * n2).toString()
"%" -> (n1 % n2).toString()
"/" -> (n1 / n2).toString()
else -> ""
}
}

💡버튼 C를 눌렀을 때의 함수 -> 모든 text를 초기화하고 연산자 옵션도 초기화한다.

fun clearButtonClicked(v: View) {
txtInput.text = ""
txtResult.text = ""
isOperator = false
hasOperator = false
}

 

💡숫자인지 아닌지를 판별하는 함수

private fun String.isNumber(): Boolean {
return try{
this.toBigInteger()
true
}catch ( e:NumberFormatException){
false
}
}

 

이제 다음 글은 계산 기록을 저장하는 단계이다.

저작자표시 (새창열림)

'Skils > Android' 카테고리의 다른 글

[Android] - Layout이란  (0) 2022.10.07
[Android] 애플리케이션 기본항목 - 4대 구성요소(Component)  (1) 2022.09.23
[Android] - 계산기 만들기(클론 코딩) - 계산 기록O  (0) 2022.09.18
[Android] Room (로컬 데이터베이스에 데이터 저장)  (0) 2022.09.03
[Android Studio] 계산기 어플 앱 만들기(Kotlin) #1  (0) 2022.08.25
'Skils/Android' 카테고리의 다른 글
  • [Android] 애플리케이션 기본항목 - 4대 구성요소(Component)
  • [Android] - 계산기 만들기(클론 코딩) - 계산 기록O
  • [Android] Room (로컬 데이터베이스에 데이터 저장)
  • [Android Studio] 계산기 어플 앱 만들기(Kotlin) #1
재한
재한
안녕하세요 💻
재한
짜이한
전체
오늘
어제
  • 분류 전체보기 (504)
    • Skils (118)
      • Android (52)
      • C++ (5)
      • Kotlin (36)
      • Algorithm (24)
      • Server (1)
    • CodingTest (228)
      • Programmers (45)
      • Baekjoon (183)
    • Experience (8)
      • 후기(코딩테스트,프로그램,프로젝트) (8)
    • Computer Science (70)
      • Design Pattern (2)
      • OOP (2)
      • Computer Architecture (14)
      • OS (2)
      • Software Engineering (3)
      • DataBase (8)
      • Network (39)
    • 학교 (75)
      • R프로그래밍 (26)
      • 회계와 사회생활 (17)
      • 컴퓨터학개론 (20)
      • it기술경영개론 (12)

블로그 메뉴

  • 홈
  • 태그
  • 카테고리
  • 글쓰기
  • 설정

인기 글

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.2
재한
[Android] - 계산기 만들기 (클론 코딩) -계산 기록 x
상단으로

티스토리툴바

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.