【Android】 DialogFragment의 배경을 투과하려고 빠진 이야기

이 기사의 내용



DialogFragment의 배경을 투과하려고하면 빠졌기 때문에, 조사한 것의 정리

・dialog.window().setBackgroundDrawableResource()로 투과할 수 있다
· onCreateDialog ()에서는 dialog가 null가됩니다.
· DialogFragment와 lifecycle의 이야기

하고 싶은 일



dialogFragment로 나타나는 여백의 배경을 투명하게 하고 싶다.
Before → After


시도한 것



일단 stack overflow를 검색하면 딱 맞는 사람이있었습니다.
dialog의 "setBackgroundDrawable()"메소드로 투명 배경을 지정하면 좋다. 간단하게.

Answer : Add this code.
dialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent)


바로 시도해 실행해 본다.

HogeDialogFragment.kt
class HogeDialogFragmnet: DialogFragment() {
    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        //背景を透過する処理
        dialog!!.window!!.setBackgroundDrawableResource(android.R.color.transparent)

        val builder = AlertDialog.Builder(activity)
        //レイアウトの処理は割愛
        return builder.create()
    }
}

좋지 않았습니다.
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.kabos.sample, PID: 2681
         java.lang.NullPointerException

DialogFragment의 소스 코드를 확인해보십시오.



dialog 인스턴스가 null이되어 오류가 발생했습니다.
onCreateDialog에서 얻으려고 시도하는 것이 어색했을 수있는 가설이 떠오르기 때문에
DialogFragment의 소스 코드를 확인해 보았습니다.

DialogFragment.java
public class DialogFragment extends Fragment
        implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener {

    //③getDialog()でメンバー変数のDialogインスタンスを取得する
    @Nullable
    public Dialog getDialog() {
        return mDialog;
    }

    //②DialogインスタンスはonGetLayoutInflater()の中で、onCreateDialog()から取得している
    @Override
    @NonNull
    public LayoutInflater onGetLayoutInflater(@Nullable Bundle savedInstanceState) {
        LayoutInflater layoutInflater = super.onGetLayoutInflater(savedInstanceState);
        if (!mShowsDialog || mCreatingDialog) {
            return layoutInflater;
        }

        try {
            mCreatingDialog = true;
            mDialog = onCreateDialog(savedInstanceState);//←ココ
            setupDialog(mDialog, mStyle);
        } finally {
            mCreatingDialog = false;
        }

        return layoutInflater.cloneInContext(requireDialog().getContext());
    }

    //①onCreateDialogで初めてDialogがインスタンス化される
    @MainThread
    @NonNull
    public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
        return new Dialog(requireContext(), getTheme());
    }
}

확인해 보니 dialog가 인스턴스화되는 것은 onCreateDialog()의 타이밍이었습니다.
자신의 최초의 코드에서는 onCreateDialog() 안에서 dialog를 참조하고 있었으므로, null가 된 것 같습니다.
따라서 onCreateDialog() 이후의 타이밍인 다음 타이밍에서 호출해야 합니다.
· onCreateView ()
· onStart ()

또한 DialogFragment는 fragment를 상속하므로 Fragment와 비슷한 라이프 사이클입니다.
· onCreate()/onCreateDialog()
· onCreateView ()
· onStart ()
· onResume()

다음과 같이 대화에 액세스하는 타이밍을 변경하면 원래의 목적대로 배경이 투명합니다.

HogeDialogFragment.kt
class HogeDialogFragmnet: DialogFragment() {
    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        //レイアウトの処理は割愛
    }

    override fun onStart() {
        super.onStart()
        //dialogはonCreateDialogでインスタンス化されたので、アクセスできる
        dialog!!.window!!.setBackgroundDrawableResource(android.R.color.transparent)
    }
}

요약



・dialog.window().setBackgroundDrawableResource()로 dialog의 배경을 투과할 수 있다
·dialog는 onCreateDialog()로 인스턴스화되므로, 그 이후에 액세스한다

라이프사이클에 대해 모호한 이해가 되었기 때문에 라이프사이클에 대해 배우는 좋은 기회가 되었습니다.

좋은 웹페이지 즐겨찾기