본문 바로가기
전공 수업/모바일 프로그래밍(Android Studio)

[6주 차] - 안드로이드 날짜 시간 관련 위젯, 기타 위젯, 간단한 기능과 복잡한 기능을 가진 View Container

by TwoJun 2023. 4. 13.

    과목명 : 모바일 프로그래밍(Mobile programming with Android Studio)

수업일자 : 2023년 04월 07일 (금)

Android Studio (Android Emulator)

 

 

 

 

 

 

1. 날짜 / 시간 관련 위젯 

1-1. 아날로그 시계, 디지털 시계

(1) AnalogClock, DigitalClock은 각각 아날로그 시계, 디지털 시계 위젯으로 모두 시간을 표시하는 위젯이며 두 위젯 모두 View 클래스를 상속받습니다.

View 클래스를 상속받고 있는 AnalogClock
View 클래스를 상속받고 있는 DigitalClock

 

 

(2) AnalogClock XML Code

<?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">

    <AnalogClock
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

<!--    <DigitalClock-->
<!--        android:layout_width="match_parent"-->
<!--        android:layout_height="wrap_content" />-->

</LinearLayout>

 

<실행 결과>

MainActivity.java 실행 환경

 

 

(3) DigitalClock XML Code

<?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">

<!--    <AnalogClock-->
<!--        android:layout_width="match_parent"-->
<!--        android:layout_height="wrap_content" />-->

    <DigitalClock
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="30dp"/>

</LinearLayout>

 

<실행 결과>

MainActivity.java 실행 환경

 

 

 

 

1-2. Chronometer (크로노미터)

