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