본문 바로가기

카테고리 없음

71일차 공부 Toast, Snackbar, AlertDialog

** Toast

=> 짧은 문자열을 출력하는 작은 대화상자

=> 안드로이드 시스템이 제공 : 앱이 종료되도 출력이 가능

=> 플로팅(화면에 떠 있는 상태) 형태로 화면 하단에 나타났다가 일정 시간이 지나면 자동으로 사라진다.

=> 알림 사항을 전달만 하고 포커스를 받을 수 가 없다.

 

1. 생성

Toast.makeText(Context context, int resin, int duration)

Toast.makeText(Context context, CharSequence text, int duration)

=> context는 toast는 화면에 출력되는 요소이기 때문에 화면 출력 정보를 소유한 Context를 매개변수로 받아야 한다.

Context는 화면에 무엇인가를 출력할 때 사용하기 위한 선색상, 면색상, 글자 색상, 배경 색상 등의 정보를 소유한 객체

안드로이드에서는 직접 Context를 생성하는 경우는 거의 없고 Context를 상속받는 Activity를 이용해서 화면을 출력한다.

Activity에 대한 참조를 얻는 방법은 Activity 클래스 안에서는 this나 Activity.this를 이용한다.

이벤트 처리를 할 때 Anonymous class를 자주 사용하는데 anonymous class 에서는 this를 사용하게 되면 anonymous class 자신이 되버리기 때문에 이 때는 Activity.this를 이용해야 Activity 클래스의 객체에 대한 참조를 할 수 있다.

 

Public class SampleActivity{
	public void onCreate(){
		btn.setOnClickListener(new View.OnCLickListener(){
			//this는 View.OnClickListener 의 인스턴스에 대한 참조이다.
			//SampleActivity.this가 SampleActivity의 인스턴스에 대한 참조이다.
		});
	}
}

 

Anonymous class는 클래스를 생성하지 않고 인스턴스를 생성하는 것이다.

this는 현재 인스턴스의 참조이다.

 

=> 안드로이드에서는 getApplicationContext()라는 메소드를 호출하면 시작하는 Activity에 대한 포인터를 리턴받을 수 있다.

 

안드로이드에서 데이터를 공유하고 싶으면 mainActivity에 만들어서 쓰면 된다.

 

=> 두번째 매개변수는 출력할 메세지로 string.xml 파일에 리소스로 등록하고 그 리소스 id를 설정해도 되고 직접 문자열로 설정해도 된다.

안드로이드에서는 String도 많이 사용하지만 String의 상위 인터페이스인 CharSequence나 Editable도 자주 사용한다.

문자열을 리턴할 때 리턴하는 문자열의 자료형을 정확하게 확인해서 CharSequence나 Editable이면 toString()을 호출해서 문자열로 변환해서 사용한다.

 

=> 세번째 매개변수는 토스트를 출력할 시간인데 1/1000 초 단위로 설정할 수 있는데 대부분은 Toast.SHORT 나 Toast.LONG과 같은 상수를 이용한다.

 

2. 출력

show()를 호출하면 된다

 

3. 기타 메소드

=> setGravity  맞춤해주는것

=> setMargin  여백주는것

=> setText

=> setDuration

=> cancel

=> setView(View view) : View를 설정 - 모양 변경

 

4. 실습

=> 버튼을 누르면 토스트가 출력되도록 하기

 

1) 프로젝트를 생성하거나 실행 가능한 Activity를 추가

 

2) 레이아웃에 버튼 1개 추가

 

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:id="@+id/toastdisp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

 

3) Activity.java 파일의 onCreate 메소드 수정

 

package com.example.android0716;

import androidx.appcompat.app.AppCompatActivity;

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

public class MainActivity extends AppCompatActivity {

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

        //xml에 디자인 한 뷰 객체 찾아오기
        Button btn = (Button)findViewById(R.id.toastdisp);
        //버튼 클릭했을 때 처리
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast toast = Toast.makeText(
                        MainActivity.this, "토스트를 출력합니다", Toast.LENGTH_LONG);
                //토스트를 화면에 출력
                toast.show();
            }
        });
    }
}

 

 

** Snackbar

=> 하단에 고정된 위치에 메시지를 출력해주는 UI

