Skip to content

Instantly share code, notes, and snippets.

@ildar2
Created September 14, 2021 10:58
Show Gist options
  • Save ildar2/3483bde7641b9fd07342bd315039bea8 to your computer and use it in GitHub Desktop.
Save ildar2/3483bde7641b9fd07342bd315039bea8 to your computer and use it in GitHub Desktop.
Модалка с dsl-билдером
/**
* Стандартное диалоговое окно по дизайну
*
* на нём есть:
* - иконка success
* - заголовок
* - описание
* - ссылка на сайт
* - кнопка Закрыть, либо Вернуться на главную, либо еще куда-то
* в зависимости от [ModalAction]
*
* @see showModal - создание модалки через dsl
*/
class ModalDialog : DialogFragment(R.layout.dialog_modal) {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NORMAL, R.style.TransparentDialogTheme)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val builder = arguments?.getSerializable(EXTRA_BUILDER)?.cast<Builder>()
tv_button.setSafeOnClickListener {
dismiss()
}
builder?.let {
iv_success.show(builder.isSuccess)
tv_header.text = builder.title
tv_description.text = builder.description
tv_description.show(!builder.description.isNullOrBlank())
tv_link.text = builder.linkText
tv_link.show(!builder.linkText.isNullOrBlank())
tv_link.setSafeOnClickListener {
toast(builder.linkUrl)
}
tv_button.text = builder.buttonText
isCancelable = when (builder.action) {
ModalAction.RETURN_TO_MAIN -> false
ModalAction.RETURN_BACK -> false
ModalAction.SHOW_CLAIM_LIST -> false
else -> true
}
tv_button.setSafeOnClickListener {
when (builder.action) {
ModalAction.RETURN_TO_MAIN -> openHomeFragment()
ModalAction.SHOW_CLAIM_LIST -> openClaimListFragment()
ModalAction.RETURN_BACK -> {
fragmentManager?.popBackStack()
dismiss()
}
else -> dismiss()
}
}
}
}
class Builder(
var title: String? = getLocz().static(R.string.common_error),
var description: String? = null,
var linkText: String? = null,
var linkUrl: String? = null,
var isSuccess: Boolean = false,
var buttonText: String? = getLocz().static(R.string.modal_button_close),
var action: ModalAction? = ModalAction.DISMISS
) : Serializable
companion object {
private const val EXTRA_BUILDER = "extra.builder"
fun Fragment.showModal(customize: Builder.() -> Unit) {
openFullscreen(
R.id.modalDialog,
bundleOf(EXTRA_BUILDER to Builder().apply(customize))
)
}
}
private fun openHomeFragment() {
val bundle = bundleOf(MainFragment.PAGE_ARGUMENT to MainFragment.PAGE_HOME)
NavHostFragment.findNavController(this)
.navigate(R.id.mobile_navigation, bundle)
}
private fun openClaimListFragment() {
openFullscreen(
R.id.claimListFragment
)
}
}
enum class ModalAction {
DISMISS, RETURN_TO_MAIN, SHOW_CLAIM_LIST, RETURN_BACK
}
R.layout.dialog_modal:
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="270dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="@drawable/bg_rounded_14dp"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="@+id/iv_success"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="16dp"
android:src="@drawable/ic_success"
android:visibility="gone"
android:importantForAccessibility="no"
tools:visibility="visible" />
<TextView
android:id="@+id/tv_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="16dp"
android:layout_marginBottom="8dp"
android:gravity="center"
android:text="@string/common_error"//ошибка
android:textColor="@color/primaryText"
android:textSize="16sp"
android:textStyle="bold"
tools:visibility="visible" />
<TextView
android:id="@+id/tv_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginBottom="8dp"
android:gravity="center"
android:textColor="@color/grayText"
android:visibility="gone"
tools:text="Истек срок действия ЭЦП"
tools:visibility="visible" />
<TextView
android:id="@+id/tv_link"
style="@style/ButtonText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:background="?selectableItemBackground"
android:gravity="center"
android:visibility="gone"
tools:text="Как пользоваться ЭЦП"
tools:visibility="visible" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="8dp"
android:background="@color/divider" /> //<color name="divider">#29000000</color>
<TextView
android:id="@+id/tv_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_modal_ripple"
android:gravity="center"
android:padding="16dp"
android:text="@string/modal_button_close"//Закрыть
android:textColor="@color/secondaryText"
android:textSize="16sp"
android:textStyle="bold" />
</LinearLayout>
</FrameLayout>
@drawable/bg_rounded_14dp:
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="14dp" />
<solid android:color="@color/white" />
</shape>
@drawable/ic_success:
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="40dp"
android:height="40dp"
android:viewportWidth="40"
android:viewportHeight="40">
<path
android:pathData="M20,21m-13,0a13,13 0,1 1,26 0a13,13 0,1 1,-26 0"
android:fillColor="#ffffff"/>
<path
android:pathData="M20,36.6663C10.795,36.6663 3.3334,29.2047 3.3334,19.9997C3.3334,10.7947 10.795,3.333 20,3.333C29.205,3.333 36.6667,10.7947 36.6667,19.9997C36.6667,29.2047 29.205,36.6663 20,36.6663ZM18.3384,26.6663L30.1217,14.8813L27.765,12.5247L18.3384,21.953L13.6234,17.238L11.2667,19.5947L18.3384,26.6663Z"
android:fillColor="#88DCE6"/>
</vector>
<!-- Для текстовых цветных кнопок со стрелкой --> - можно удалить эту ссылку по идее
<style name="ButtonText" parent="TextRegular">
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_width">wrap_content</item>
<item name="android:paddingTop">8dp</item>
<item name="android:paddingBottom">8dp</item>
<item name="android:paddingStart">16dp</item>
<item name="android:paddingEnd">16dp</item>
<item name="android:background">?attr/selectableItemBackground</item>
<item name="android:textColor">@drawable/selector_link_text</item>
<item name="drawableEndCompat">@drawable/ic_navigate</item>
<item name="drawableTint">@color/link_clickable</item>
<item name="android:drawablePadding">10dp</item>
</style>
@drawable/bg_modal_ripple:
<?xml version="1.0" encoding="utf-8"?>
<ripple
xmlns:android="http://schemas.android.com/apk/res/android"
android:color="@color/ripple">
<item android:id="@android:id/mask">
<shape android:shape="rectangle">
<solid android:color="#000000" />
<corners
android:bottomLeftRadius="@dimen/default_corner_radius" //15dp
android:bottomRightRadius="@dimen/default_corner_radius" />
</shape>
</item>
<item>
<shape>
<corners
android:bottomLeftRadius="@dimen/default_corner_radius"
android:bottomRightRadius="@dimen/default_corner_radius" />
</shape>
</item>
</ripple>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment