5월 4주차 학습 내용 정리
Android
1. 레이아웃
- 레이아웃 : 위젯을 배치하여 안드로이드 화면을 목적에 맞게 배열하도록 함
(view의 하위 클래스)
- LinearLayout, RelativeLayout, FrameLayout, TableLayout, GridLayout 등이 있음
- 레이아웃 내 레이아웃 사용 가능하며 LinearLayout이 가장 많이 쓰임
- LinearLayout : 레이아웃의 왼쪽 위부터 아래쪽 또는 오른쪽으로 차례로 배치(orientation으로 방향 설정)
- RelativeLayout : 위젯 자신이 속한 레이아웃의 상하좌우 위치를 지정하여 배치,
또는 다른 위젯으로부터 상대적인 위치 지정
- FrameLayout : 위젯을 겹쳐 배치 가능(visibility 설정을 통해 보이고자 하는 위젯 지정 가능)
- TableLayout : 행과 열의 개수를 지정한 테이블 형태로 위젯 배열(열 확장 불가)
- GridLayout : 테이블 레이아웃과 비슷하며 행이나 열을 확장하여 다양하게 배치 가능
- TableLayout을 활용하여 간단 계산기 앱 만들기
* activity_main.xml
<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"
tools:context=".MainActivity"
android:padding="10dp"
android:stretchColumns="*">
<TableRow>
<EditText
android:id="@+id/edt1"
android:layout_span="4"
android:inputType="numberDecimal"/>
</TableRow>
<TableRow>
<EditText
android:id="@+id/edt2"
android:layout_span="4"
android:layout_marginBottom="15dp"
android:inputType="numberDecimal"/>
</TableRow>
<TableRow>
<Button
android:id="@+id/btn0"
android:text="0"
android:backgroundTint="#E1B6E8"
android:textColor="@color/black"
android:layout_marginRight="5dp"/>
<Button
android:id="@+id/btn1"
android:text="1"
android:backgroundTint="#E1B6E8"
android:textColor="@color/black"
android:layout_marginRight="5dp"/>
<Button
android:id="@+id/btn2"
android:text="2"
android:backgroundTint="#E1B6E8"
android:textColor="@color/black"
android:layout_marginRight="5dp"/>
<Button
android:id="@+id/btn3"
android:text="3"
android:backgroundTint="#E1B6E8"
android:textColor="@color/black"/>
</TableRow>
<TableRow>
<Button
android:id="@+id/btn4"
android:text="4"
android:backgroundTint="#E1B6E8"
android:textColor="@color/black"
android:layout_marginRight="5dp"/>
<Button
android:id="@+id/btn5"
android:text="5"
android:backgroundTint="#E1B6E8"
android:textColor="@color/black"
android:layout_marginRight="5dp"/>
<Button
android:id="@+id/btn6"
android:text="6"
android:backgroundTint="#E1B6E8"
android:textColor="@color/black"
android:layout_marginRight="5dp"/>
<Button
android:id="@+id/btn7"
android:text="7"
android:backgroundTint="#E1B6E8"
android:textColor="@color/black"/>
</TableRow>
<TableRow>
<Button
android:id="@+id/btn8"
android:text="8"
android:backgroundTint="#E1B6E8"
android:textColor="@color/black"
android:layout_marginRight="5dp"/>
<Button
android:id="@+id/btn9"
android:text="9"
android:backgroundTint="#E1B6E8"
android:textColor="@color/black"
android:layout_marginRight="5dp"/>
<Button
android:id="@+id/btnDot"
android:text="."
android:backgroundTint="#E1B6E8"
android:textColor="@color/black"
android:layout_marginRight="5dp"/>
<Button
android:id="@+id/btnC"
android:text="C"
android:backgroundTint="#E1B6E8"
android:textColor="@color/black"
/>
</TableRow>
<TableRow>
<Button
android:id="@+id/btnAdd"
android:text="더하기"
android:backgroundTint="#E1B6E8"
android:textColor="@color/black"
android:layout_span="4"
android:layout_marginTop="20dp"/>
</TableRow>
<TableRow>
<Button
android:id="@+id/btnSub"
android:text="빼기"
android:backgroundTint="#E1B6E8"
android:textColor="@color/black"
android:layout_span="4"/>
</TableRow>
<TableRow>
<Button
android:id="@+id/btnMul"
android:text="곱하기"
android:backgroundTint="#E1B6E8"
android:textColor="@color/black"
android:layout_span="4"/>
</TableRow>
<TableRow>
<Button
android:id="@+id/btnDiv"
android:text="나누기"
android:backgroundTint="#E1B6E8"
android:textColor="@color/black"
android:layout_span="4"/>
</TableRow>
<TableRow>
<TextView
android:id="@+id/txtResult"
android:text="계산결과 : 0"
android:textColor="#DF0101"
android:textSize="20sp"
android:layout_marginTop="20dp"
android:layout_span="4"/>
</TableRow>
</TableLayout>
* MainActivity.java
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
EditText edt1, edt2;
Button[] numButtons = new Button[10];
Button btnAdd, btnSub, btnMul, btnDiv, btnDot, btnC;
TextView txtResult;
View.OnClickListener numButtonListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
Button button = (Button)view;
String strNum = button.getText().toString();
EditText edit = null;
if (edt1.isFocused()) edit = edt1;
else if (edt2.isFocused()) edit = edt2;
String eNum = edit.getText().toString();
if (eNum.equals("0")) edit.setText("");
edit.append(strNum);
if (view == btnC) {
edt1.setText("");
edt2.setText("");
return;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTitle("계산기");
setContentView(R.layout.activity_main);
setUI();
setListener();
}
private void setListener() {
for (Button aButton : numButtons) {
aButton.setOnClickListener(numButtonListener);
}
btnDot.setOnClickListener(numButtonListener);
btnC.setOnClickListener(numButtonListener);
btnAdd.setOnClickListener(this);
btnSub.setOnClickListener(this);
btnMul.setOnClickListener(this);
btnDiv.setOnClickListener(this);
}
private void setUI() {
for (int i = 0; i < numButtons.length; i++) {
int id = getResources().getIdentifier(
"btn" + i, "id", getPackageName());
Log.d("mytag", String.valueOf(id));
numButtons[i] = findViewById(id);
}
edt1 = findViewById(R.id.edt1);
edt2 = findViewById(R.id.edt2);
btnAdd = findViewById(R.id.btnAdd);
btnSub = findViewById(R.id.btnSub);
btnMul = findViewById(R.id.btnMul);
btnDiv = findViewById(R.id.btnDiv);
btnDot = findViewById(R.id.btnDot);
btnC = findViewById(R.id.btnC);
txtResult = findViewById(R.id.txtResult);
}
@Override
public void onClick(View view) {
String str1 = "";
String str2 = "";
double num1 = 0;
double num2 = 0;
double result = 0;
try{
str1 = edt1.getText().toString();
str2 = edt2.getText().toString();
num1 = Double.valueOf(str1);
num2 = Double.valueOf(str2);
} catch (Exception e) {
Toast.makeText(this, "정확한 값을 입력하세요.", Toast.LENGTH_SHORT).show();
return;
}
if (view == btnAdd) {
result = num1 + num2;
} else if (view == btnSub) {
result = num1 - num2;
} else if (view == btnMul) {
result = num1 * num2;
} else if (view == btnDiv) {
if (num2 == 0) {
Toast.makeText(
this, "0으로 나눌 수 없습니다.", Toast.LENGTH_SHORT).show();
return;
}
result = num1 / num2;
}
txtResult.setText("계산결과 : " + result);
}
}
2. 다양한 위젯 활용하기
- 날짜와 시간 관련 위젯 : TimePicker, DatePicker, CalendarView, Chronometer 등
- TimePicker : 시간 표시 및 조절
- DatePicker, CalendarView : 날짜 표시 및 조절
- Chronometer : 타이머 형식의 위젯(시간 측정 시 사용)
- 날짜 / 시간 선택하여 예약 기능 구현하기
* activity_main.xml
<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=".MainActivity"
android:orientation="vertical"
android:padding="10dp">
<Chronometer
android:id="@+id/chronometer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:format="예약에 걸린 시간 %s"
android:gravity="center_horizontal"
android:textSize="22sp"
android:textStyle="bold"
android:textColor="#3F51B5"
android:layout_marginTop="10dp"/>
<Button
android:id="@+id/btnStart"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="예약 시작"
android:backgroundTint="#DDDBDB"
android:textColor="@color/black"
android:layout_marginTop="10dp"/>
<RadioGroup
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<RadioButton
android:id="@+id/rdDate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="날짜 설정 (캘린더뷰)"
android:checked="true"
android:layout_marginTop="15dp"/>
<RadioButton
android:id="@+id/rdTime"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="시간 설정"/>
</RadioGroup>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<CalendarView
android:id="@+id/calendarView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
/>
<TimePicker
android:id="@+id/timePicker"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:timePickerMode="spinner"
android:visibility="invisible"
android:layout_gravity="center_vertical"/>
</FrameLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="#C5C4C4"
android:layout_marginBottom="10dp">
<Button
android:id="@+id/btnFinish"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="예약완료"
android:backgroundTint="#DDDBDB"
android:textColor="@color/black"
android:layout_marginLeft="10dp"/>
<TextView
android:id="@+id/txtResult"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:text="0000년 00월 00일 00시 00분 예약됨"
android:textColor="@color/black"/>
</LinearLayout>
</LinearLayout>
* MainActivity.java
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
Chronometer chronometer;
Button btnStart, btnFinish;
RadioButton rdDate, rdTime;
CalendarView calendarView;
TimePicker timePicker;
TextView txtResult;
int year, month, day;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setUI();
setListener();
setInitDate(); // 날짜 변경이 없으면 오늘 날짜로 설정
}
private void setInitDate() {
Calendar cal = Calendar.getInstance();
this.year = cal.get(Calendar.YEAR);
this.month = cal.get(Calendar.MONTH) + 1;
this.day = cal.get(Calendar.DAY_OF_MONTH);
}
private void setListener() {
btnStart.setOnClickListener(this);
btnFinish.setOnClickListener(this);
rdDate.setOnClickListener(this);
rdTime.setOnClickListener(this);
calendarView.setOnDateChangeListener(new CalendarView.OnDateChangeListener() {
@Override
public void onSelectedDayChange(@NonNull CalendarView calendarView,
int year, int month, int day) {
MainActivity.this.year = year;
MainActivity.this.month = month + 1;
MainActivity.this.day = day;
}
});
}
private void setUI() {
chronometer = findViewById(R.id.chronometer);
btnStart = findViewById(R.id.btnStart);
btnFinish = findViewById(R.id.btnFinish);
rdDate = findViewById(R.id.rdDate);
rdTime = findViewById(R.id.rdTime);
calendarView = findViewById(R.id.calendarView);
timePicker = findViewById(R.id.timePicker);
txtResult = findViewById(R.id.txtResult);
}
private String make2digits(int value) {
if (value < 10) return "0" + value;
else return value + "";
}
private String selectedDate() {
String result = make2digits(year) + "년 "
+ make2digits(month) + "월 " + make2digits(day) + "일 ";
return result;
}
private String selectedTime() {
int hour = timePicker.getHour();
int min = timePicker.getMinute();
String result = make2digits(hour) + "시 " + make2digits(min) + "분 ";
return result;
}
@Override
public void onClick(View view) {
if (view == btnStart) {
chronometer.setBase(SystemClock.elapsedRealtime()); // 실제 흐른 시간값으로 설정
chronometer.start();
chronometer.setTextColor(Color.RED);
} else if (view == btnFinish) {
chronometer.stop();
calendarView.getDate();
chronometer.setTextColor(Color.BLUE);
txtResult.setText(selectedDate() + selectedTime() + "예약됨");
} else if (view == rdDate) {
calendarView.setVisibility(View.VISIBLE);
timePicker.setVisibility(View.INVISIBLE);
} else if (view == rdTime) {
calendarView.setVisibility(View.INVISIBLE);
timePicker.setVisibility(View.VISIBLE);
}
}
}
- CompoundButton : Button 클래스의 하위 클래스로 체크박스, 라디오버튼, 스위치, 토글버튼의 상위 클래스
- CheckBox : 클릭할 때마다 체크 또는 언체크로 상태가 변경됨
- Switch / ToggleButton : 온오프 상태 표시
- RadioButton : 여러개 중 하나만 선택해야 하는 경우 사용(RadioGroup과 함께 사용)
* activity_main.xml
<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=".MainActivity"
android:orientation="vertical"
android:padding="20dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="선택을 시작하겠습니까?"
android:textSize="20dp"/>
<CheckBox
android:id="@+id/chkStart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="시작함"
android:checked="false"/>
<!-- 시작함을 클릭했을 때 보이게 하기-->
<LinearLayout
android:id="@+id/innerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:visibility="invisible">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="좋아하는 동물은?"
android:textSize="20dp"
android:layout_marginTop="10dp"/>
<RadioGroup
android:id="@+id/rGroup"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<RadioButton
android:id="@+id/rdDog"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="강아지"
android:checked="true"/>
<RadioButton
android:id="@+id/rdCat"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="고양이"/>
<RadioButton
android:id="@+id/rdRabbit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="토끼"/>
<RadioButton
android:id="@+id/rdFox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="사막여우"/>
</RadioGroup>
<Button
android:id="@+id/btnFinish"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="선택완료"
android:layout_marginTop="10dp"/>
<ImageView
android:id="@+id/imgPet"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerInside"
android:src="@drawable/dog3"
android:visibility="invisible"
android:layout_marginTop="10dp"/>
</LinearLayout>
</LinearLayout>
* MainActivity.java
public class MainActivity extends AppCompatActivity {
CheckBox chkStart;
LinearLayout innerLayout;
RadioGroup rGroup;
Button btnFinish;
ImageView imgPet;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setTitle("귀여운 동물 보기");
chkStart = findViewById(R.id.chkStart);
innerLayout = findViewById(R.id.innerLayout);
rGroup = findViewById(R.id.rGroup);
btnFinish = findViewById(R.id.btnFinish);
imgPet = findViewById(R.id.imgPet);
chkStart.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if (b) {
innerLayout.setVisibility(View.VISIBLE);
} else {
innerLayout.setVisibility(View.INVISIBLE);
}
}
});
btnFinish.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int id = rGroup.getCheckedRadioButtonId();
switch (id) {
case R.id.rdDog:
imgPet.setImageResource(R.drawable.dog3);
break;
case R.id.rdCat:
imgPet.setImageResource(R.drawable.cat);
break;
case R.id.rdRabbit:
imgPet.setImageResource(R.drawable.rabbit);
break;
case R.id.rdFox:
imgPet.setImageResource(R.drawable.fox2);
break;
}
imgPet.setVisibility(View.VISIBLE);
}
});
}
}
- ProgressBar, SeekBar, RatingBar : 진행 상태를 표시하는 기능
- ProgressBar : 작업의 진행 상태를 bar 또는 원 형태로 제공
- SeekBar : ProgressBar의 하위 클래스로 사용자의 터치로 상태 조절 가능
ex) 음량 조절, 동영상 재생 위치 지정 등
- RatingBar : 진행 상태를 별 모양으로 표시
ex) 별점 평가
- 활용 연습
* activity_main.xml
<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=".MainActivity"
android:orientation="vertical"
android:padding="20dp">
<ProgressBar
android:id="@+id/progressbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="?android:progressBarStyleHorizontal"
android:max="100"
android:progress="50"/>
<SeekBar
android:id="@+id/seekbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="100"
android:progress="30"
android:thumb="@mipmap/ic_launcher"/> <!--커서(?) 모양 변경-->
<RatingBar
android:id="@+id/ratingBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:stepSize="0.5"
android:rating="2"/> <!-- 사용자와 상호작용. 밑에 두개는 표시용-->
<RatingBar
android:id="@+id/ratingBarIndi"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="?android:ratingBarStyleIndicator"
android:rating="5"/>
<RatingBar
android:id="@+id/ratingBarSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="?android:ratingBarStyleSmall"/>
</LinearLayout>
* MainActivity.java
public class MainActivity extends AppCompatActivity {
ProgressBar progressBar;
SeekBar seekbar;
RatingBar ratingBar, ratingBarIndi, ratingBarSmall;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
progressBar = findViewById(R.id.progressbar);
seekbar = findViewById(R.id.seekbar);
ratingBar = findViewById(R.id.ratingBar);
ratingBarIndi = findViewById(R.id.ratingBarIndi);
ratingBarSmall = findViewById(R.id.ratingBarSmall);
seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean b) { // i 값 : 현재 진행 상태, boolean : 사용자가 변경했는지 여부
progressBar.setProgress(progress);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) { // 움직이기 시작할 때 호출
Log.d("mytag", "seekbar moved");
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) { // 멈출 때 호출
Log.d("mytag", "seekbar stopped");
}
});
ratingBar.setOnRatingBarChangeListener(new RatingBar.OnRatingBarChangeListener() {
@Override
public void onRatingChanged(RatingBar ratingBar, float v, boolean b) {
ratingBarIndi.setRating(v);
ratingBarSmall.setRating(v);
}
});
}
}
'Daily Record' 카테고리의 다른 글
6월 2주차 학습 내용 정리 (0) | 2023.06.11 |
---|---|
6월 1주차 학습 내용 정리 (0) | 2023.06.04 |
5월 23일 학습 내용 정리 (0) | 2023.05.23 |
[JDBC/활용] SQL과 JFrame으로 CRUD 구현하기 (0) | 2023.05.22 |
5월 3주차 학습 내용 정리 (0) | 2023.05.20 |
Liked this Posting!