(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">

    <Chronometer
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:format="시간 측정 : %s"
        android:gravity="center"
        android:textSize="30dp" />

</LinearLayout>

 

<실행 결과>

MainActivity.java 실행 환경

 

 

 

 

1-3. TimePicker, DatePicker, CalendarView

(1) TimePicker

- 시간을 표시하거나 조절하는 기능을 담당하는 위젯입니다.

 

(2) DatePicker, CalendarView

- 날짜를 표시하거나 조절하는 기능을 담당하는 위젯입니다.

 

(3) TimePicker, DatePicker, CalendarView 위젯 모두 View 클래스를 상속받습니다.

View 클래스를 상속받는 TimePicker

 

View 클래스를 상속받는 DatePicker

 

View 클래스를 상속받는 CalendarView

 

 

(4) TimePicker, DatePicker를 모두 spinner 형태로 표시하는 XML Code

<?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">
    
    <TimePicker
        android:timePickerMode="spinner"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    
    <DatePicker
        android:datePickerMode="spinner"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

 

<실행 결과>

MainActivity.java 실행 환경

 

 

 

 

1-4. 날짜 / 시간 예약 예시 Application

(1) XML Code

<?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:baselineAligned="false"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">
        <Chronometer
            android:id="@+id/chronometer"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:textSize="20dp"
            android:layout_gravity="center"
            android:format="예약에 걸린 시간 : %s"/>
        <Button
            android:id="@+id/btnStart"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="예약 시작"/>
    </LinearLayout>

    <RadioGroup
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
        <RadioButton
            android:id="@+id/rdoCal"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="날짜 설정(캘린더 뷰)"/>
        <RadioButton
            android:id="@+id/rdoTime"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="시간 설정"/>
    </RadioGroup>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dip"
        android:layout_weight="1">
        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="center">
            <CalendarView
                android:id="@+id/calendarView1"
                android:showWeekNumber="false"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />
            <TimePicker
                android:id="@+id/timePicker1"
                android:timePickerMode="spinner"
                android:layout_width="match_parent"
                android:layout_height="match_parent"/>
        </FrameLayout>
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <Button
            android:id="@+id/btnEnd"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="예약 완료"/>
        <TextView
            android:id="@+id/tvYear"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="0000"/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="년"/>
        <TextView
            android:id="@+id/tvMonth"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="00"/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="월"/>
        <TextView
            android:id="@+id/tvDate"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="00"/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="일"/>
        <TextView
            android:id="@+id/tvHour"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="00"/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="시"/>
        <TextView
            android:id="@+id/tvMinute"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="00"/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="분에 예약되었습니다."/>
    </LinearLayout>
</LinearLayout>

 

(2) MainActivity.java

package com.example.a6weekstest__;

import androidx.appcompat.app.AppCompatActivity;

import android.graphics.Color;
import android.os.Bundle;
import android.os.SystemClock;
import android.view.View;
import android.widget.Button;
import android.widget.CalendarView;
import android.widget.Chronometer;
import android.widget.RadioButton;
import android.widget.TextView;
import android.widget.TimePicker;

import org.w3c.dom.Text;

import java.sql.Time;

public class MainActivity extends AppCompatActivity {

    Chronometer chrono;
    Button btnStart, btnEnd;
    RadioButton rdoCal, rdoTime;
    CalendarView calView;
    TimePicker tPicker;
    TextView tvYear, tvMonth, tvDate, tvHour, tvMinute;
    int selectYear, selectMonth, selectDay;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setTitle("시간 예약 - 20170931");
        getSupportActionBar().setIcon(R.drawable.skullicon1220);
        getSupportActionBar().setDisplayShowHomeEnabled(true);

        // Button
        btnStart = (Button) findViewById(R.id.btnStart);
        btnEnd = (Button) findViewById(R.id.btnEnd);

        // Chronometer
        chrono = (Chronometer) findViewById(R.id.chronometer);

        // RadioButton
        rdoCal = (RadioButton) findViewById(R.id.rdoCal);
        rdoTime = (RadioButton) findViewById(R.id.rdoTime);

        // FrameLayout의 위젯 TimePicker, CalendarView
        tPicker = (TimePicker) findViewById(R.id.timePicker1);
        calView = (CalendarView) findViewById(R.id.calendarView1);

        // TextView의 Year, Month, Date, Minute, Hour,
        tvYear = (TextView) findViewById(R.id.tvYear);
        tvMonth = (TextView) findViewById(R.id.tvMonth);
        tvDate = (TextView) findViewById(R.id.tvDate);
        tvHour = (TextView) findViewById(R.id.tvHour);
        tvMinute = (TextView) findViewById(R.id.tvMinute);

        // 초기엔 TimePicker, CalendarView를 감추도록 한다.
        tPicker.setVisibility((View.INVISIBLE));
        calView.setVisibility((View.INVISIBLE));

        rdoCal.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                tPicker.setVisibility(View.INVISIBLE);
                calView.setVisibility(View.VISIBLE);
            }
        });

        rdoTime.setOnClickListener(new View.OnClickListener(){
            public void onClick(View v) {
                tPicker.setVisibility(View.VISIBLE);
                calView.setVisibility(View.INVISIBLE);
            }
        });

        // 예약 버튼을 누르면 예약까지 걸린 시간을 측정한다.
        btnStart.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                chrono.setBase(SystemClock.elapsedRealtime());
                chrono.start();
                chrono.setTextColor(Color.RED);
            }
        });

        // 예약 완료를 누르면 예약된 시간 정보를 가져온다.
        btnEnd.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                chrono.stop();
                chrono.setTextColor(Color.BLUE);
                tvYear.setText(Integer.toString(selectYear));
                tvMonth.setText(Integer.toString(selectMonth));
                tvDate.setText(Integer.toString(selectDay));
                tvHour.setText(Integer.toString(tPicker.getCurrentHour()));
                tvMinute.setText(Integer.toString(tPicker.getCurrentMinute()));

            }
        });

        calView.setOnDateChangeListener(new CalendarView.OnDateChangeListener() {
            public void onSelectedDayChange(CalendarView view, int year, int month, int dayofMonth) {
                selectYear = year;
                selectMonth = month;
                selectDay = dayofMonth;
            }
        });
    }
}

 

<실행 결과>

- 애플리케이션 초기 실행 화면입니다.

Application 실행 초기 화면

 

 

<실행 결과>

