Layout / Chronometer / TimePicker / DatePicker / CalendarView

2022. 10. 10. 15:43Dev.Program/Android

728x90

ch05_레이아웃

======== 0612_ch05_Layout_Basic_LinearLayout

< 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"
  tools:context=".MainActivity"
   android:orientation="vertical">

  <Button
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="버튼1"
      android:textSize="20sp"/>
  <Button
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="버튼2"
      android:textSize="20sp"/>
  <Button
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="버튼3"
      android:textSize="20sp"/>

</LinearLayout>
  •  
  • android:orientation="vertical" 추가할 경우 위치가 수직으로 바뀜

 

 

  • layout_gravity 와 gravity 속성이 있다!

< gravity 속성 > 

  • 내 안에 소속된 위젯들의 배치를 결정
  • | 기호를 사용하여 조합가능

  • android:gravity="right"

  • android:gravity="right|bottom"
  • 내 안 속성들의 배치를 변경

 

> 레이아웃이 아니라 위젯에 설정 시

  • 이렇게 위젯 내부의 속성들이 변경(지금은 텍스트 위치가 변경)

======== 0612_ch05_Layout_Basic_LinearLayout2

< Layout-gravity 속성 >

  • 위젯들의 배치를 결정

  • 자신의 위치를 부모(주로 레이아웃)를 기준으로 배치할 위치를 결정

⇒ gravity 와 Layout-gravity 는 쓰다보면 많이 헷갈림! 계속 해봐야한다

 

======== 0612_ch05_p14_Exam_5_1

> 문제풀어보기

<?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=".MainActivity"
  android:orientation="vertical">

  <Button
      android:layout_width="110dp"
      android:layout_height="100dp"
      android:text="버튼1"
      android:textSize="20sp"
      android:layout_gravity="center"
      android:gravity="right|top"
      android:background="#dfd782"/>
  <Button
      android:layout_width="110dp"
      android:layout_height="100dp"
      android:text="버튼2"
      android:textSize="20sp"
      android:gravity="left|center"
      android:background="#dfd782"/>
  <Button
      android:layout_width="110dp"
      android:layout_height="100dp"
      android:text="버튼3"
      android:textSize="20sp"
      android:layout_gravity="right"
      android:gravity="right|bottom"
      android:background="#dfd782"/>

</LinearLayout>

 

======== 0612_ch05_Layout_Basic_LinearLayout3

< baselineAligned >

  • 크기가 다른 위젯들을 정렬하기 위해 기준선 사용할 것인지 결정
  • ⇒ 만약, false 값을 지정할 경우 레이아웃 상단을 기준으로 위젯을 배치
  • ⇒ true 값 지정 또는 생략 시, Button 위젯일 때는 위젯 중심을 기준선으로 설정하고, TextView 위젯일 때는 위젯 하단을 기준선으로 설정함
<?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=".MainActivity"
  android:orientation="horizontal"
  android:baselineAligned="false">

  <Button
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="버튼1"
      android:textSize="20sp"
      android:background="#00FF55"
      android:layout_margin="10dp"/>

  <Button
      android:layout_width="wrap_content"
      android:layout_height="80dp"
      android:text="버튼2"
      android:textSize="20sp"
      android:background="#00FF55"
      android:layout_margin="10dp"/>

  <Button
      android:layout_width="wrap_content"
      android:layout_height="100dp"
      android:text="버튼3"
      android:textSize="20sp"
      android:background="#00FF55"
      android:layout_margin="10dp"/>
</LinearLayout>
  • 크기가 다른 위젯들을 정렬하기 위해 기준선 사용할 것인지 결정
  • ⇒ 만약, false 값을 지정할 경우 레이아웃 상단을 기준으로 위젯을 배치하고, true 값 또는 속성을 생략할 경우 위젯들의 중심선을 기준으로 나란히 배치

 

> 버튼이 아니라 텍스트뷰일 때

<?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=".MainActivity"
  android:orientation="horizontal"
  android:baselineAligned="true">

  <TextView
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="버튼1"
      android:textSize="20sp"
      android:background="#00FF55"
      android:layout_margin="10dp"/>

  <TextView
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="버튼2"
      android:textSize="30sp"
      android:background="#00FF55"
      android:layout_margin="10dp"/>

  <TextView
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="버튼3"
      android:textSize="40sp"
      android:background="#00FF55"
      android:layout_margin="10dp"/>
</LinearLayout>
  • true 일 때
  • false 일 때

 

======== 0612_ch05_Layout_Basic_LinearLayout_Overlap

< Overlap LinearLayout : 중첩 리니어레이아웃 >

리니어 레이아웃 속에 리니어 레이아웃(Vertical)

<?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=".MainActivity"
  android:orientation="vertical">

  <!--
  레이아웃 중첩 사용
  LinearLayout 내에 또 다른 LinearLayout 여러 개를 겹치면
  각 레이아웃별로 orientation 등의 속성을 다르게 지정할 수 있다!
  => 즉, 각각의 레이아웃 별 위젯 속성을 별도로 관리 가능
  -->

  <LinearLayout
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:orientation="vertical"
      android:gravity="center"
      android:layout_weight="1">

      <Button
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="버튼1"
          android:textSize="20sp"/>

      <Button
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="버튼2"
          android:textSize="20sp"/>
  </LinearLayout>

  <LinearLayout
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:orientation="horizontal"
      android:gravity="center"
      android:background="#00FF00"
      android:layout_weight="1">

      <Button
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="버튼3"
          android:textSize="20sp"/>

      <Button
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="버튼4"
          android:textSize="20sp"/>
  </LinearLayout>

  <LinearLayout
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:orientation="horizontal"
      android:gravity="center"
      android:background="#0000FF"
      android:layout_weight="1">

      <Button
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="버튼5"
          android:textSize="20sp"/>

      <Button
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="버튼6"
          android:textSize="20sp"/>
  </LinearLayout>


</LinearLayout>
  • android:layout_weight="1" 을 안줬을 때와 줬을 때의 차이점! (가중치 : 비율을 입력해준다 ⇒ 우린 1:1:1 이라서 1이라고 넣어줌)

 

<?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=".MainActivity"
  android:orientation="vertical">

  <!--
  레이아웃 중첩 사용
  LinearLayout 내에 또 다른 LinearLayout 여러 개를 겹치면
  각 레이아웃별로 orientation 등의 속성을 다르게 지정할 수 있다!
  => 즉, 각각의 레이아웃 별 위젯 속성을 별도로 관리 가능
  -->

  <LinearLayout
      android:layout_width="match_parent"
      android:layout_height="0dp"
      android:orientation="vertical"
      android:gravity="center"
      android:layout_weight="1">

      <Button
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="버튼1"
          android:textSize="20sp"/>

      <Button
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="버튼2"
          android:textSize="20sp"/>
  </LinearLayout>

  <LinearLayout
      android:layout_width="match_parent"
      android:layout_height="0dp"
      android:orientation="horizontal"
      android:gravity="center"
      android:background="#00FF00"
      android:layout_weight="2">

      <Button
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="버튼3"
          android:textSize="20sp"/>

      <Button
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="버튼4"
          android:textSize="20sp"/>
  </LinearLayout>

  <LinearLayout
      android:layout_width="match_parent"
      android:layout_height="0dp"
      android:orientation="horizontal"
      android:gravity="center"
      android:background="#0000FF"
      android:layout_weight="1">

      <Button
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="버튼5"
          android:textSize="20sp"/>

      <Button
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="버튼6"
          android:textSize="20sp"/>
  </LinearLayout>


</LinearLayout>
  • 비율을 달리할 때! height 는 0dp 로 주기!
  • match_parent 가 되어있을 때와 0dp 되어있을 때 차이점!

 

======== 0612_ch05_p22_Exam_5_2

> 22p 5-2 연습문제 풀기

<?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=".MainActivity"
  android:orientation="vertical">
  <!-- 전체 화면 2분할 상하 배치 -->

  <LinearLayout
      android:layout_width="match_parent"
      android:layout_height="0dp"
      android:layout_weight="1"
      android:orientation="horizontal">
      <!-- 전체 화면 2분할 중 상단 2분할 좌우 배치-->
      <LinearLayout
          android:layout_width="0dp"
          android:layout_height="match_parent"
          android:layout_weight="1"
          android:background="#FF0000">
      </LinearLayout>
      <LinearLayout
          android:layout_width="0dp"
          android:layout_height="match_parent"
          android:layout_weight="1"
          android:orientation="vertical">
          <!-- 상단 좌우 2분할 중 우측 상하 2분할 -->
          <LinearLayout
              android:layout_width="match_parent"
              android:layout_height="0dp"
              android:layout_weight="1"
              android:background="#FFFF00">
          </LinearLayout>
          <LinearLayout
              android:layout_width="match_parent"
              android:layout_height="0dp"
              android:layout_weight="1"
              android:background="#000000">
          </LinearLayout>
      </LinearLayout>
  </LinearLayout>

  <LinearLayout
      android:layout_width="match_parent"
      android:layout_height="0dp"
      android:background="#0000FF"
      android:layout_weight="1">
  </LinearLayout>

</LinearLayout>

 

======== 0612_ch05_Layout_Basic_LinearLayout_for_use_java

> 지금까지 만든 레이아웃을 자바코드로 만들어보자

activity_main.xml 주석처리할 거

< MainActivity.java >

  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setTitle("자바 코드로 레이아웃 생성");
      // 레이아읏이 설정된 activity_main.xml 파일을 표시하지 않도록 주석 처리
//        setContentView(R.layout.activity_main);
  }

 

  • Ctrl + P 하면 어떤 매개변수 값을 받는지 볼 수 있다

 

// 자바 코드를 사용하여 LinearLayout 생성
// 1. LayoutParams 객체를 생성하여 LinearLayout 에 필요한 필수 속성 파라미터 설정
//    => layout_width 속성과 layout_height 속성에 대한 설정
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
      // layout_width, layout_height 속성을 순서대로 지정
      // => LinearLayout.LayoutParams.상수명 을 사용하여 속성 값 지정 가능
      LinearLayout.LayoutParams.MATCH_PARENT, // layout_width"match_parent" 와 동일
      LinearLayout.LayoutParams.MATCH_PARENT // layout_height="match_parent" 와 동일
);

 

  • Context 나오면 보통 나 자신을 가리킴(=this)

 

  • orientation 넣어보기
  • 값을 뭐 넣을지 모를땐 클래스명. 찍어보기!
  • 안드로이드에서는 그냥 Ctrl + Space 해도 됨!
  • 선택하면 자동으로 클래스명 붙음

 

> 백그라운드 색상

layout.setBackgroundColor(Color.BLUE);

layout.setBackgroundColor(Color.rgb(0,0,255)); // 여기선 16진수 말고 10진수

  • 두 가지 다 가능! 여기선 16진수 #0000FF 가 아닌 10진수 사용 rgb(0,0,255)

> 4. setContentView() 메서드를 호출하여 레이아웃 표시

  • params 는 생략가능하지만, Linear 에서는 생략 불가!
  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setTitle("자바 코드로 레이아웃 생성");
      // 레이아읏이 설정된 activity_main.xml 파일을 표시하지 않도록 주석 처리
//        setContentView(R.layout.activity_main);

      // 자바 코드를 사용하여 LinearLayout 생성
      // 1. LayoutParams 객체를 생성하여 LinearLayout 에 필요한 필수 속성 파라미터 설정
      //    => layout_width 속성과 layout_height 속성에 대한 설정
      LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
              // layout_width, layout_height 속성을 순서대로 지정
              // => LinearLayout.LayoutParams.상수명 을 사용하여 속성 값 지정 가능
              LinearLayout.LayoutParams.MATCH_PARENT, // layout_width"match_parent" 와 동일
              LinearLayout.LayoutParams.MATCH_PARENT // layout_height="match_parent" 와 동일
      );

      // 2. LinearLayout 객체 생성
      // => 생성자 파라미터에 현재 액티비티(컨텍스트 객체)를 전달
      //    1) this    2) 액티비티클래스명.this   3) getApplicationContext() 중 택 1
      LinearLayout layout = new LinearLayout(this);

      // 3. 생성된 LinearLayout 객체의 메서드들을 호출하여 각종 속성 설정
      layout.setOrientation(LinearLayout.VERTICAL);

      // 레이아웃 색상 설정 => 주의! setBackground() 메서드가 아닌 setBackgroundColor() 메서드사용
      layout.setBackgroundColor(Color.BLUE);
      layout.setBackgroundColor(Color.rgb(0,0,255)); // 여기선 16진수 말고 10진수

      // 4. setContentView() 메서드를 호출하여 레이아웃 표시
      // => 파라미터로 생성된 레이아웃 객체 전달
      setContentView(layout, params);
  }

> 실행화면

⇒ 자바로 잘 하진 않지만(xml 로 하는게 훨씬 편리하기 때문!), 자바로도 이렇게 만들 수 있다는 거 알아두기!

 

// 자바 코드를 사용하여 버튼 생성하여 레이아웃에 부착
// 1. Button 객체 생성(findViewId() 메서드가 아닌 new 사용)
// => 파라미터로 현재 액티비티 객체(컨텍스트 객체) this 전달
Button btn = new Button(this);

// 2. Button 객체의 메서드를 사용하여 버튼 속성 설정
// => width, height 값 생략 시 기본값은 width = match_parent, height = wrap_content 로 지정됨
btn.setText("버튼입니다");
btn.setBackgroundColor(Color.GREEN);

// 3. 레이아웃 객체의 addView() 메서드를 호출하여 버튼 객체 전달
layout.addView(btn);

 

btn.setOnClickListener(new View.OnClickListener() {
  @Override
  public void onClick(View v) {
      Toast.makeText(MainActivity.this, "코드로 생성한 버튼입니다", Toast.LENGTH_SHORT).show();
  }
});
  • 추가
  • 버튼 클릭 시
    토스트 동작

 

> 27p 5-3

final  EditText edit = new EditText(this);
edit.setText("IT Cookbook. Android");
edit.setBackgroundColor(Color.WHITE);
layout.addView(edit);

Button btn2 = new Button(this);
btn2.setText("버튼입니다");
btn2.setBackgroundColor(Color.YELLOW);
layout.addView(btn2);

final TextView text = new TextView(this);
text.setText("IT Cookbook. Android");
text.setTextColor(Color.rgb(255, 0, 255));
text.setBackgroundColor(Color.WHITE);
text.setTextSize(20);
layout.addView(text);

btn2.setOnClickListener(new View.OnClickListener() {
  @Override
  public void onClick(View v) {
      // EditText 에 입력된 문자열을 TextView 에 출력
      text.setText(edit.getText().toString());
  }
});
  • 추가
  • 버튼입니다 클릭했을 때 EditText 에 입력된 문자열을 TextView 에 출력 (final 입력해야 함!)

======== 0612_ch05_Layout_Basic_relativeLayout

< RelativeLayout >

< activity_main.xml >

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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">

  <Button
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="위"
      android:textSize="20sp"/>

  <Button
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="아래"
      android:textSize="20sp"/>

</RelativeLayout>
  • 디자인 탭에서 보면
    실제 화면
    아래/위 겹쳐있는 거 보임!

  • 이게 체크 되어있기 때문에 블루프린트가 보이는 거!

 

  • 28p
<Button
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:text="위"
  android:textSize="20sp"
  android:layout_centerHorizontal="true"/>

 

<Button
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:text="아래"
  android:textSize="20sp"
  android:layout_centerHorizontal="true"
  android:layout_alignParentBottom="true"/>



<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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">

  <Button
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="위"
      android:textSize="20sp"
      android:layout_centerHorizontal="true"/>

  <Button
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="아래"
      android:textSize="20sp"
      android:layout_centerHorizontal="true"
      android:layout_alignParentBottom="true"/>

  <Button
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="좌측"
      android:textSize="20sp"
      android:layout_alignParentLeft="true"
      android:layout_centerVertical="true"/>

  <Button
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="중앙"
      android:textSize="20sp"
      android:layout_centerInParent="true"/>

  <Button
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="우측"
      android:textSize="20sp"
      android:layout_centerVertical="true"
      android:layout_alignParentRight="true"/>

</RelativeLayout>

 

======== 0612_ch05_Layout_Basic_RelativeLayout2

  • 왼쪽 선을 넘어갔기 때문에 toLeftOf (다른 부분도 동일함)

 

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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">

  <!--
  상대방 위젯과의 상대적 위치에 따른 위젯 배치를 위해
  기준 위젯에 대한
  -->
  <Button
      android:layout_width="150dp"
      android:layout_height="150dp"
      android:id="@+id/baseBtn"
      android:layout_centerInParent="true"
      android:text="기준위젯"
      android:textSize="30sp"/>
  <Button
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="1번"
      android:textSize="20sp"
      android:layout_toLeftOf="@id/baseBtn"
      android:layout_alignTop="@id/baseBtn"/>

</RelativeLayout>
  • 이 부분은 id 값을 지정하는 게 아니라 id 를 불러오는 거기 때문에 @+id 가 아닌 @id !

 

>

p.31

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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">

<!--
상대방 위젯과의 상대적 위치에 따른 위젯 배치를 위해
기준위젯에 대한 id 설정이 필요함 => id를 참조하여 상대 지정
-->
<Button
  android:layout_width="150dp"
  android:layout_height="150dp"
  android:id="@+id/baseBtn"
  android:layout_centerInParent="true"
  android:text="기준위젯"
  android:textSize="30sp"/>

<Button
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:text="1번"
  android:textSize="20sp"
  android:layout_toLeftOf="@id/baseBtn"
  android:layout_alignTop="@id/baseBtn"/>

<Button
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:text="2번"
  android:textSize="20sp"
  android:layout_toLeftOf="@id/baseBtn"
  android:layout_alignBaseline="@id/baseBtn"/>

<Button
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:text="3번"
  android:textSize="20sp"
  android:layout_toLeftOf="@id/baseBtn"
  android:layout_alignBottom="@id/baseBtn"/>

<Button
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:text="4번"
  android:textSize="20sp"
  android:layout_above="@id/baseBtn"
  android:layout_alignLeft="@id/baseBtn"/>

  <Button
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:text="5번"
  android:textSize="20sp"
  android:layout_below="@id/baseBtn"
  android:layout_alignRight="@id/baseBtn"/>

<Button
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:text="6번"
  android:textSize="20sp"
  android:layout_above="@id/baseBtn"
  android:layout_toRightOf="@id/baseBtn"/>

</RelativeLayout>

 

> 디자인탭에서 따로 설정도 가능! (엄청 많다~~)

ch05 테이블레이아웃 생략 → 그리드가 더 편함! 안드4버전 이상부터는 그리드 지원

======== 0616_ch05_Layout_Basic_GridLayout

< GridLayout >

  • TableLayout 또는 GridLayout 등은 위젯 추가 시 width, height 값 필요없음
  • 단, 실제 디자인 시 보다 깔끔한 디자인을 위해서는 위젯의  width, height 값을 수치(dp)로 직접 입력
