출력 결과 :
안드로이드 스튜디오를 접한 사람이라면 먼저 자바나 코틀린을 접했을 것이다.
자바의 간단한 계산기는 eval함수를 이용하여 문자열을 계산해준다. 그 함수는 javax 함수 위에 있는데, 안드로이드는 없기 때문에 이것도 생각해본다.
먼저, 디자인 xml을 생성한다.
여러가지 레이아웃으로 만들어도 관계 없지만, 여기서는 테이블 레이아웃을 이용했다.
<?xml version="1.0" encoding="utf-8"?>
<TableLayout 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:paddingRight="10dp"
android:paddingLeft="10dp"
android:paddingTop="200dp"
android:stretchColumns="*"
tools:context=".MainActivity">
<TableRow>
<EditText
android:layout_span="4"
android:id="@+id/et_result"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="textPersonName"
android:hint="숫자를 입력하세요." />
</TableRow>
<!-- 첫번째 버튼 줄-->
<TableRow>
<Button
android:id="@+id/num_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="1" />
<Button
android:id="@+id/num_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="2" />
<Button
android:id="@+id/num_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="3" />
<Button
android:id="@+id/btn_plus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="+" />
</TableRow>
<!--첫 번째 버튼 줄 종료-->
<!-- 두 번째 버튼 줄 -->
<TableRow>
<Button
android:id="@+id/num_4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="4" />
<Button
android:id="@+id/num_5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="5" />
<Button
android:id="@+id/num_6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="6" />
<Button
android:id="@+id/btn_minus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="-" />
</TableRow>
<!-- 두 번째 버튼 줄 종료-->
<!--세 번째 버튼 줄 시작-->
<TableRow>
<Button
android:id="@+id/num_7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="7" />
<Button
android:id="@+id/num_8"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="8" />
<Button
android:id="@+id/num_9"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="9" />
<Button
android:id="@+id/btn_multiple"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="*" />
</TableRow>
<!-- 세 번째 버튼 줄 종료-->
<!-- 네 번째 버튼 줄 시작-->
<TableRow>
<Button
android:id="@+id/num_0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0" />
<Button
android:id="@+id/btn_clear"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="C" />
<Button
android:id="@+id/btn_slush"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="/" />
<Button
android:id="@+id/btn_result"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="=" />
</TableRow>
<!-- 네번째 줄 종료-->
</TableLayout>
안드로이드의 테이블은 html과 다르게 따로 td등을 만들 필요 없이 한 줄이 <tablerow> 인데, 여기 내부에 들어있는 요소의 양이 제일 많은대로 열이 된다. 즉, 첫 번째 줄에 요소 3개, 두 번째 줄에 요소 4개 세 번째 줄의 요소가 5개라면, 5X3의 테이블 레이아웃이 완성된다.
EditText는 한 줄에 크게 차지하기 때문에 span 속성을 통해 4칸을 차지하도록 속성을 주었다.
레이아웃의 stretchColumns 속성은 테이블의 모양이 균일하게 요소 내부를 채워준다. 만일, 단일 테이블 요소의 크기를 조절하고 싶다면, stretchColunms 속성에 *가 아닌, 열의 숫자를 지정해주면 된다.
이제 코드이다.
package com.mary.countingapp;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "Main_Activity";
private EditText ptResult;
private Button btn[]=new Button[16];
private int i=0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
initListener();
}
private void init(){
btn[0]=findViewById(R.id.num_0);
btn[1]=findViewById(R.id.num_1);
btn[2]=findViewById(R.id.num_2);
btn[3]=findViewById(R.id.num_3);
btn[4]=findViewById(R.id.num_4);
btn[5]=findViewById(R.id.num_5);
btn[6]=findViewById(R.id.num_6);
btn[7]=findViewById(R.id.num_7);
btn[8]=findViewById(R.id.num_8);
btn[9]=findViewById(R.id.num_9);
btn[10]=findViewById(R.id.btn_plus);
btn[11]=findViewById(R.id.btn_minus);
btn[12]=findViewById(R.id.btn_multiple);
btn[13]=findViewById(R.id.btn_slush);
btn[14]=findViewById(R.id.btn_clear);
btn[15]=findViewById(R.id.btn_result);
ptResult=findViewById(R.id.et_result);
}
private void initListener(){
for (int i=0; i<14;i++){
btn[i].setOnClickListener((View view)-> {
Button btn = (Button) view;
ptResult.append(btn.getText().toString());
});
}
btn[14].setOnClickListener((View view)-> {
ptResult.setText("");
});
btn[15].setOnClickListener((View view)-> {
String result=ptResult.getText().toString();
ptResult.setText(Eval.cal(result));
});
}
}
버튼이 16개나 된다.
그러니까, 이 버튼의 변수를 일일히 지정하는 것보다, 배열로 지정하면 변수의 이름을 일일히 지정해줄 필요도 없고 이벤트 리스너를 만들 때 일일히 지정할 필요 없이 같은 역할을 하는 버튼을 for문을 돌려 이벤트 리스너를 지정한다.
배열의 크기를 지정하고, 각 배열의 위치에 findView 속성을 통해 버튼을 호출해 배열 속에 넣는다.
여기서 역할이 좀 중요한데, clear과 =는 텍스트에디터 위에 나타나는 값이 아니다. 나머지는 텍스트 에디터 위에 나타나는 값이다. 그렇기 때문에 clear과 = 버튼은 뒤로 지정하고, 나머지를 배열의 앞에 넣어 for문을 돌린다.
for문을 돌리는 방식은 간단하다. 내가 textEditor 위에 호출할 값들까지만 for문을 돌리며, for문 내부 함수는 버튼 속의 text값을 getText로 가져와 문자열로 파싱 후 append 하면 된다.
즉, 1을 누르면 "1", 2를 누르면 "1"+"2"가 되니 3이 아니라 12가 되는 셈이다.
clear 버튼이야.. 그냥 텍스트 에디터 위의 값을 다 날리면 되니 setText("")로 공백을 만든다.
마지막 result를 위해서 먼저 자바스크립트 라이브러리를 참조하게 해 줄 라이브러리를 찾는다. 여기서는 Rinor for Android를 이용했다.
https://mvnrepository.com/artifact/io.apisense/rhino-android/1.0
이제 이 라이브러리를 의존성을 부여하자.
앱 수준의 build.gradle로 이동해서 implement한다.
implementation 'io.apisense:rhino-android:1.0'
이제, 자바스크립트를 참조할 수 있으니, eval 함수를 만들자.
새 자바 클래스를 생성한다.
package com.mary.countingapp;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
public class Eval {
public static String cal(String result){
ScriptEngineManager manager=new ScriptEngineManager();
ScriptEngine engine=manager.getEngineByName("js");
try{
return engine.eval(result).toString();
}catch (Exception e){
e.printStackTrace();
}
return null;
}
}
먼저 스크립트 매니저를 호출하고, 이후에 엔진을 호출한다. 엔진은 내가 어떤 스크립트를 사용할건지 선택하게 하는데, 나는 자바스크립트를 만들테니 확장자 js를 호출한다. 이러면 자바스크립트 내부의 함수(eval)을 이용할 수 있다.
이 함수를 결과값 이벤트 리스너에서 호출한다.
'Android' 카테고리의 다른 글
안드로이드 스튜디오,java] 기초 액션바 만들기 (0) | 2020.07.15 |
---|---|
안드로이드 스튜디오] 이벤트가 실행되기 까지 (0) | 2020.07.14 |
안드로이드 스튜디오(JAVA)]카운팅 앱 만들기 (0) | 2020.07.14 |
안드로이드 스튜디오] 인★그램 시작화면 만들어보기 (0) | 2020.07.14 |
안드로이드 스튜디오] 마우스를 클릭하면 변경되는 버튼 제작하기 (0) | 2020.07.14 |