- 초기 실행 후 캘린더를 확인하기 위해 "날짜 설정" 라디오 버튼을 체크하면 아래와 같이 캘린더 뷰가 표시됩니다.

"날짜 설정" 라디오 버튼을 체크하면 위와 같이 CalendarView가 노출된다.

 

 

<실행 결과>

- TimePicker를 확인하기 위해 아래의 "시간 설정" 라디오 버튼을 체크하면 아래와 같이 TimePicker가 표시됩니다.

"시간 설정" 라디오 버튼을 체크하면 위와 같이 TimePicker가 표시된다.

 

 

<실행 결과>

- 예약까지 걸린 시간을 체크하기 위해 "예약 시작" 버튼을 누르면 Timer가 작동하기 시작합니다.

예약 시작 버튼을 클릭하면 상단의 타이머가 작동하는 것을 확인할 수 있다.

 

 

<실행 결과>

- 원하는 날짜와 시간을 모두 체크하고 하단의 "예약 완료" 버튼을 누르면 예약까지 걸린 시간과 언제 예약을 했는지 년, 월, 일 및 시간이 모두 표시됩니다.

캘린더 뷰에서 원하는 날짜를 선택한다.

 

TimePicker에서 원하는 시간을 설정한다.

 

최종적으로 예약 일자 / 시간이 하단에 출력되고 예약까지 걸린 시간도 확인할 수 있다.

 

 

 

 

 

 

2. Applicaiton Icon 설정하기

(1) 프로젝트 디렉토리에서 app / src / main / res / mipmap 디렉토리에 존재하는 이미지로 애플리케이션의 아이콘을 설정할 수 있습니다.

Project Directory

 

(2) res 디렉토리를 선택하고 마우스 우측 클릭 → New → Image asset(Configuration Image Asset) 페이지로 이동합니다.

res > New > Image Asset(Configuration Image Asset)

 

(3) Configuration Image Asset 페이지의 Source Asset에서 사용할 이미지를 선택, Layer name을 설정하고 하단의 Next를 클릭합니다.

Layer Name, Source Asset을 모두 설정하고 하단의 Next 버튼 클릭

 

(4) 최종 화면에서 모든 내용을 확인하고 Finish 버튼을 클릭합니다.

최종 확인 Finish

 

(5) 여기까지 완료되었다면 프로젝트 디렉토리를 확인했을 때 app / src / main / res / mipmap 디렉토리에 Layer name을 기반으로 한 새로운 이미지 디렉토리가 생성된 것을 확인할 수 있습니다.

 

 

(6) Emulator 환경을 확인해 보면 설정한 이미지로 Applicaiton Icon이 변경된 것을 확인할 수 있습니다.

Application Icon이 변경된 것을 확인할 수 있다.

 

 

 

 

 

 

3. 안드로이드 기타 위젯 : AutoCompleteTextView, MultiAutoCompleteTextView

(1) 두 위젯 모두 View 클래스, TextView 클래스를 상속받는 것을 확인할 수 있습니다.

View, TextView를 모두 상속받는 AutoCompleteTextView, MultiAutoCompleteTextView

 

 

 

 

4-1.  AutoCompleteTextView

(1) 자동 완성 텍스트 View의 경우 단어 1개가 자동으로 완성됩니다.

 

(2) 자동 완성 텍스트 View는 ",(Comma)" 자체를 단어로 인식해서 구분 역할을 수행할 수 없습니다.

 

 

 

 

4-2. MultiAutoCompleteTextView

(1) 멀티 자동 완성 텍스트 View의 경우 ",(Comma)"로 구분하여 여러 개의 단어가 자동으로 완성됩니다.

 

 

 

 

4-3. 예시 XML, MainActivity.java Code

(1) XML Code

<?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">

    <AutoCompleteTextView
        android:id="@+id/autoCompleteTextView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:hint="자동 완성 텍스트뷰"/>

    <MultiAutoCompleteTextView
        android:id="@+id/multiAutoCompleteTextView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:hint="멀티 자동 완성 텍스트 뷰"/>