<?xml version="1.0" encoding="utf-8"?>
<GridLayout 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:rowCount="2"
  android:columnCount="4">
 
  <!-- TableLayout 또는 GridLayout 등은 위젯 추가 시 width, height 값 필요없음 -->
  <Button
      android:text="1"/>

</GridLayout>
  • 버튼 9개 만들기
  • 4열이 다 차면 자동으로 넘어감
  • 2행 4열이라고 해서 2행까지만 나오는 건 아님!

 

> 버튼 8개로 줄이기

  • 칸은 합쳐졌는데 버튼들이 밀려남
  • 칸을 꽉채움!

 

<Button
  android:layout_row="0"
  android:layout_column="0"
  android:text="1"
  android:layout_rowSpan="2"
  android:layout_gravity="fill_vertical"/>
  • 원래는 이렇게 위치를 지정해줬는데 버전이 올라가면서 생략가능하게됨(0번 행의 0번 열에 위치)

 

<Button
  android:layout_row="0"
  android:layout_column="0"
  android:text="1"
  android:layout_rowSpan="2"
  android:layout_gravity="fill_vertical"/>

<Button
  android:text="2"
  android:layout_columnSpan="2"
  android:layout_gravity="fill_horizontal"/>

  • 세로로 꽉 채우는 것(fill_vertical)과, 가로로 꽉 채우는 것(fill_horizontal)

 

<?xml version="1.0" encoding="utf-8"?>
<GridLayout 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:rowCount="2"
  android:columnCount="4">

  <!--
  TableLayout 또는 GridLayout 등은 위젯 추가 시 width, height 값 필요없음
  단, 실제 디자인 시 보다 깔끔한 디자인을 위해서는 위젯의  width, height 값을 수치(dp)로 직접 입력
  -->
  <Button
      android:layout_row="0"
      android:layout_column="0"
      android:text="1"
      android:layout_rowSpan="2"
      android:layout_gravity="fill_vertical"/>

  <Button
      android:text="2"
      android:layout_row="0"
      android:layout_column="1"
      android:layout_columnSpan="2"
      android:layout_gravity="fill_horizontal"/>

  <Button
      android:layout_row="0"
      android:layout_column="3"
      android:text="3"/>

  <Button
      android:layout_row="1"
      android:layout_column="1"
      android:text="4"/>

  <Button
      android:layout_row="1"
      android:layout_column="2"
      android:text="5"/>

  <Button
      android:layout_row="1"
      android:layout_column="3"
      android:text="6"/>

</GridLayout>
  • android:layout_row="X"

android:layout_column="X" 다 달아주기(디자인 탭에서 늘릴 경우 빈 칸들이 생기기때문에 자리를 지정해주는 게 좋음!)

 

> ch05 50p

  • 만들어보기

 

< activity_main.xml >

<?xml version="1.0" encoding="utf-8"?>
<GridLayout 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:rowCount="9"
  android:columnCount="5">

  <EditText
      android:layout_row="0"
      android:layout_column="0"
      android:layout_columnSpan="5"
      android:id="@+id/et1"
      android:layout_width="400dp"
      android:layout_gravity="fill_horizontal"/>
  <EditText
      android:layout_row="1"
      android:layout_column="0"
      android:layout_columnSpan="5"
      android:id="@+id/et2"
      android:layout_width="400dp"
      android:layout_gravity="fill_horizontal"/>
  <Button
      android:layout_row="2"
      android:layout_column="0"
      android:id="@+id/btn0"
      android:layout_width="80dp"
      android:text="0"/>
  <Button
      android:layout_row="2"
      android:layout_column="1"
      android:id="@+id/btn1"
      android:layout_width="80dp"
      android:text="1"/>
  <Button
      android:layout_row="2"
      android:layout_column="2"
      android:id="@+id/btn2"
      android:layout_width="80dp"
      android:text="2"/>
  <Button
      android:layout_row="2"
      android:layout_column="3"
      android:id="@+id/btn3"
      android:layout_width="80dp"
      android:text="3"/>
  <Button
      android:layout_row="2"
      android:layout_column="4"
      android:id="@+id/btn4"
      android:layout_width="80dp"
      android:text="4"/>
  <Button
      android:layout_row="3"
      android:layout_column="0"
      android:id="@+id/btn5"
      android:layout_width="80dp"
      android:text="5"/>
  <Button
      android:layout_row="3"
      android:layout_column="1"
      android:id="@+id/btn6"
      android:layout_width="80dp"
      android:text="6"/>
  <Button
      android:layout_row="3"
      android:layout_column="2"
      android:id="@+id/btn7"
      android:layout_width="80dp"
      android:text="7"/>
  <Button
      android:layout_row="3"
      android:layout_column="3"
      android:id="@+id/btn8"
      android:layout_width="80dp"
      android:text="8"/>
  <Button
      android:layout_row="3"
      android:layout_column="4"
      android:id="@+id/btn9"
      android:layout_width="80dp"
      android:text="9"/>
  <Button
      android:layout_row="4"
      android:layout_column="0"
      android:layout_columnSpan="5"
      android:layout_width="400dp"
      android:layout_gravity="fill_horizontal"
      android:id="@+id/btnSum"
      android:text="더하기"/>
  <Button
      android:layout_row="5"
      android:layout_column="0"
      android:layout_columnSpan="5"
      android:layout_width="400dp"
      android:layout_gravity="fill_horizontal"
      android:id="@+id/btnMin"
      android:text="빼기"/>
  <Button
      android:layout_row="6"
      android:layout_column="0"
      android:layout_columnSpan="5"
      android:layout_width="400dp"
      android:layout_gravity="fill_horizontal"
      android:id="@+id/btnMul"
      android:text="곱하기"/>
  <Button
      android:layout_row="7"
      android:layout_column="0"
      android:layout_columnSpan="5"
      android:layout_width="400dp"
      android:layout_gravity="fill_horizontal"
      android:id="@+id/btnDiv"
      android:text="나누기"/>
  <TextView
      android:layout_row="8"
      android:layout_column="0"
      android:layout_columnSpan="5"
      android:text="계산 결과 :"
      android:textSize="30sp"
      android:id="@+id/tv1"
      android:layout_width="400dp"
      android:layout_gravity="fill_horizontal"/>

</GridLayout>

 

< MainActivity.java >

  EditText etNum1, etNum2;
  Button btnAdd, btnSub, btnMul, btnDiv;
  TextView tvResult;

