/lightbulb-dialogs

Say goodbye to the hassle of creating dialogs in your Android app with Lightbulb dialogs library. Designed to provide you with maximum flexibility, our library offers a wide range of customizable options that help you create the perfect dialog for your needs.

Primary LanguageKotlinApache License 2.0Apache-2.0

💡 Lightbulb-Dialogs

Our Android library provides a flexible and user-friendly approach for creating dialog windows. With a wide range of customizable attributes, users can easily design dynamic and visually appealing dialogue windows for their applications. Our library includes pre-built templates for common dialog types, such as alerts, confirmations, pickers, and input prompts, as well as the ability to create custom dialogues using a variety of styling options. Overall, this library is an essential tool that helps you to create engaging and functional applications with little effort.


📋 Features

  • Configuration change state handling.
  • Different dialog layout types support: Regular, Fullscreen, BottomSheet.
  • Different show/hide animations support.
  • Width/height Constraints support.
  • Custom dialog - Gives you the ability to implement your unique dialog if the existing ones does not meet your requirements.
  • Adapter picker dialog - Gives you the ability to implement picker dialog using recycler adapter without the need to write the heavy selection logic... It's already there :)
  • Predefined implementations
    • Alert dialog - Dialog that shows a title, message and set of buttons to interact with the user.
    • Loading dialog - Provides a user-friendly way to indicate to the user that the application is working on a task and needs a moment to complete the action.
    • Picker dialogs - Set of dialogs that allow the user to choose between different values.
      • Chips picker dialog - Picker dialog showing available options in Material chips.
      • Color picker dialog - Gives you the ability to pick colors from predefined set.
      • Icon picker dialog - Gives you the ability to pick icons from predefined set.
      • Date range picker dialog - Gives you the ability to pick date range.
      • Date&Time picker dialog - Gives you the ability to pick date with time.
      • Time picker dialog - Gives you the ability to pick time.
      • Month picker dialog - Gives you the ability to pick month of year.

🎨 Screenshots

Image

Latest releases 🛠

Setup

1. Add Jitpack repository to your project

repositories {
    ...
    maven {
        url 'https://jitpack.io'
    }
}

2. Provide the gradle dependency

implementation 'com.github.rooneyandshadows:lightbulb-dialogs:2.0.3'

3. General usage

class DemoFragment : Fragment() {
    private lateinit var myDialog: MyDialog

    companion object {
        private const val DIALOG_TAG = "MY_DIALOG_TAG"
        private const val DIALOG_STATE_TAG = "MY_DIALOG_STATE_TAG"
    }

    @Override
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        var dialogSavedState: Bundle? = null
        savedInstanceState?.apply {
            dialogSavedState = BundleUtils.getParcelable(DIALOG_STATE_TAG, this, Bundle::class.java)
        }
        createDialog(dialogSavedState)
    }

    @Override
    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        val dialogState = myDialog.saveDialogState()
        BundleUtils.putParcelable(DIALOG_STATE_TAG, outState, dialogState)
    }

    private fun createDialog(dialogSavedState: Bundle?) {
        myDialog = MyDialogBuilder(this, childFragmentManager, DIALOG_TAG).apply {
            //Setup the dialog
        }.buildDialog()
    }
}

AdapterPickerDialog example

Note

Create your adapter

class DemoSingleSelectionDialog : AdapterPickerDialog<DemoModel>() {
    override val adapter: DialogPickerAdapter<DemoModel>
        get() = super.adapter as DialogPickerRadioButtonAdapter<DemoModel>
    override val adapterCreator: AdapterCreator<DemoModel>
        get() = object : AdapterCreator<DemoModel> {
            @Override
            override fun createAdapter(): DialogPickerRadioButtonAdapter<DemoModel> {
                return object : DialogPickerRadioButtonAdapter<DemoModel>() {
                    @Override
                    override fun getItemIcon(context: Context, item: DemoModel): Drawable {
                        return AppIconUtils.getIconWithAttributeColor(
                            context,
                            item.icon,
                            R.attr.colorOnSurface,
                            R.dimen.ICON_SIZE_RECYCLER_ITEM
                        )
                    }

                    @Override
                    override fun getItemIconBackground(
                        context: Context,
                        item: DemoModel
                    ): Drawable {
                        return DrawableUtils.getRoundedCornersDrawable(
                            item.iconBackgroundColor.color,
                            ResourceUtils.dpToPx(100)
                        )
                    }
                }
            }
        }

    companion object {
        fun newInstance(): DemoSingleSelectionDialog {
            return DemoSingleSelectionDialog()
        }
    }
}

Note

Create your adapter picker dialog

adapterPickerDialog = AdapterPickerDialogBuilder(
    this,
    childFragmentManager,
    DIALOG_TAG,
    object : AdapterPickerDialogInitializer<DemoSingleSelectionDialog> {
        @Override
        override fun initialize(): DemoSingleSelectionDialog {
            return DemoSingleSelectionDialog.newInstance()
        }
    }
).apply {
    withInitialDialogState(dialogSavedState)
    withTitle(title)
    withMessage(message)
    withPositiveButton(DialogButtonConfiguration(positiveText), onPositiveButtonClick)
    withNegativeButton(DialogButtonConfiguration(negativeText), onNegativeButtonClick)
    withSelectionCallback(selectionCallback)
}.buildDialog()