=> 초창기 안드로이드 버전에 없었고 나중에 추가가 되었다.

라이브러리를 추가해서 사용해야 한다.

 

1. 안드로이드에서 추가된 라이브러리 사용

=> 안드로이드는 버전이 엡데이트 될 때 새로운 UI를 추가하는 경우가 많아서 이런 UI를 사용할 때 사용

 

1) File - Project Structure 메뉴를 실행

 

2) 왼쪽 창에서 Module 하단의 app을 선택

 

3) 오른쪽 탭에서 dependencies를 선택하고 + 버튼을 눌러서 필요한 라이브러리 추가

 

Snackbar는 support.design 라이브러리를 추가해서 사용

 

2. Snackbar

=> Snackbar는 Action을 통해서 onClick을 설정할 수 있다.

사용자와의 인터페이스로 이용 가능

=> Toast는 Context를 매개변수로 받지만 Snackbar는 View를 매개변수로 받음

1) 생성

Snackbar.make(View view, CharSequence text, int duration)

Snackbar.make(View view, int residents, int duration)

 

2) 출력

show();

 

3) 클릭했을 때 동작 지정

 

setAction(String msg, new View.OnClickListener(){
	public void onClick(View view){
		클랙했을 때 수행할 내용;
	});
}

 

 

3. 버튼을 클릭했을 때 Snackbar 출력하기

1) support.design 라이브러리를 추가

=> [File] - [Project Structure] 실행

 

2) dependencies 에서

등록된걸 확인하고 OK 를 누르면 라이브러리를 다운받기 시작한다.

 

 

3) Activity.java 클래스의 onCreate 메소드에서 버튼의 클릭 처리 메소드의 내용을 수정

 

package com.example.android0716;

import androidx.appcompat.app.AppCompatActivity;

import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import com.google.android.material.snackbar.Snackbar;

public class MainActivity extends AppCompatActivity {

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

        //xml에 디자인 한 뷰 객체 찾아오기
        Button btn = (Button)findViewById(R.id.toastdisp);
        //버튼 클릭했을 때 처리
        btn.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View view){
                /*
                //토스트 만들기
                Toast toast = Toast.makeText(
                        MainActivity.this,
                        "토스트를 출력합니다.",
                        Toast.LENGTH_LONG);
                //토스트를 화면에 출력
                toast.show();
                */

                //스낵바 출력
                Snackbar.make(view, "스낵바 출력",
                        Snackbar.LENGTH_LONG)
                        .setAction("SONG",
                                new View.OnClickListener(){
                                    public void onClick(View view){
                                        MediaPlayer player =
                                                MediaPlayer.create(
                                                        MainActivity.this, R.raw.spice);
                                        player.start();
                                    }
                                })
                        .show();
            }
        });
    }
}

 

** 대화상자 - Dialog

=> 사용자에게 전달 사항을 알리고 사용자의 선택을 받아들이는 통신 수단 중의 하나

=> Activity를 화면에 그대로 유지한 채 중앙에 열리기 때문에 메세지를 보여주거나 추가 입력 또는 선택용으로 사용하기에 적합

 

1. 생성 및 출력

1) Dialog 생성

=> 생성자에 Context를 대입받아서 생성

 

2) 모양 설정

setContentView(View view)로 출려되는 모양 설정

setTitle(문자열)을 이용해서 제목을 설정

 

3) 출력

show();

 

2. 일반 다이얼로그 출력

1) 사용가능한 Activity 추가

 

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

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="대화상자 출력"
        android:id="@+id/dlgshow"/>

</LinearLayout>

 

 

2) Activity.java 파일의 onCreate 메소드 수정

 

package com.example.android0716;

import androidx.appcompat.app.AppCompatActivity;

import android.app.Dialog;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class DialogActivity extends AppCompatActivity {

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

        Button dlgshow = (Button)findViewById(R.id.dlgshow);
        dlgshow.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //대화상자 생성
                Dialog dlg = new Dialog(DialogActivity.this);
                TextView txtView = new TextView(DialogActivity.this);
                txtView.setText("대화상자 출력");
                //모양설정
                dlg.setContentView(txtView);
                dlg.setTitle("대화상자");
                //출력
                dlg.show();
            }
        });
    }
}

 

3. AlertDialog

=> Dialog 클래스는 화면 모든 영역을 직접 디자인해야 하지만 AlertDialog는 문자열 메시지 그리고 타이틀 바와 아이콘 영역 등을 미리 만들어 두고 사용자가 선택해서 설정만 하면 생성할 수 있도록 만든 Dialog의 고수준 매핑 클래스

 

=> 생성자는 protected로 되어 있어서 직접 호출하지 못하고 Builder를 통해서 생성

=> 설정과 관련된 메소드들은 다시 AlertDialog를 리턴하기 때문에 메소드를 연속해서 호출하는 형태로 디자인을 한다.

AlertDialog.Builder setMessage(CharSequence message)

AlertDialog.Builder setTitle(CharSequence titile)

AlertDialog.Builder setIcon(int iconid)

 

AlertDialog(CharSequence message, CharSequence titile, int iconId)

제너릭 객체를 대입할때 내부자료형을 설정하는 것

 

 

 

이와 유사한 형태의 클래스로는 String이 있다.

 

=> 출력은 show 메소드를 이용한다.

 

=> 어떤 클래스를 디자인 할때 생성하는 부분이 복잡하면 생성자를 private 이나 protected로 숨기고 별도의 메소드를 이용해서 생성하도록 만들어주어야 한다.

이러한 디자인 패턴을 팩토리 메소드 패턴이라고 한다.

 

=> 하나의 클래스에 설정해야할 내용이 많은 경우 하나의 메소드에서 전부 설정하면 메소드의 모양이 너무 복잡해지거나 오버로딩을 많이 하게 되거나 또는 별도의 클래스를 만들어야 하는 일이 발생한다.

이런 경우 Map을 이용해서 설정하는 경우가 있는데 바람직하지 못하다.

Map은 리턴 타입으로 사용하는 것이 좋다.

 

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

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="대화상자 출력"
        android:id="@+id/dlgshow"/>
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="대화상자 출력"
        android:id="@+id/alertdialog"/>

</LinearLayout>

 

 

2. Activity.java 클래스의 onCreate메소드에 클릭 이벤트를 작성해서 AlertDialog를 출력

 

package com.example.android0716;

import androidx.appcompat.app.AppCompatActivity;

import android.app.AlertDialog;
import android.app.Dialog;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class DialogActivity extends AppCompatActivity {

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

        Button dlgshow = (Button)findViewById(R.id.dlgshow);
        dlgshow.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //대화상자 생성
                Dialog dlg = new Dialog(DialogActivity.this);
                TextView txtView = new TextView(DialogActivity.this);
                txtView.setText("대화상자 출력");
                //모양설정
                dlg.setContentView(txtView);
                dlg.setTitle("대화상자");
                //출력
                dlg.show();
            }
        });

        Button alertdialog = (Button)findViewById(R.id.alertdialog);
        alertdialog.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                AlertDialog.Builder dlg = new AlertDialog.Builder(DialogActivity.this);
                dlg.setTitle("제목") // 메소드 체이닝(Method Chainning)
                        .setMessage("내용")
                        .setIcon(android.R.drawable.ic_dialog_alert)
                        .show();
            }
        });
    }
}

 

=> 연속적으로 메소드를 호출하는 것을 Method Chainning이라고 하는데 메소드 체이닝을 할 수 있도록 만드는 경우는 어떤 작업을 할 때 설정해야 할 내용이 많고 그 내용들이 필수가 아니고 선택적으로 설정해야 하는 경우 한번에 설정하도록 하면 순서를 기억해야 하거나 종류들을 전부 기억해야 하기 때문에 체이닝 형태로 설정할 수 있도록 만들어 준다.

 

=> 대화상자에 버튼 배치

대화상자에는 사용자가 어떤선택을 했는지 알 수 있도록 버튼을 추가 할 수 있다.

AlertDialog에는 버튼을 추가할 수 있는 메소드가 3가지가 있는데 이름만 다르고 사용방법은 모두 동일하다.

코딩의 의미를 전달하기 위해서 메소드 이름을 다르게 만들어 둔 것이다.

setPositiveButton(CharSequence text, DialogInterface.OnClickListener listener)