</LinearLayout>

 

(2) MainActivity.java

 

package com.example.a6weekstest3;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.MultiAutoCompleteTextView;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        String[] items = { "CSI-NewYork", "CSI-Lasvegas", "CSI-Miami", "Friends", "Fringe", "Lost"};

        AutoCompleteTextView auto = (AutoCompleteTextView) findViewById(R.id.autoCompleteTextView1);
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                android.R.layout.simple_dropdown_item_1line, items);

        auto.setAdapter(adapter);

        MultiAutoCompleteTextView multi = (MultiAutoCompleteTextView) findViewById(R.id.multiAutoCompleteTextView1);

        MultiAutoCompleteTextView.CommaTokenizer token = new MultiAutoCompleteTextView.CommaTokenizer();
        multi.setTokenizer(token);
        multi.setAdapter(adapter);
    }
}

 

<실행 결과>

초기 실행 화면 - MainActivity.java

 

AutoCompleteTextView
MultiAutoCompleteTextView

 

 

 

 

 

 

4. 기타 위젯 : ProgressBar, SeekBar, RatingBar

4-1. ProgressBar

(1) 특정 작업의 진행 상태Bar 또는 원의 형태로 제공합니다.

- Bar 형태의 경우 작업의 진행 정도를 알 수 있지만 원 형태는 현재 진행 중인 상태만 표시해 줍니다.

 

 

 

 

4-2. ProgressBar의 속성

(1) android:max

- 범위를 지정하는 속성

 

(2) android:progress

- Bar의 시작 지점을 설정하는 속성

 

(3) android:secondaryProgress

- 두 번째 ProgressBar를 지정하는 속성

 

 

 

 

4-3. SeekBar

(1) ProgressBar의 하위 클래스로 ProgressBar와 유사하고 사용자가 터치로 임의 조절이 가능합니다.

 

 

 

 

4-4. RatingBar

(1) SeekBar, ProgressBar의 확장 버전으로 진행 상황을 별 모양으로 표시하며, 별도의 점수나 평가를 주고자 할 때 사용하며 별 모양의 형태로 레이팅을 적용해 줄 수 있습니다.

 

 

 

 

4-5. RatingBar의 XML 속성

(1) android:numStarts

- 별의 개수를 설정하는 속성

 

(2) android:rating

- 초기 값을 설정하는 속성

 

(3) android:stepSize

- 레이팅을 줄 때 한 번에 채워지는 개수를 설정하는 속성

 

 

 

 

4-6. ProgressBar, SeekBar, RatingBar 예시 코드

(1) XML Code

<?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">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="기타 위젯"
        android:textColor="#ff0000"
        android:textSize="30dp"
        android:layout_gravity="center"/>

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:backgroundTint="@color/teal_200"
        android:text="Button" />

    <ProgressBar
        android:id="@+id/progressBar"
        android:layout_margin="20dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

    <SeekBar
        android:id="@+id/seekBar"
        android:layout_margin="20dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

    <RatingBar
        android:id="@+id/ratingBar"
        android:layout_margin="20dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:contentDescription="평점을 주세요"
        android:numStars="5"/>
</LinearLayout>

 

<실행 결과>

MainActivity.java 실행 환경

 

 

 

 

 

 

5. 간단한 기능의 View Container

5-1. ScrollView

(1) 수직 방향으로 스크롤할 수 있는 View입니다.

 

(2) 수평 방향으로 스크롤하는 수평 스크롤 뷰(HorizontalScrollView)가 따로 존재합니다.

 

(3) ScrollView에는 단 하나의 위젯만 넣을 수 있습니다.

 

(4) ScrollView의 경우 View 클래스를 상속받습니다.

View 클래스를 상속받는 ScrollView

 

 

 

 

5-2. ScrollView의 XML Code

