Dynamic Dialogs
Display improved dialogs and dialog fragments on Android.
- Pranav Pandey
- Android | Library
- 15 Nov, 2019
- 4 Min read
A simple library to display dialogs and dialog fragments on Android 4.0 (API 14) and above devices.
ToC
Table of Contents
Background
I have various dialogs in my apps available on Google Play and sometimes it is required to have a completely custom layout like for color picker dialog. I was using AppCompat (or AndroidX) dialog before but it doesn’t have support for scrolling indicators for custom layouts.
Android 5.0 (API 21) does this by default but my apps support Android 4.1 (API 16) so, I had filed an issue with no success as they will not backport this feature.
As a result, I have decided to make a custom one and extracted latest code from the AppCompat
library based on MDC-Android and added the scroll indicators implementation for custom layouts also. It is working pretty good in my apps and has various helper methods to do it in a better way. Please read below to know more about its usage.
Usage
This is a library to display dialog and dialog fragments with ease. It has some improvements over appcompat-v7
(or AndroidX/MDC-Android) dialogs and share the same behavior and methods which can be used with any other framework or library. This library is fully commented so I am highlighting some of the features below.
Please follow and keep exploring the GitHub repository to find out more hidden features.
Setup
First add alertDialogStyle
in the base application theme to make dynamic-dialogs
working.
<!-- Base application theme. -->
<style name="AppTheme" parent="...">
<!-- Customize your theme here. -->
...
<!-- Add dynamic dialogs style in the base app theme. -->
<item name="alertDialogStyle">@style/DynamicDialog</item>
</style>
DynamicDialog
It is almost identical to the AppCompatDialog
but provides scroll indicators at top and bottom for the custom dialogs also. So, if you are using any scrollable view in your custom dialog like NestedScrollView
or RecyclerView
, it can be set as root view
and the scroll indicators will be added automatically if the view can be scrolled.
new DynamicDialog.Builder(context)
// Set dialog title.
.setTitle(...)
...
// Set a custom view.
.setView(int layoutResId)
// OR
setView(View view)
// Set view root to automatically add scroll dividers.
.setViewRoot(int viewRootId)
// OR
.setViewRoot(View viewRoot)
// Show the dialog.
.show();
DynamicDialogFragment
Base dialog fragment to provide all the functionality of DynamicDialog
inside a fragment. It can be extended to customize it further by overriding the supported methods.
public CustomDialogFragment extends DynamicDialogFragment {
...
/**
* Override this method to customize the dynamic dialog builder before creating the dialog.
*
* @param dialogBuilder The current builder to be customized.
* @param savedInstanceState The saved state of the fragment to restore it later.
*
* @return The customized dynamic dialog builder.
*/
@Override
protected @NonNull DynamicDialog.Builder onCustomiseBuilder(
@NonNull DynamicDialog.Builder dialogBuilder, @Nullable Bundle savedInstanceState) {
// TODO: Customise the dialog here.
...
return dialogBuilder;
}
/**
* Override this method to customize the dynamic dialog before attaching it with
* this fragment.
*
* @param alertDialog The current dialog to be customized.
* @param savedInstanceState The saved state of the fragment to restore it later.
*
* @return The customized dynamic dialog.
*/
protected @NonNull DynamicDialog onCustomiseDialog(@NonNull DynamicDialog alertDialog,
@Nullable Bundle savedInstanceState) {
// TODO: Customise the dialog builder here.
...
return alertDialog;
}
...
}
Show dialog
Show the DynamicDialogFragment
by using showDialog(fragmentActivity)
method.
For better understanding, please check AboutDialogFragment in the
sample
project.
Dialog state
It will automatically maintain its state on configuration changes (like device rotation, etc.) by calling setRetainInstance(true)
in onCreate()
method. If you don’t want to use this feature (generally, if you are displaying it in onResume()
method) then, call setAutoDismiss(true)
to dismiss it in onPause()
method.
DynamicDialogFragment.newInstance().
...
// Dismiss dialog fragment on configuration changes.
.setAutoDismiss(true)
// Show the dialog fragment.
.showDialog(fragmentActivity);
Dialog builder
To show quick DynamicDialogFragment
, you can use its setBuilder(DynamicDialog.Builder)
method and pass DynamicDialog.Builder
with all the customizations. It will automatically wrap it in a DialogFragment
and use showDialog(fragmentActivity)
method to display it.
DynamicDialogFragment.newInstance().setBuilder(
new DynamicDialog.Builder(context)
// Set dialog title.
.setTitle(...)
// Set dialog message.
.setMessage(...)
// Set negative button with a click listener.
.setNegativeButton(..., clickListener))
// Show the dialog fragment.
.showDialog(fragmentActivity);
Dialog callbacks
As DialogFragment
has required some extra work to get the event callbacks, it already has all the listeners of DynamicDialog.Builder
built-in so that there is no extra effort is required.
DynamicDialogFragment.newInstance()
...
// Callback when this dialog fragment is displayed.
.setOnShowListener(onShowListener)
// Callback when this dialog fragment has been dismissed.
.setOnDismissListener(onDismissListener)
// Callback when this dialog fragment has been canceled.
.setOnCancelListener(onCancelListener)
// Callback when a key is pressed in this dialog fragment.
.setOnKeyListener(onKeyListener)
// Show the dialog fragment.
.showDialog(fragmentActivity);
For better understanding, please check CustomDialogFragment in the
sample
project.
Dependency
It depends on the dynamic-utils to perform various internal operations. So, its functions can also be used to perform other useful operations.
Installation
Please follow the GitHub repository for the installation guide. I hope it will help you in your projects and please ask questions or share your feedback in the comments section to make it better.