setNeutralButton(CharSequence text, DialogInterface.OnClickListener listener)

setNegativeButton(CharSequence text, DialogInterface.OnClickListener listener)

여기서 만들어지는 버튼들은 기본적으로 대화상자를 닫는 기능을 가지고 있다.

 

=> 안드로이드는 Back Button을 가지고 있어서 BackButton을 누르면 대화상자가 닫히게 된다.

setCancelable(boolean cancelable)을 호출해서 false를 대입하면 BackButton을 눌러도 대화상자가 닫히지 않게 된다.

 

4. 화면 출력 처리 방식

1) 1초에 1씩 증가하면서 TextView에 숫자를 출력하기

=> 실행 가능한 Activity 생성

 

=> 레이아웃에 테그트 뷰 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=".DisplayActivity"
    android:orientation="vertical">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="value"
        android:id="@+id/display"/>
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="대화상자 출력"
        android:id="@+id/btn"/>

</LinearLayout>

 

3) Activity.java 클래스에 작업을 위한 코드를 작성

 

package com.example.android0716;

import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;

import android.content.DialogInterface;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class DisplayActivity extends AppCompatActivity {
    String msg = "기본값";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_display);

        final TextView display =(TextView)findViewById(R.id.display);
        /*
        try{
                //1초에 출력될 것 같지만 실제로는 모아서 출력하기 때문에
                //마지막에 10만 출력됩니다.
            for(int i=1; i<=10; i=i+1){
                Thread.sleep(1000);
                Log.e("i:", i+"");
                display.setText("i=" + i);
            }
        }catch(Exception e){}
        */

        Button btn = (Button)findViewById(R.id.btn);
        //버튼을 클릭했을 때 처리
        btn.setOnClickListener(new View.OnClickListener(){
            public void onClick(View view){
                //대화상자를 생성
                AlertDialog.Builder dlg = new AlertDialog.Builder(DisplayActivity.this);
                //대화상자 모양을 설정하고 출력
                dlg.setTitle("대화상자 콜백")
                        .setMessage("대화상자는 어떻게 동작?")
                        .setPositiveButton("확인",
                                new DialogInterface.OnClickListener() {
                                    @Override
                                    public void onClick(DialogInterface dialogInterface, int i) {
                                        msg="확인";
                                        try {
                                            for (int j = 0; j < 10; j++) {
                                                Thread.sleep(1000);
                                                Log.e("j:", j + "");
                                            }
                                        }catch(Exception e){}
                                    }
                                })
                        .setNegativeButton("취소",
                                new DialogInterface.OnClickListener() {
                                    @Override
                                    public void onClick(DialogInterface dialogInterface, int i) {
                                        msg = "취소";
                                    }
                                })
                        .show();
                //대화상자가 출력됨과 동시에 수행됩니다.
                //대화상자가 닫히고 난 후 수행하는 코드를 만들려면
                //대화상자의 콜백 메소드를 이용해야 합니다.
                display.setText(msg);
            }
        });
    }
}

 

 

** GUI 프로그래밍에서의 화면 출력

=> 하나의 메소드 안에 화면 출력하는 코드와 그렇지 않은 코드가 같이 존재하면 화면 출력을 하는 코드는 오랜 시간이 걸리기 때문에 나중에 처리한다.

화면 출력 이후에 작업을 수행하고자 하면 화면 출력이 끝나면 수행해 달라고 콜백 메소드에 작성을 해주어야 한다.

=> Callback Method : 이벤트가 발생하면 호출되는 메소드

=> 스레드를 이용하지 않고 주기적으로 화면 갱신을 수행하면 모아서 한꺼번에 처리한다.

화면 갱신은 오랜시간이 걸리는 작업이라서 모아서 한꺼번에 처리한다.

GUI 프로그래밍을 할 때는 스레드를 만드는 것을 할 수 있어야하고 main 스레드와 다른 스레드를 구분할 수 있어야 한다.

Main 스레드에서만 화면 갱신을 할 수 있기 때문이며 이러한 이유로 main 스레드에게 수행할 내용을 전달하는 방식을 반드시 알아야 한다.

 

** 목록 선택 대화 상자

=> AlertDialog는 버튼을 배치하는 메소드를 3개 가지고 있다.