<?xml version="1.0" encoding="utf-8"?>
<ScrollView 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="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical">

        <Button
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:text="BUTTON 1" />

        <Button
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:text="BUTTON 2" />

        <Button
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:text="BUTTON 3" />

        <Button
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:text="BUTTON 4" />

        <Button
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:text="BUTTON 5"/>

        <Button
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:text="BUTTON 6"/>

        <Button
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:text="BUTTON 7"/>

        <Button
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:text="BUTTON 8"/>

        <Button
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:text="BUTTON 9"/>
    </LinearLayout>
    
</ScrollView>

 

< 위젯 배치 결과>

스크롤 내리기 전 위젯 배치

 

스크롤을 내린 위젯

 

 

 

 

5-3. SlidingDrawer

(1) 위젯을 서랍처럼 열어서 보여주거나 닫아서 감출 수 있는 위젯입니다.

 

(2) View 클래스를 상속받습니다.

View 클래스를 상속받는 SlidingDrawer

 

 

 

 

5-4. SlidingDrawer의 일반적인 형태

(1) SlidingDrawer의 handle 이름과 SlidingDrawer의 손잡이 역할을 하는 Button ID동일해야 합니다.

 

(2) SlidingDrawer의 content 이름과 LinearLayout의 ID동일해야 합니다.

SlidingDrawer의 일반적인 형태

 

 

 

 

5-5. SlidingDrawer의 예시 XML Code

<?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="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="서랍 외부"/>

    <SlidingDrawer
        android:content="@+id/content"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content">
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="서랍 손잡이"/>

        <LinearLayout
            android:id="@+id/content"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#00FF00"
            android:gravity="center">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="서랍 내부"/>
        </LinearLayout>
    </SlidingDrawer>
</LinearLayout>

 

<위젯 배치 결과>

SlidingDrawer

 

 

 

 

 

 

6. 복잡한 기능의 View Container

6-1. ViewFlipper

(1) 내부에 여러 개의 위젯을 배치한 후 필요에 따라서 화면을 왼쪽과 오른쪽으로 밀어서 하나의 위젯씩 화면에 보여주는 방식의 View 컨테이너를 의미합니다.

 

(2) ViewFlipper의 경우 View, ViewGroup 클래스를 상속받습니다.

View, ViewGroup 클래스를 상속받는 ViewFlipper

 

 

 

 

6-2. ViewFlipper의 일반적인 형태

ViewFlipper의 일반적인 형태

 

 

 

 

6-3. ViewFlipper 예시 XML, MainActivity.java Code

(1) XML Code

<?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="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <Button
            android:id="@+id/btnPrev"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="      이전 화면        "/>
        <Button
            android:id="@+id/btnNext"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="      다음 화면       " />
    </LinearLayout>

    <ViewFlipper
        android:id="@+id/viewFlipper1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#ff0000">
            <!-- ~~ 이곳에 필요한 위젯을 삽입 ~~>-->
        </LinearLayout>
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#00ff00">
            <!-- ~~ 이곳에 필요한 위젯을 삽입 ~~>-->
        </LinearLayout>
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#0000ff">
            <!-- ~~ 이곳에 필요한 위젯을 삽입 ~~>-->
        </LinearLayout>
    </ViewFlipper>
</LinearLayout>

 

(2) MainActivity.java

package com.example.a6weekstest4;

import androidx.appcompat.app.AppCompatActivity;

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

public class MainActivity extends AppCompatActivity {
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button btnPrev, btnNext;
        final ViewFlipper vFlipper;
        
        btnPrev = (Button) findViewById(R.id.btnPrev);
        btnNext = (Button) findViewById(R.id.btnNext);
        vFlipper = (ViewFlipper) findViewById(R.id.viewFlipper1);
        
        btnPrev.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                vFlipper.showPrevious();
            }
        });
        
        btnNext.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                vFlipper.showNext();
            }
        });
    }
}

 

<위젯 배치 결과>

ViewFlipper

 

 

 

 

6-4. TabHost

(1) 여러 탭을 배치하고 탭을 클릭할 때마다 특정 화면이 노출되도록 하는 View 컨테이너를 의미합니다.

 

(2) TabHost의 경우 View, ViewGroup 클래스를 상속받습니다. 

