Detailed explanation and use of DialogFragment of Android Dialog

1. Introduction

        In the Android development process, there are often pop-up window services. In normal pop-up window services, Dialog is commonly used. The principle of Dialog is also to add views to Dialog. Dialog itself is an independent window. Like Activity, it has its own window management. If simply using Dialog is inconvenient to manage, Google provides a DialogFragment pop-up window later.

2. Introduction to DialogFragment

        Seeing DialogFragment, you can see from the words that it is a combination of Dialog and Fragment, but in DialogFragment, DialogFragment is actually a fragment that holds a Dialog inside, which is convenient for developers to manage. Fragment is actually a View in fragment management, and the final view display is done through dialog.

        class NamelessClass_1 implements Observer<LifecycleOwner> {
            NamelessClass_1() {
            }

            @SuppressLint({"SyntheticAccessor"})
            public void onChanged(LifecycleOwner lifecycleOwner) {
                if (lifecycleOwner != null && DialogFragment.this.mShowsDialog) {
                    View view = DialogFragment.this.requireView();
                    if (view.getParent() != null) {
                        throw new IllegalStateException("DialogFragment can not be attached to a container view");
                    }

                    if (DialogFragment.this.mDialog != null) {
                        if (FragmentManager.isLoggingEnabled(3)) {
                            Log.d("FragmentManager", "DialogFragment " + this + " setting the content view on " + DialogFragment.this.mDialog);
                        }

                        DialogFragment.this.mDialog.setContentView(view);
                    }
                }

            }
        }

 Similarly, rich methods are also provided in the class

1. Display

    public void show(@NonNull FragmentManager manager, @Nullable String tag) {
        this.mDismissed = false;
        this.mShownByMe = true;
        FragmentTransaction ft = manager.beginTransaction();
        ft.add(this, tag);
        ft.commit();
    }

2. Disappear

    public void dismiss() {
        this.dismissInternal(false, false);
    }

3. Get the dialog

    @Nullable
    public Dialog getDialog() {
        return this.mDialog;
    }

4. Initialize internal resources

  @Nullable
    View onFindViewById(int id) {
        return this.mDialog != null ? this.mDialog.findViewById(id) : null;
    }

5.dialog creation


    @MainThread
    @NonNull
    public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
        if (FragmentManager.isLoggingEnabled(3)) {
            Log.d("FragmentManager", "onCreateDialog called for DialogFragment " + this);
        }

        return new Dialog(this.requireContext(), this.getTheme());
    }

Three, actual combat

Through the above introduction, we are probably familiar with the general working method of DialogFragment. If you want to study it carefully, you can check the source code.

In actual combat use

1. Inheritance rewriting

base class:

abstract class BaseBindDialogFragment<V : ViewDataBinding> : DialogFragment() {

    val TAG=javaClass::class.java.name
    lateinit var bind: V

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {

        bind = DataBindingUtil.inflate(inflater, getLayoutId(), container, false)

        initView(bind.root)
        return bind.root
    }


    override fun onStart() {
        super.onStart()
        initConfig(dialog)
    }

    @LayoutRes
    abstract fun getLayoutId(): Int

    abstract fun initView(view: View)

    abstract fun initConfig(dialog:Dialog?)


}
class MyDialogFrgament : BaseBindDialogFragment<DialogFragmentbind>() {

    override fun getLayoutId(): Int {
        return R.layout.layout_dialog_view
    }

    override fun initView(view: View) {

        bind.textInfo.text="我在测试"
    }

    override fun onResume() {
        super.onResume()
        MyLog.log(TAG,"onResume")
    }

    override fun onPause() {
        super.onPause()
        MyLog.log(TAG,"onPause")
    }

    override fun onStop() {
        super.onStop()
        MyLog.log(TAG,"onStop")
    }

    override fun initConfig(dialog: Dialog?) {
        dialog?.let {

        }
    }
}

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data class="DialogFragmentbind"></data>

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">


        <TextView
            android:id="@+id/text_info"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
    </FrameLayout>
</layout>

implement:

    private fun dialogExport() {
        dialog = MyDialogFrgament()
        dialog.show(supportFragmentManager, "dialogExport")
    }

Notice:

During the development process, many novices will report errors:

DialogFragment can not be attached to a container view

 

The reason for this error is that the parent of the view is not null, and after disappearing, it is displayed again. At this time, it will check whether the parent is null.

At the heart of this problem is the use of the syntax

solve:

1. Get the parent of the view, and remove yourself

2. Create a new object every time it is displayed

Guess you like

Origin blog.csdn.net/qq36246172/article/details/130558593