코코딩딩

[안드로이드]Dialog 만들기 (DialogFragment, Custom Dialog) 본문

코딩/Android

[안드로이드]Dialog 만들기 (DialogFragment, Custom Dialog)

겟츄 2022. 3. 30. 14:58

안드로이드에서 Dialog (대화상자)를 구현하는 법을 정리하고자 한다.

 

처음 검색할 때는 custom dialog 에 대해서 알아보기 위해서 예제를 찾았는데 Dialog클래스를 직접 사용한 예제였다.

다른 방법이 없나 검색을 해본 결과 android developers에 잘나와 있었다. 이곳에서 말하길 Dialog 클래스는 dialog의

기본 클래스 이지만 직접 인스턴스화 하지말고 AlertDialog를 사용할 것을 권장하고 있다. 또한 DialogFragment를

같이 사용해 구현하는 방법을 알려주고 있다.


DialogFregment 구현

Fragment

package com.example.testdialogfragment;

import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;

import androidx.fragment.app.DialogFragment;

public class StartGameDialogFragment extends DialogFragment {
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setMessage("StartGame")
                .setPositiveButton(R.string.start, new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                    }
                })
                .setNegativeButton("cancel", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                    }
                })
                .setNeutralButton("중간버튼?", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {

                    }
                });
        return builder.create();
    }
}

MainActivity

package com.example.testdialogfragment;

import androidx.appcompat.app.AppCompatActivity;

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

public class MainActivity extends AppCompatActivity {
    private Button button;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        button = (Button) findViewById(R.id.btn_dialog);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                openDialog();
            }
        });
    }
    public void openDialog(){
        StartGameDialogFragment startGameDialogFragment = new StartGameDialogFragment();
        startGameDialogFragment.show(getSupportFragmentManager(),"dialog");
    }
}

activity_main.xml

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

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="다이얼로그 테스트"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintHorizontal_bias="0.514"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.351" />

    <Button
        android:id="@+id/btn_dialog"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="72dp"
        android:text="dialog"
        app:layout_constraintEnd_toEndOf="@+id/textView"
        app:layout_constraintStart_toStartOf="@+id/textView"
        app:layout_constraintTop_toBottomOf="@+id/textView" />

</androidx.constraintlayout.widget.ConstraintLayout>

 

실행화면

버튼누른 후 동작 화면

 

개발자 문서에 있는 것과 크게 다르지 않은 내용이지만 진행과정을 정리해 보았다.

fragment 코드에 setPositiveButton 에서 R.string.start 이 부분이 처음에는 동작하지 않아 뭔지 검색을 해보니

values폴더에 strings.xml에 string들을 name으로 불러올 수 있게 되어있었다.

<resources>
    <string name="app_name">testDialogFragment</string>
    <string name="start">ststart</string>
</resources>

위와 같이 start를 불러오면 ststart 라는 문자열이 나온다. 처음에 동작하지 않아 직접 "cancel"로 직접 string을 입력해도 된다. 


Custom Dialog 구현

CustomDialogFragment

package com.example.testdialogfragment;

import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.EditText;

import androidx.fragment.app.DialogFragment;

public class CustomDialogFragment extends DialogFragment {

    CustomDialogListener listener;

    private EditText editTextUsername;
    private EditText editTextPssword;


    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {


        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        LayoutInflater inflater = requireActivity().getLayoutInflater();
        View view = inflater.inflate(R.layout.layout_dialog, null);

        editTextUsername = view.findViewById(R.id.layout_et_username);
        editTextPssword = view.findViewById(R.id.layout_et_password);

        builder.setView(view)
                .setPositiveButton("확인", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        //확인로직
                        String username = editTextUsername.getText().toString();
                        String password = editTextPssword.getText().toString();
                        listener.onDialogPositiveClick(username,password);
                    }
                })
                .setNegativeButton("취소", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        //취소로직
                        CustomDialogFragment.this.getDialog().cancel();
                        listener.onDialogNegativeClick(CustomDialogFragment.this);
                    }
                });
        return builder.create();
    }

    public interface CustomDialogListener {
        void onDialogPositiveClick(String username, String pasword);
        void onDialogNegativeClick(DialogFragment dialog);
    }


    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        try {
            listener = (CustomDialogListener) context;
        } catch (ClassCastException e) {
            throw new ClassCastException(this.toString()
                    + " must implement CustomDialogListener");
        }
    }
}

MainActivity

package com.example.testdialogfragment;

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

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

import org.w3c.dom.Text;

public class MainActivity extends AppCompatActivity implements CustomDialogFragment.CustomDialogListener{
    private Button button;
    private Button customButton;

    TextView textViewUsername;
    TextView textViewPassword;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //textview 값가져오기
        textViewUsername = (TextView)findViewById(R.id.tv_username);
        textViewPassword = (TextView)findViewById(R.id.tv_password);


        // StartGameDialogFragment 버튼
        button = (Button) findViewById(R.id.btn_dialog);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                openDialog();
            }
        });
        // CustomDialogFragment 버튼
        customButton = (Button) findViewById(R.id.btn_custom);
        customButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                openCustom();
            }
        });


    }
    public void openDialog(){
        StartGameDialogFragment startGameDialogFragment = new StartGameDialogFragment();
        startGameDialogFragment.show(getSupportFragmentManager(),"dialog");
    }
    public void openCustom(){
        DialogFragment dialog = new CustomDialogFragment();
        dialog.show(getSupportFragmentManager(),"customDialog");
    }


    @Override
    public void onDialogPositiveClick(String username, String password) {
        textViewUsername.setText(username);
        textViewPassword.setText(password);
    }

    @Override
    public void onDialogNegativeClick(DialogFragment dialog) {

    }
}

 기존에서 추가된 activity_main.xml

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

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="다이얼로그 테스트"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintHorizontal_bias="0.514"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.351" />

    <Button
        android:id="@+id/btn_dialog"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="72dp"
        android:text="dialog"
        app:layout_constraintEnd_toEndOf="@+id/textView"
        app:layout_constraintStart_toStartOf="@+id/textView"
        app:layout_constraintTop_toBottomOf="@+id/textView" />

    <Button
        android:id="@+id/btn_custom"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="32dp"
        android:text="custom"
        app:layout_constraintEnd_toEndOf="@+id/btn_dialog"
        app:layout_constraintStart_toStartOf="@+id/btn_dialog"
        app:layout_constraintTop_toBottomOf="@+id/btn_dialog" />

    <TextView
        android:id="@+id/tv_username"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="24dp"
        android:text="dialog 아이디 나오는곳"
        android:textSize="24sp"
        app:layout_constraintEnd_toEndOf="@+id/btn_custom"
        app:layout_constraintStart_toStartOf="@+id/btn_custom"
        app:layout_constraintTop_toBottomOf="@+id/btn_custom" />

    <TextView
        android:id="@+id/tv_password"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:text="dialog 비밀번호 나오는곳"
        android:textSize="24sp"
        app:layout_constraintEnd_toEndOf="@+id/tv_username"
        app:layout_constraintStart_toStartOf="@+id/tv_username"
        app:layout_constraintTop_toBottomOf="@+id/tv_username" />

</androidx.constraintlayout.widget.ConstraintLayout>

CustomDialog 시작 화면

 

 

CustomDialog custom버튼 클릭 화면

 

CustomDialog에서 데이터입력 후 확인버튼을 누른 후 변경된 main 화면

'코딩 > Android' 카테고리의 다른 글

[안드로이드] ViewModel , LiveData  (0) 2022.04.05
[안드로이드] DataBinding  (0) 2022.03.31