//    Button btn0, btn1, btn2, btn3, btn4, btn5, btn6, btn7, btn8, btn9;
  // 숫자 버튼 10개 관리하는 다른 방법 - 배열을 사용하여 숫자버튼에 대한 ID 관리
  Button[] btnNums = new Button[10]; // Button 위젯의 객체를 저장할 Button 타입 배열 생성
  // Button 위젯에 대한 ID 를 저장할 int 형 배열 생성
  int[] btnNumsIds = { // 10개의 Button 에 대한 ID 를 배열에 직접 저장
          R.id.btn0, R.id.btn1, R.id.btn2, R.id.btn3, R.id.btn4,
          R.id.btn5, R.id.btn6, R.id.btn7, R.id.btn8, R.id.btn9
  };
  • 버튼만 따로

 

package com.example.a0616_ch05_p50_test_5_5;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

  EditText etNum1, etNum2;
  Button btnAdd, btnSub, btnMul, btnDiv;
  TextView tvResult;

//    Button btn0, btn1, btn2, btn3, btn4, btn5, btn6, btn7, btn8, btn9;
  // 숫자 버튼 10개 관리하는 다른 방법 - 배열을 사용하여 숫자버튼에 대한 ID 관리
  Button[] btnNums = new Button[10]; // Button 위젯의 객체를 저장할 Button 타입 배열 생성
  // Button 위젯에 대한 ID 를 저장할 int 형 배열 생성
  int[] btnNumsIds = { // 10개의 Button 에 대한 ID 를 배열에 직접 저장
          R.id.btn0, R.id.btn1, R.id.btn2, R.id.btn3, R.id.btn4,
          R.id.btn5, R.id.btn6, R.id.btn7, R.id.btn8, R.id.btn9
  };

  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);

      btnAdd = findViewById(R.id.btnSum);
      btnSub = findViewById(R.id.btnMin);
      btnMul = findViewById(R.id.btnMul);
      btnDiv = findViewById(R.id.btnDiv);

      etNum1 = findViewById(R.id.et1);
      etNum2 = findViewById(R.id.et2);

      tvResult = findViewById(R.id.tv1);

      // 숫자 Button 위젯 10개에 대한 ID 가져오는 작업을 반복문으로 수행
      for(int i = 0; i < btnNumsIds.length; i++) { // ID가 저장된 배열 크기를 조건식으로 사용
          // Button 위젯의 ID 가 저장된 배열의 각 요소를 findViewById() 메서드에 전달하여
          // 해당 ID 에 대한 위젯 객체를 Button 타입 배열의 각 요소에 저장
          btnNums[i] = findViewById(btnNumsIds[i]);
      }
      // -----------------------------------------------------
      // 숫자 버튼 클릭 시 EditText 에 숫자 표시를 위한 이벤트 처리
      // => 숫자 버튼 클릭에 대한 작업이 동일하므로 반복문을 사용하여 동일 작업을 처리
      for(int i = 0; i < btnNumsIds.length; i++) {
          btnNums[i].setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View v) {
                  // 현대 커서가 위치한 EditText 위젯을 판별 = isFocused() 메서드 활용
                  if(etNum1.isFocused()) {
                      Toast.makeText(MainActivity.this, "숫자1 EditText 커서위치함!", Toast.LENGTH_SHORT).show();
                  } else if(etNum2.isFocused()) {
                      Toast.makeText(MainActivity.this, "숫자2 EditText 커서위치함!", Toast.LENGTH_SHORT).show();
                  } else {
                      Toast.makeText(MainActivity.this, "숫자입력창 선택 필수!", Toast.LENGTH_SHORT).show();
                  }
              }
          });
      }

  }
}



  • 오류!!! i 가 빨간줄! 외부에 있는 변수이기 때문! 근데 외부의 i 는 for문에 있다,, for 문 안의 i를 final로 만들면 i 값이 안바뀌기 때문에 for 문의 i 값에 final 을 붙이면 안됨!
  • 그래서 대신 저장할 변수 하나를 만들어줌
      for(int i = 0; i < btnNumsIds.length; i++) {
          // 내부클래스에서 외부에 있는 변수에 접근 시 해당 변수가 final 이어야 한다.
          // 그러나, 반복문의 제어변수에 final 이 붙을 수 없으므로
          // 반복문 제어변수 값을 대신 저장할 변수 1개 필요
          final int index = i;
          btnNums[i].setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View v) {
                  // 현재 커서가 위치한 EditText 위젯을 판별 = isFocused() 메서드 활용
                  if(etNum1.isFocused()) {
//                        Toast.makeText(MainActivity.this, "숫자1 EditText 커서위치함!", Toast.LENGTH_SHORT).show();
                      // EditText(etNum1) 의 숫자를 가져와서 클릭된 버튼의 숫자와 결합하여 표시
                      etNum1.setText(etNum1.getText().toString() + btnNums[index].getText());
                  } else if(etNum2.isFocused()) {
                      Toast.makeText(MainActivity.this, "숫자2 EditText 커서위치함!", Toast.LENGTH_SHORT).show();
                  } else {
                      Toast.makeText(MainActivity.this, "숫자입력창 선택 필수!", Toast.LENGTH_SHORT).show();
                  }
              }
          });
      }
  • 주의할 점! onClick 안에 만들면 안됨! 위치 중요!
  • 이제 누르는대로 작동함



>>>> 

  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);

      btnAdd = findViewById(R.id.btnSum);
      btnSub = findViewById(R.id.btnMin);
      btnMul = findViewById(R.id.btnMul);
      btnDiv = findViewById(R.id.btnDiv);

      etNum1 = findViewById(R.id.et1);
      etNum2 = findViewById(R.id.et2);

      tvResult = findViewById(R.id.tv1);

      // 숫자 Button 위젯 10개에 대한 ID 가져오는 작업을 반복문으로 수행
      for(int i = 0; i < btnNumsIds.length; i++) { // ID가 저장된 배열 크기를 조건식으로 사용
          // Button 위젯의 ID 가 저장된 배열의 각 요소를 findViewById() 메서드에 전달하여
          // 해당 ID 에 대한 위젯 객체를 Button 타입 배열의 각 요소에 저장
          btnNums[i] = findViewById(btnNumsIds[i]);
      }
      // -----------------------------------------------------
      // 숫자 버튼 클릭 시 EditText 에 숫자 표시를 위한 이벤트 처리
      // => 숫자 버튼 클릭에 대한 작업이 동일하므로 반복문을 사용하여 동일 작업을 처리
      for(int i = 0; i < btnNumsIds.length; i++) {
          // 내부클래스에서 외부에 있는 변수에 접근 시 해당 변수가 final 이어야 한다.
          // 그러나, 반복문의 제어변수에 final 이 붙을 수 없으므로
          // 반복문 제어변수 값을 대신 저장할 변수 1개 필요
          final int index = i;
          btnNums[i].setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View v) {
                  // 현재 커서가 위치한 EditText 위젯을 판별 = isFocused() 메서드 활용
                  if(etNum1.isFocused()) {
//                        Toast.makeText(MainActivity.this, "숫자1 EditText 커서위치함!", Toast.LENGTH_SHORT).show();
                      // EditText(etNum1) 의 숫자를 가져와서 클릭된 버튼의 숫자와 결합하여 표시
                      etNum1.setText(etNum1.getText().toString() + btnNums[index].getText());
                  } else if(etNum2.isFocused()) {
//                        Toast.makeText(MainActivity.this, "숫자2 EditText 커서위치함!", Toast.LENGTH_SHORT).show();
                      etNum2.setText(etNum2.getText().toString() + btnNums[index].getText());
                  } else {
                      Toast.makeText(MainActivity.this, "숫자입력창 선택 필수!", Toast.LENGTH_SHORT).show();
                  }
              }
          });
      }

      View.OnClickListener listener = new View.OnClickListener() {
          @Override
          public void onClick(View v) {
              // 숫자1 또는 숫자2 가 입력되지 않았을 경우 해당 숫자 입력 요청 수행
              if(etNum1.length() == 0) {
                  Toast.makeText(MainActivity.this, "숫자1 입력 필수!", Toast.LENGTH_SHORT).show();\
                  etNum1.requestFocus(); // 커서요청
                  return; // 현재 메서드 종료
              } else if(etNum2.length() == 0) {
                  Toast.makeText(MainActivity.this, "숫자2 입력 필수!", Toast.LENGTH_SHORT).show();\
                  etNum2.requestFocus(); // 커서요청
                  return; // 현재 메서드 종료
              }

              // switch~case 문을 사용하여 각 버튼 판별
              switch(v.getId()) { // 클릭된 View 타입 객체의 ID 가져오기
                  // case 문을 사용하여 각 버튼의 ID 값과 비교
                  case R.id.btnSum :
                      Toast.makeText(MainActivity.this, "더하기", Toast.LENGTH_SHORT).show();
                      break;
                  case R.id.btnMin :
                      Toast.makeText(MainActivity.this, "빼기", Toast.LENGTH_SHORT).show();
                      break;
                  case R.id.btnMul :
                      Toast.makeText(MainActivity.this, "곱하기", Toast.LENGTH_SHORT).show();
                      break;
                  case R.id.btnDiv :
                      Toast.makeText(MainActivity.this, "나누기", Toast.LENGTH_SHORT).show();
              }
          }
      };

      btnAdd.setOnClickListener(listener);
      btnSub.setOnClickListener(listener);
      btnDiv.setOnClickListener(listener);
      btnMul.setOnClickListener(listener);

  }
}
  • return 과 break 필수!

 

> 최종코드

package com.example.a0616_ch05_p50_test_5_5;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

  EditText etNum1, etNum2;
  Button btnAdd, btnSub, btnMul, btnDiv;
  TextView tvResult;

//    Button btn0, btn1, btn2, btn3, btn4, btn5, btn6, btn7, btn8, btn9;
  // 숫자 버튼 10개 관리하는 다른 방법 - 배열을 사용하여 숫자버튼에 대한 ID 관리
  Button[] btnNums = new Button[10]; // Button 위젯의 객체를 저장할 Button 타입 배열 생성
  // Button 위젯에 대한 ID 를 저장할 int 형 배열 생성
  int[] btnNumsIds = { // 10개의 Button 에 대한 ID 를 배열에 직접 저장
          R.id.btn0, R.id.btn1, R.id.btn2, R.id.btn3, R.id.btn4,
          R.id.btn5, R.id.btn6, R.id.btn7, R.id.btn8, R.id.btn9
  };

  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);

      btnAdd = findViewById(R.id.btnSum);
      btnSub = findViewById(R.id.btnMin);
      btnMul = findViewById(R.id.btnMul);
      btnDiv = findViewById(R.id.btnDiv);

      etNum1 = findViewById(R.id.et1);
      etNum2 = findViewById(R.id.et2);

      tvResult = findViewById(R.id.tv1);

      // 숫자 Button 위젯 10개에 대한 ID 가져오는 작업을 반복문으로 수행
      for(int i = 0; i < btnNumsIds.length; i++) { // ID가 저장된 배열 크기를 조건식으로 사용
          // Button 위젯의 ID 가 저장된 배열의 각 요소를 findViewById() 메서드에 전달하여
          // 해당 ID 에 대한 위젯 객체를 Button 타입 배열의 각 요소에 저장
          btnNums[i] = findViewById(btnNumsIds[i]);
      }
      // -----------------------------------------------------
      // 숫자 버튼 클릭 시 EditText 에 숫자 표시를 위한 이벤트 처리
      // => 숫자 버튼 클릭에 대한 작업이 동일하므로 반복문을 사용하여 동일 작업을 처리
      for(int i = 0; i < btnNumsIds.length; i++) {
          // 내부클래스에서 외부에 있는 변수에 접근 시 해당 변수가 final 이어야 한다.
          // 그러나, 반복문의 제어변수에 final 이 붙을 수 없으므로
          // 반복문 제어변수 값을 대신 저장할 변수 1개 필요
          final int index = i;
          btnNums[i].setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View v) {
                  // 현재 커서가 위치한 EditText 위젯을 판별 = isFocused() 메서드 활용
                  if(etNum1.isFocused()) {
//                        Toast.makeText(MainActivity.this, "숫자1 EditText 커서위치함!", Toast.LENGTH_SHORT).show();
                      // EditText(etNum1) 의 숫자를 가져와서 클릭된 버튼의 숫자와 결합하여 표시
                      etNum1.setText(etNum1.getText().toString() + btnNums[index].getText());
                  } else if(etNum2.isFocused()) {
//                        Toast.makeText(MainActivity.this, "숫자2 EditText 커서위치함!", Toast.LENGTH_SHORT).show();
                      etNum2.setText(etNum2.getText().toString() + btnNums[index].getText());
                  } else {
                      Toast.makeText(MainActivity.this, "숫자입력창 선택 필수!", Toast.LENGTH_SHORT).show();
                  }
              }
          });
      }

      View.OnClickListener listener = new View.OnClickListener() {
          @Override
          public void onClick(View v) {
              // 숫자1 또는 숫자2 가 입력되지 않았을 경우 해당 숫자 입력 요청 수행
              if(etNum1.length() == 0) {
                  Toast.makeText(MainActivity.this, "숫자1 입력 필수!", Toast.LENGTH_SHORT).show();
                  etNum1.requestFocus(); // 커서요청
                  return; // 현재 메서드 종료
              } else if(etNum2.length() == 0) {
                  Toast.makeText(MainActivity.this, "숫자2 입력 필수!", Toast.LENGTH_SHORT).show();
                  etNum2.requestFocus(); // 커서요청
                  return; // 현재 메서드 종료
              }

              int num1 = Integer.parseInt(etNum1.getText().toString());
              int num2 = Integer.parseInt(etNum2.getText().toString());
              int result = 0;

              // switch~case 문을 사용하여 각 버튼 판별
              switch(v.getId()) { // 클릭된 View 타입 객체의 ID 가져오기
                  // case 문을 사용하여 각 버튼의 ID 값과 비교
                  case R.id.btnSum :
//                        Toast.makeText(MainActivity.this, "더하기", Toast.LENGTH_SHORT).show();
                      result = num1 + num2;
                      break;
                  case R.id.btnMin :
//                        Toast.makeText(MainActivity.this, "빼기", Toast.LENGTH_SHORT).show();
                      result = num1 - num2;
                      break;
                  case R.id.btnMul :
//                        Toast.makeText(MainActivity.this, "곱하기", Toast.LENGTH_SHORT).show();
                      result = num1 * num2;
                      break;
                  case R.id.btnDiv :
//                        Toast.makeText(MainActivity.this, "나누기", Toast.LENGTH_SHORT).show();
                      if(num1 == 0) {
                          Toast.makeText(MainActivity.this, "0으로 나눌 수 없음!", Toast.LENGTH_SHORT).show();
                          etNum1.requestFocus();
                          return;
                      } else if(num2 == 0) {
                          Toast.makeText(MainActivity.this, "0으로 나눌 수 없음!", Toast.LENGTH_SHORT).show();
                          etNum2.requestFocus();
                          return;
                      }
                      result = num1 / num2;
              } // Switch ~ case 문

              // 연산 결과를 TextView 에 출력
              tvResult.setText("계산 결과 : " + result);
          }
      };

      btnAdd.setOnClickListener(listener);
      btnSub.setOnClickListener(listener);
      btnDiv.setOnClickListener(listener);
      btnMul.setOnClickListener(listener);

  }
}

 