View, ViewGroup 클래스를 상속받는 TabHost

 

 

 

 

6-5. TabHost의 일반적인 형태 - XML Code

TabHost의 일반적인 형태 - XML Code

 

 

 

 

6-6. TabHost의 일반적인 형태 - MainActivity.java

(1) TabSpec 

- Tab을 구성하는 요소들의 집합입니다.

TabHost의 일반적인 형태 - MainActivity.java

 

 

 

 

6-7. TabHost의 주요 특징

(1) TabHost, TabWidget, FrameLayout의 경우 지정된 ID 값을 변경하지 않아야 안드로이드가 TabHost의 구성 요소임을 인식할 수 있습니다.

TabHost의 구성 방식

 

 

 

 

6-8. TabHost의 예시 XML, MainActivty.java Code

(1) XML Code

<?xml version="1.0" encoding="utf-8"?>
<TabHost 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="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:id="@android:id/tabhost">

    <LinearLayout
        android:layout_width="421dp"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <TabWidget
            android:id="@android:id/tabs"
            android:layout_width="410dp"
            android:layout_height="wrap_content"></TabWidget>

        <FrameLayout
            android:id="@android:id/tabcontent"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <LinearLayout
                android:id="@+id/tabSong"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="#f00000"
                android:orientation="horizontal" />

            <LinearLayout
                android:id="@+id/tabArtist"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="#f0f000"
                android:orientation="horizontal" />

            <LinearLayout
                android:id="@+id/tabAlbum"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="#f000ff"
                android:orientation="horizontal" />
        </FrameLayout>
    </LinearLayout>
</TabHost>

 

(2) MainActivity.java

package com.example.a6weekstest4;

import androidx.appcompat.app.AppCompatActivity;

import android.app.TabActivity;
import android.os.Bundle;
import android.widget.TabHost;

@SuppressWarnings("deprecation")
public class MainActivity extends TabActivity {

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

        TabHost tabHost = getTabHost();

        TabHost.TabSpec tabSpecSong = tabHost.newTabSpec("SONG").setIndicator("음악별");
        tabSpecSong.setContent(R.id.tabSong);
        tabHost.addTab(tabSpecSong);

        TabHost.TabSpec tabSpecArtist = tabHost.newTabSpec("ARTIST").setIndicator("가수별");
        tabSpecArtist.setContent(R.id.tabArtist);
        tabHost.addTab(tabSpecArtist);

        TabHost.TabSpec tabSpecAlbum = tabHost.newTabSpec("ALBUL").setIndicator("앨범별");
        tabSpecAlbum.setContent(R.id.tabAlbum);
        tabHost.addTab(tabSpecAlbum);

        tabHost.setCurrentTab(0);
    }
}

 

<실행 결과>

탭을 클릭할 때마다 화면 전환이 이루어지는 것을 확인할 수 있다.

 

 

 

 

6-9. ActionBar, Fragment

(1) ActionBar

- ActionBar의 경우 허니콤(Android 3.0, API 11)에서 태블릿과 같은 환경에서 여러 화면을 사용하기 위해 고안된 View 컨테이너입니다.

 

- 태블릿, 스마트폰 등 다양한 크기의 화면을 디자인할 때 사용될 수 있습니다.

 

 

(2) Fragment

- Activity보다 더 작은 단위의 화면입니다.

 

- Fragment를 사용하면 대형 화면에서 Activity 화면을 분할해서 표현할 수 있습니다.

 

- 스마트폰과 같은 소형 화면에서 화면의 분할보다는 실행 중에 화면을 동적으로 추가, 제거하는데 더 많이 사용됩니다.

 

 

 

 

6-10. ActionBar, Fragment를 활용한 화면 구현

(1) ActionBar를 생성한 후 Tab 위젯을 ActionBar에 등록합니다.

ActionBar와 Fragment의 구성 방식

 

(2) XML을 사용하지 않고 Java 코드로 구현합니다.

ActionBar에 Tab을 추가하는 Java 코드 형식

 

 

 

 