Positive, Neutral, Negative 이다.

하나의 메소드를 2번이상 호출하면 마지막에 호출한 것 하나만 유효하다.

이런 이유로 버튼을 3개 까지만 배치가 가능하다.

=> 4개 이상의 목록에서 선택하는 대화상자를 만들고자 할 때는 목록선택 대화상자를 만들어야 한다.

이 때는 setItems(CharSequece [] items 또는 int intesId, DialogInterface.OnClickListener listener)를 호출해야 한다.

=> 문자열 배열을 리소스로 만들 때는 values 디렉토리에 arrays.xml 파일에 만들면 된다.

=> listener 의 onClick메소드의 2번째 매개변수가 선택한 아이템의 인덱스다.

 

=> setItems 대신에 setSingleChoiceItems를 호출하면 목록 옆에 라이도 버튼이 생성되서 하나만 선택할 수 있도록 해준다.

이 메소드는 문자열 배열 ,리소스 아이디, ListAdapter, Cursor를 매개변수로 받을 수 있다.

 

=> setMultiChoiceItems 메소드를 호출하면 다중 선택이 가능한 목록 대화상자를 만들 수 있다. 이 메소드는 boolean 배열을 매개변수로 받아서 선택한 목록들의 인덱스에 해당하는 데이터만 true로 설정

 

** ProgressDialog

=> 진행 상황을 표시해주는 다이얼로그

=> setProgressStyle 이라는 메소드를 이용해서 막대모양이나 원 모양의 진행율을 표시할 수 있다.

 

** Date 또는 TimePickerDialog

=> DatePickerDialog : 날짜를 선택할 수 있는 대화상자

=> TimePickerDialog : 시간을 선택할 수 있는 대화상자

=> 스마트 폰은 초단위 설정이 안된다.

 

** Custom Dialog

=> 사용자가 디자인 한 뷰를 출력하는 다이얼로그

=> 뷰는 자바코드로 직접 생성해서 설정해도 되지만 layout.xml 파일을 만들어서 작성한 후 전개해서 사용해도 된다.

전개는 layout.xml 파일로 만든 걸 View 클래스의 객채로 변환하는 작업을 말한다.

 

=> 로그인 다이얼로그를 만들어서 출력하고 입력한 내용을 확인하는 예제

1. 실행 가능한 Activity를 생성 (LoginActivity)

 

2. activity_login.xml 파일 수정

=> TextView1개와 대화상자를 출력할 버튼 1개를 추가

=> 실제 작업이라면 로그인을 할 수 있도록 할 Activity에 버튼이나 ImageView 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=".LoginActivity"
    android:orientation="vertical">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="결과"
        android:textSize="30sp"
        android:id="@+id/result"/>
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="로그인"
        android:textSize="30sp"
        android:id="@+id/login"/>

</LinearLayout>

 

3) res/layout 디렉토리에 로그인 화면으로 사용할 layout 파일을 추가하고 

 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="5dp">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="아이디"
        android:textSize="20dp"/>
    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/id"/>

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="비밀번호"
        android:textSize="20dp"/>
    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/pw"/>

</LinearLayout>

 

 

4. LoginActivity.java 파일에 인스턴스 변수를 선언

=> 버튼과 텍스트 뷰 변수

 

public class LoginActivity extends AppCompatActivity {
    //화면에 보여지는 버튼과 텍스트 뷰에 대한 변수
    Button loginbtn;
    TextView result;

 

5. LoginActivity.java 파일의 onCreate 메소드에 작업 내용을 작성

 

package com.example.android0716;

import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;

import android.content.DialogInterface;
import android.media.MediaCasStateException;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;

public class LoginActivity extends AppCompatActivity {
    //화면에 보여지는 버튼과 텍스트 뷰에 대한 변수
    Button loginbtn;
    TextView result;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);