AlertDialog example

alertDialog = AlertDialogBuilder(this, childFragmentManager, DIALOG_TAG).apply {
    withInitialDialogState(dialogSavedState)
    withTitle(title)
    withMessage(message)
    withPositiveButton(DialogButtonConfiguration(positiveButtonText), positiveButtonClickListener)
    withNegativeButton(DialogButtonConfiguration(negativeButtonText), negativeButtonClickListener)
}.buildDialog()

LoadingDialog example

loadingDialog = LoadingDialogBuilder(this, childFragmentManager, DIALOG_TAG).apply {
    val onShowListener = object : DialogShowListener {
        override fun doOnShow(dialogFragment: BaseDialogFragment) {
            requireView().postDelayed({
                dialogFragment.dismiss()
                val toastMessage = ResourceUtils.getPhrase(ctx, R.string.demo_action_completed_text)
                InteractionUtils.showMessage(ctx, toastMessage)
            }, 3000)
        }
    }
    withInitialDialogState(dialogSavedState)
    withTitle(title)
    withMessage(message)
    withOnShowListener(onShowListener)
}.buildDialog()

ChipsPickerDialog example

chipsPickerDialog = ChipsPickerDialogBuilder(this, childFragmentManager, DIALOG_TAG).apply {
    withInitialDialogState(dialogSavedState)
    withTitle(title)
    withMessage(message)
    withPositiveButton(DialogButtonConfiguration(positiveButtonText), positiveButtonClickListener)
    withNegativeButton(DialogButtonConfiguration(negativeButtonText), negativeButtonClickListener)
    withSelectionCallback(onSelectionChanged)
}.buildDialog()

ColorPickerDialog example

colorPickerDialog = ColorPickerDialogBuilder(this, childFragmentManager, DIALOG_TAG).apply {
    withInitialDialogState(dialogSavedState)
    withTitle(title)
    withMessage(message)
    withPositiveButton(DialogButtonConfiguration(positiveButtonText), positiveButtonClickListener)
    withNegativeButton(DialogButtonConfiguration(negativeButtonText), negativeButtonClickListener)
    withSelectionCallback(onSelectionChanged)
}.buildDialog()

IconPickerDialog example

iconPickerDialog = IconPickerDialogBuilder(this, childFragmentManager, DIALOG_TAG).apply {
    withInitialDialogState(dialogSavedState)
    withTitle(title)
    withMessage(message)
    withPositiveButton(DialogButtonConfiguration(positiveButtonText), positiveButtonClickListener)
    withNegativeButton(DialogButtonConfiguration(negativeButtonText), negativeButtonClickListener)
    withSelectionCallback(onSelectionChanged)
}.buildDialog()

DateRangePickerDialog example

dateRangePickerDialog = DateRangePickerDialogBuilder(this, childFragmentManager, DIALOG_TAG).apply {
    withInitialDialogState(dialogSavedState)
    withPositiveButton(DialogButtonConfiguration(positiveButtonText), positiveButtonClickListener)
    withNegativeButton(DialogButtonConfiguration(negativeButtonText), negativeButtonClickListener)
    withOnDateSelectedEvent(onSelectionChanged)
}.buildDialog()

DateTimePickerDialog example

dateTimePickerDialog = DateTimePickerDialogBuilder(this, childFragmentManager, DIALOG_TAG).apply {
    withInitialDialogState(dialogSavedState)
    withPositiveButton(DialogButtonConfiguration(positiveButtonText), positiveButtonClickListener)
    withNegativeButton(DialogButtonConfiguration(negativeButtonText), negativeButtonClickListener)
    withOnDateSelectedEvent(onSelectionChanged)
}.buildDialog()

TimePickerDialog example

timePickerDialog = TimePickerDialogBuilder(this, childFragmentManager, DIALOG_TAG).apply {
    withInitialDialogState(dialogSavedState)
    withPositiveButton(DialogButtonConfiguration(positiveButtonText), positiveButtonClickListener)
    withNegativeButton(DialogButtonConfiguration(negativeButtonText), negativeButtonClickListener)
    withOnDateSelectedEvent(onSelectionChanged)
}.buildDialog()

MonthPickerDialog example

monthPickerDialog = MonthPickerDialogBuilder(this, childFragmentManager, DIALOG_TAG).apply {
    withInitialDialogState(dialogSavedState)
    withPositiveButton(DialogButtonConfiguration(positiveButtonText), positiveButtonClickListener)
    withNegativeButton(DialogButtonConfiguration(negativeButtonText), negativeButtonClickListener)
    withOnDateSelectedEvent(onSelectionChanged)
}.buildDialog()

More detailed demonstrations you can find in the demo application.