여러 가지 방법으로 커스텀 다이얼로그를 만들 수 있다.

 

그런데 그 중에서 어떤 방법이 제일 효율적이라고 말할 수 있을까?

 

자바라는 언어는 객체지향 언어고, 결합도를 낮추기 위해 노력해야 한다.

 

그때그때 AlertDialog.Builder 객체에 커스텀 레이아웃을 inflate해서 만드는 것이 과연 좋은 것인가?

 

그렇다고 따로 클래스를 만들고 그 안에 setContentView로 레이아웃과 메서드를 다 새로 만드는 일은

 

상당히 비효율적일 뿐더러, 다이얼로그 하나하나 전부 새로 만들어야 하지 않는가.

 

그렇다고 CustomDialog 클래스를 만들고 setTitle, setMessage 등 메서드를 만들자니

 

그것 또한 또 하나의 틀을 만들어내는 것 같고, 따지고 보면 AlertDialog랑 별다를 게 없지 않은가.

 

제목 = cd_title

내용 = cd_msg

positive button = cd_pb

종료 버튼 = cd_close

 

로 정해서 최소한의 도구만 만들어 놓고, CustomDialog.Builder를 이용해 만드는 방식으로 하자.

 

편리하게 문법을. 

 

흠...

 

package com.example.myapp;

import android.content.Context;
import android.graphics.Bitmap;
import android.view.ActionMode;
import android.widget.TextView;

import androidx.annotation.LayoutRes;
import androidx.annotation.StringRes;
import androidx.appcompat.app.AppCompatDialog;

public class CustomDialog2 extends AppCompatDialog {
        static Context context;
        static int id;
        static TextView cd_title;
        static TextView cd_contents;
        static CustomDialog2 dialog;

        public CustomDialog2(Context context) {
            super(context);
        }

        static class Builder{

//            String title;

            Builder(Context context1, @LayoutRes int id1){
                context = context1;
                id = id1;
            }

            public CustomDialog2 setTitle(@StringRes int id){
                cd_title = dialog.findViewById(R.id.cd_title);
                cd_title.setText(id);
                //this.title = context.getString(id);
                return dialog;
            }
            public Builder setTitle(String str){
                cd_title = dialog.findViewById(R.id.cd_title);
                cd_title.setText(str);
                return this;
            }
            public CustomDialog2 setContents(@StringRes int id){
                cd_contents = dialog.findViewById(R.id.cd_contents);
                cd_contents.setText(id);
                return dialog;
            }
            public Builder setContents(String str){
                cd_contents = dialog.findViewById(R.id.cd_contents);
                cd_contents.setText(str);
                return this;
            }


            public Builder create(){
                dialog = new CustomDialog2(context);
                dialog.setContentView(id);
                return this;
            }

            public Builder show() {
                dialog.show();
                return this;
            }
        }
}


CustomDialog2.Builder builder = new CustomDialog2.Builder(적절한 컨텍스트, R.layout.quest_generate_dialog);
                builder.create().setTitle("하").setContents("뭐야 대체 왜 ???").show();

여차저차 만들어졌다. 그러나...

이건 결국 다른 커스텀 다디얼로그와 다를 게 없지 않은가... 하아.

 

일단, 유의할 점.

builder 내부 클래스 이름은 중요하지 않다. 

builder.create().setTitle()... 이렇게 연속적으로 연결할 수 있는 이유는,

Builder 내부 클래스에서 메서드들의 반환 타입을 Builder로 하고 return에 this로 자기 자신을 반환하게 해서

연속적으로(체인) 사용할 수 있도록. 다만, create()에서 setContentView로 바탕을 깔기 때문에

setTitle과 setContents는 creat() 다음에야 올 수 있다.

그리고 setTitle이나 setContents의 반환값을 CustomDialog2로 하면 show가 정상적으로 작동하는데,

이는 재정의한 Builder를 반환하는 show()가 아닌, AppCompatDialog를 상속받은 그 안에 있는

show()가 작동한 것이다. 유의! 빌더 쓸 거면 전부 빌더로 통일하면 된다.

 

findViewById는 setContentView로 바탕이 깔려있어야 사용 가능하고,

이미 바탕이 있는 상태면 Inflater로 새롭게 메모리에 올려야 한다.

그리고 이 경우 findViewById 앞에 (뷰)를 해줘야 한다... 리사이클러 뷰 사용할 때처럼.

 

hello-bryan.tistory.com/132

onlyfor-me-blog.tistory.com/145

shwjdqls.github.io/android-custom-dialog/

참고하자.

 

이건 빌더 패턴 만들 때 알아본 것.

johngrib.github.io/wiki/builder-pattern/