        //뷰를 찾아오기
        result = (TextView)findViewById(R.id.result);
        loginbtn = (Button)findViewById(R.id.login);
        //버튼을 눌렀을 때 처리
        loginbtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //layout 파일에 만든 뷰를 전개하기
                //Anonymous class 나 Lambda 식에서는 자신이 속한 메소드의 지역변수를 사용할 수 없다.
                //사용하고자 하는 변수가 있으면 이 변수를 인스턴스변수로 만들거나 final 변수로 만들어야 한다.
                //메소드 안에서 final 변수를 쓰는 거의 유일한 이유다.
                final LinearLayout linear = (LinearLayout)View.inflate(
                        LoginActivity.this, R.layout.login, null);
                //디자인 한 뷰를 출력하는 대화상자를 생성
                new AlertDialog.Builder(LoginActivity.this)
                        .setTitle("로그인")
                        .setView(linear)
                        .setCancelable(false)
                        .setNegativeButton("취소", null)
                        .setPositiveButton("로그인", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialogInterface, int i) {
                                //뷰의 참조를 가져올 때는 부모 뷰에서 호출해야 한다.
                                //id를 입력하는 EditText는 linear안에 있으므로 linear가 호출해야 한다.
                                EditText id = linear.findViewById(R.id.id);
                                EditText password = (EditText)linear.findViewById(R.id.password);
                                //입력한 내용을 가지고 로그인 시도를 한다.
                                //EdidText나 TextView에서 가져온 문자열은 자료형이 String이 아니므로 toString()을 호출해서 문자열로 변환해야 한다.
                                result.setText("아이디" + id.getText().toString() + " 비밀번호:" + password.getText().toString());
                            }
                        })
                        .show();
            }
        });
    }
}

 

로그인을 클릭하면 대화상자 형태로 사진과 같은 창이 뜬다.

 

 

 

** EventHandling

=> Event : 시스템 또는 사용자가 발생시키는 사건

시스템이 발생시키는 사건은 Notification이라고 별도로 부르기도 한다.

시스템이 발생시키는 사건은 사용자에게 주는 알림의 성격이 강하기 때문에 별도로 부르기도 한다.

 

=> EventHandler : Event가 발생하면 호출되는 객체 또는 함수

 

=> Event 처리 방식

1. Hierachy Event Model : 클래스에 만들어져 있는 메소드를 재정의 하는 구조

=> 상속받은 클래스에서만 사용 가능

=> 이 형태의 이벤츠 처리 메소드는 이벤트가 발생한 객체를 매개변수로 갖지 않는다. 이 메소드가 구현된 클래스의 객체가 이벤트가 발생한 곳이므로 this 이면 이벤트가 발생한 객체이다.

=> 이벤트에 대한 정보를 가지고 있는 객체만 매개변수로 만들어진다.

 

2. Delegation Model : 이벤트를 처리할 객체나 함수를 지정하는 구조

=> 상속과 상관없이 자신이 처리할 수 도 있고 다른 객체에게 위임할 수도 있다.

=> 이렇게 이벤트 처리를 위임받은 객체를 Listener라고 한다.

=> 이 경우의 메소드들은 첫번째 매개변수를 이용하면 이벤트가 발생한 객체를 알 수 있다.

 

3. VC# 이나 MFC, Java의 Swing, Java F/X 그리고 iOS, MacOS X 등의 모든 GUI 프로그래밍에서는 모두 동일

첫 번째 매개변수가 이벤트가 발생한 객체냐 아니면 이벤트가 발생한 객체에 대한 벙보를 가진 객체냐의 차이이다.

 

** Heirachy Event Model

=> 상위클래스가 가진 이벤트 처리 메소드를 재정의 하는 방식

=> View 와 Activity 클래스에는 기본적인 이벤트 처리를 위한 메소드가 내장되어 있다.

Boolean onTouchEvent(MotionEvent event) : 터치했을 때 호출되는 메소드

Boolean keyDown(int keyCode, KeyEvent event) : 키보드를 눌렀을 때

Boolean keyUp(int keyCode, KeyEvent event) : 키보드에서 뗏을 때

Boolean keyLongPress(int keyCode, KeyEvent event) : 길게 눌렀을 때

Void onBackPressed() : back 버튼 눌렀을 때

boolean inTrackballEvent(MotionEvent event) : 트랙볼 이벤트

 

=> boolean을 리턴하는 메소드들은 이벤트가 발생하면 시스템이 무엇인가를 수행하는 이벤트

리턴하는 값이 true 이면 시스템이 가진 처리를 하는 것이고 false를 리턴하면 하지 않는 것이다.