6-11. ActionBar의 MainActivty.java 예시 Code (1) 

package com.example.a6weekstest4;

import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.FragmentTransaction;

import android.app.ActionBar;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity implements ActionBar.TabListener {
    androidx.appcompat.app.ActionBar.Tab tabSong;
    ActionBar.Tab tabArtist;
    ActionBar.Tab tabAlbum;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        androidx.appcompat.app.ActionBar bar = getSupportActionBar();
        bar.setNavigationMode(androidx.appcompat.app.ActionBar.NAVIGATION_MODE_TABS);
        
        tabSong = bar.newTab();
        tabSong.setText("음악별");
        tabSong.setTabListener((androidx.appcompat.app.ActionBar.TabListener) this);
        bar.addTab(tabSong);
        
        // ~~ 생략(tabArtist, tabAlbum);
    }
    
    public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
        
    }
    public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
        
    }
    public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {

    }
}

 

 

 

 

6-11. ActionBar의 MainActivty.java 예시 Code (2)

(1) Fragment를 상속받는 MyTabFragment 클래스를 내부 클래스로 생성합니다.

package com.example.a6weekstest4;

import android.graphics.Color;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;

public class MyTabFragment extends androidx.fragment.app.Fragment {
    String tabName;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Bundle data = getArguments();
        tabName = data.getString("tabName");
    }
    
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle saveInstanceState) {
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.MATCH_PARENT,
                LinearLayout.LayoutParams.MATCH_PARENT);
        LinearLayout baseLayout =  new LinearLayout(super.getActivity());
        baseLayout.setOrientation(LinearLayout.VERTICAL);
        baseLayout.setLayoutParams(params);
        
        if (tabName == "음악별")
            baseLayout.setBackgroundColor(Color.RED);
        if (tabName == "가수별")
            baseLayout.setBackgroundColor(Color.GREEN);
        if (tabName == "앨범별")
            baseLayout.setBackgroundColor(Color.BLUE);
        
        return baseLayout;
    }
}

 

 

 

 

6-12. ActionBar의 MainActivty.java 예시 Code (3)

(1) 멤버변수로 Fragment 배열 변수를 추가하고 onTabSelected() 메소드를 구현합니다.

package com.example.a6weekstest4;

import android.os.Bundle;
import androidx.fragment.app.FragmentTransaction;
import com.google.android.material.tabs.TabLayout;

public class MyTabFragment extends androidx.fragment.app.Fragment {
    String tabName;
    
    // 멤버변수로 Fragment의 배열 변수를 추가한다.
    MyTabFragment myFrags[] = new MyTabFragment[3];
    
    public void onTabSelected(TabLayout.Tab tab, FragmentTransaction ft) {
        MyTabFragment myTabFrag = null;
        
        if (myFrags[tab.getPosition()] == null) {
            myTabFrag = new MyTabFragment();
            Bundle data = new Bundle();
            data.putString("tabName", tab.getText().toString());
            myTabFrag.setArguments(data);
            myFrags[tab.getPosition()] = myTabFrag;
        }
        else 
            myTabFrag = myFrags[tab.getPosition()];
        
        ft.replace(android.R.id.content, myTabFrag);
    }
}

 

 

 

 

 

 

7. Reference

(1) Reference

- Android Studio를 활용한 안드로이드 프로그래밍 / 한빛아카데미(Hanbit Academy, Inc.)

 

(2) URL

https://www.hanbit.co.kr/store/books/look.php?p_code=B1212492850 

 

IT CookBook, Android Studio를 활용한 안드로이드 프로그래밍(7판)

안드로이드 프로그래밍을 하면서 부딪힐 수 있는 다양한 오류나 실수까지 친절하게 안내하여 시행착오 없이 안드로이드를 빠르게 정복할 수 있습니다.

www.hanbit.co.kr

 

 

 

 

- 학부에서 수강했던 전공 수업 내용을 정리하는 포스팅입니다.

- 내용 중에서 오타 또는 잘못된 내용이 있을 시 지적해 주시기 바랍니다.

댓글