⇒ 이런식으로 위젯을 배열로 관리하는 것도 하나의 방법이다!

 

남은 FrameLayout 은 실습 X : 설명만

======== 0616_ch06_Chronometer_Basic

PDF 파일 chapter 6

< Chronometer >

<?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=".MainActivity">

  <Chronometer
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:textSize="30sp"
      android:id="@+id/chrono"/>

</LinearLayout>

 

<Chronometer
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:textSize="30sp"
  android:id="@+id/chrono"
  android:gravity="center"
  android:format="시간 측정 : %s"/>

 

<?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=".MainActivity"
  android:orientation="vertical">

  <Chronometer
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:textSize="30sp"
      android:id="@+id/chrono"
      android:gravity="center"
      android:format="시간 측정 : %s"/>
 
  <Button
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:id="@+id/btnStart"
      android:text="START"
      android:textSize="20sp"/>

</LinearLayout>
  • 버튼 추가

 

< MainActivity.java >

START 버튼을 클릭 시 Button 텍스트를 판별

현재 텍스트가 START 일 경우 STOP 으로 변경

현재 텍스트가 STOP 일 경우 START 으로 변경

package com.example.a0616_ch06_chronometer_basic;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Chronometer;

public class MainActivity extends AppCompatActivity {

  Button btnStart;
  Chronometer chronometer;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);

      btnStart = findViewById(R.id.btnStart);
      chronometer = findViewById(R.id.chrono);

      btnStart.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View v) {
              // START 버튼을 클릭 시 Button 텍스트를 판별
              // 현재 텍스트가 START 일 경우 STOP 으로 변경
              // 현재 텍스트가 STOP 일 경우 START 으로 변경
              if(btnStart.getText().equals("START")) {
                  btnStart.setText("STOP");
              } else if(btnStart.getText().equals("STOP")) {
                  btnStart.setText("START");
              }
          }
      });

  }
}
  • 버튼 클릭 이벤트 추가

 

if(btnStart.getText().equals("START")) {
  btnStart.setText("STOP");
  // chronometer 의 start() 메서드를 호출하여 타이머 가동
  chronometer.start(); // 타이머 시작
  chronometer.setTextColor(Color.RED); // 텍스트 색상을 빨간색으로 변경
} else if(btnStart.getText().equals("STOP")) {
  btnStart.setText("START");
  // chronometer 의 stop() 메서드를 호출하여 타이머 중지
  chronometer.stop(); // 타이머 중지
  chronometer.setTextColor(Color.BLUE); // 텍스트 색상을 파란색으로 변경
}

 

btnStart.setOnClickListener(new View.OnClickListener() {
  @Override
  public void onClick(View v) {
      // START 버튼을 클릭 시 Button 텍스트를 판별
      // 현재 텍스트가 START 일 경우 STOP 으로 변경
      // 현재 텍스트가 STOP 일 경우 START 으로 변경
      if(btnStart.getText().equals("START")) {
          btnStart.setText("STOP");

          // START 버튼 클릭 시 크로노미터의 시각을 0분 0초로 초기화
          chronometer.setBase(SystemClock.elapsedRealtime()); // 시간 초기화

          // chronometer 의 start() 메서드를 호출하여 타이머 가동
          chronometer.start(); // 타이머 시작
          chronometer.setTextColor(Color.RED); // 텍스트 색상을 빨간색으로 변경
      } else if(btnStart.getText().equals("STOP")) {
          btnStart.setText("START");
          // chronometer 의 stop() 메서드를 호출하여 타이머 중지
          chronometer.stop(); // 타이머 중지
          chronometer.setTextColor(Color.BLUE); // 텍스트 색상을 파란색으로 변경
      }
  }
});
  • STOP 눌렀다가 다시 START 누를 경우 0부터 다시 시작(초기화)

 

======== 0616_ch06_TimePicker_Basic

< TimePicker >

<?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=".MainActivity"
  android:orientation="vertical">

  <TimePicker
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:id="@+id/timePicker"/>

  <Button
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:id="@+id/btnPick"
      android:text="설정 완료"
      android:textSize="20sp"/>
 
</LinearLayout>
  • 시간 클릭 가능 (왼쪽 밑 키보드 버튼 클릭 시 직접입력도 가능)

 

  • TimePickerMode 속성

< timePickerMode 속성 >

  • 두가지가 있다
<TimePicker
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:id="@+id/timePicker"
  android:timePickerMode="spinner"/>

  • clock 이 디폴트 값

<!--

TimePicker : 시간을 선택할 수 있는 위젯

timePickerMode 속성을 생략하거나 clock 지정 시 시계 형태 디자인

만약, 속성을 spinner 지정 시 시, 분, 초를 회전시켜 선택 디자인

-->

 

< MainActivity.java >

  • 원래는 커런트아워, 커런트미닛 사용했음(예전버전)
package com.example.a0616_ch06_timepicker_basic;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TimePicker;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);


      final TimePicker tPicker = findViewById(R.id.timePicker);
      Button btnPick = findViewById(R.id.btnPick);

      btnPick.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View v) {
              int hour = tPicker.getHour();
              int min = tPicker.getMinute();
              Toast.makeText(MainActivity.this, hour + "시 " + min + "분", Toast.LENGTH_SHORT).show();

          }
      });

  }
}
  • 지금은 오류 뜨는데 무시하고 그냥 실행

 

  • 우리는 롤리팝 버전(Lv21)이라 그런 거! 최소 마시멜로우(Lv23) 버전 이상은 되어야 실행된다
  • 지금은 가상이라 그냥 실행되는거 실제 폰에서는 마시멜로우 이상 버전에만 실행

 

      btnPick.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View v) {
              // 안드로이드 API 23(Mashmellow) 부터 사용 가능한 코드
//                int hour = tPicker.getHour();
//                int min = tPicker.getMinute();

              // 만약, API Level 23 이전의 코드에서 사용 시 getCurrentXXX() 메서드 사용
              int hour = tPicker.getCurrentHour();
              int min = tPicker.getCurrentMinute();
              Toast.makeText(MainActivity.this, hour + "시 " + min + "분", Toast.LENGTH_SHORT).show();

          }
      });
  • 우린 Lollipop 버전이라 Deprecated 된 getCurrentXXX() 메서드 사용
  • 실행되는 기능은 똑같다!

 

======== 0616_ch06_DatePicker_Basic

< DatePicker >

<?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=".MainActivity"
  android:orientation="vertical">

  <DatePicker
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:id="@+id/dPicker"/>

  <Button
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:id="@+id/btnPick"
      android:text="설정 완료"
      android:textSize="20sp"/>

</LinearLayout>

 

< datePickerMode 속성 >

  • spinner

<!--

DatePicker : 날짜를 선택하는 위젯

datePickerMode="spinner" 선택 시 스피너와 캘린더 동시에 표시

datePickerMode="calendar" 선택 또는 생략 시 캘린더만 표시

-->

 

< MainActivity.java >

package com.example.a0616_ch06_datepicker_basic;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.DatePicker;

public class MainActivity extends AppCompatActivity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);

      final DatePicker datePicker = findViewById(R.id.dPicker);
      Button btnPick = findViewById(R.id.btnPick);

      btnPick.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View v) {
             
          }
      });
  }
}
  • id 값 들고와서 이벤트 연결

 

btnPick.setOnClickListener(new View.OnClickListener() {
  @Override
  public void onClick(View v) {
      int year = datePicker.getYear();
      int month = datePicker.getMonth();
      int day = datePicker.getDayOfMonth();

      Toast.makeText(MainActivity.this, year + "년 " + month + "월 " + day + "일", Toast.LENGTH_SHORT).show();
  }
});
  • 6월 18일을 찍었는데 Toast 는 5월 18일이 찍힘!
  • getMonth() 가 0부터 시작하기 때문
  • 그래서 int month = datePicker.getMonth()+1; 이렇게 +1 해준다

 

btnPick.setOnClickListener(new View.OnClickListener() {
  @Override
  public void onClick(View v) {
      int year = datePicker.getYear();
      int month = datePicker.getMonth()+1; // 0월 ~ 11월 사용하므로 getMonth() + 1 필요
      int day = datePicker.getDayOfMonth();

      Toast.makeText(MainActivity.this, year + "년 " + month + "월 " + day + "일", Toast.LENGTH_SHORT).show();
  }
});
  • 최종!

 

======== 0616_ch06_CalendarView_Basic

< CalendarView >

<?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=".MainActivity"
  android:orientation="vertical">

  <CalendarView
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:id="@+id/calendarView"/>

  <Button
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:id="@+id/btnPick"
      android:text="설정 완료"
      android:textSize="20sp"/>

</LinearLayout>
  • 심플하게 사용할 땐 CalendarView 가 낫다! 방법은 같음

 

< MainActivity.java >

  • calendarView 는 getYear() 등등의 메서드가 없음! (datePicker랑 좀 다름!)
  • getDate() 가 있는데 리턴타입이 long 타입! 따로 변환해줘야함(복잡하고 귀찮다..)

 

> 그래서 setOnDateChangeListener() 사용

  • 구현해보면 year, month, dayOfMonth 값 넘어옴

 

package com.example.a0616_ch06_calendarview_basic;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.CalendarView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
  int selectedYear, selectedMonth, selectedDay;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);

      final CalendarView calendarView = findViewById(R.id.calendarView);
      Button btnPick = findViewById(R.id.btnPick);

      // CalendarView 날짜 변경 시 동작하는 이벤트 처리
      calendarView.setOnDateChangeListener(new CalendarView.OnDateChangeListener() {
          @Override
          public void onSelectedDayChange(@NonNull CalendarView view, int year, int month, int dayOfMonth) {
          // 날짜가 변경되면 호출되는 메서드(파라미터로 변경된 날짜 정보가 각 변수로 전달됨)
//                Toast.makeText(MainActivity.this, year + "년 " + (month+1) + "월 " + dayOfMonth+1 + "일", Toast.LENGTH_SHORT).show();

              // 선택된 날짜를 별도의 멤버변수에 저장한 뒤 사용 가능!
              selectedYear = year;
              selectedMonth = month + 1;
              selectedDay = dayOfMonth;
          }
      });

      btnPick.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View v) {
              Toast.makeText(MainActivity.this, selectedYear + "년 " +
                      selectedMonth + "월 " + selectedDay + "일", Toast.LENGTH_SHORT).show();
          }
      });

  }
}

 

728x90