Significantly simplify MagiskDialog layout

The goal of original implementation, wrap view again and again, seems to be use the shadow and customizable round corners from MaterialCardView. But this can be done with use MaterialShapeDrawable which used in MaterialCardView directly. This will significantly simplify the layout and MagiskDialog class.
This commit is contained in:
RikkaW 2020-10-22 16:47:47 +08:00 committed by John Wu
parent c93ada03c7
commit fa3ef8a1c1
3 changed files with 189 additions and 225 deletions

View File

@ -2,25 +2,24 @@ package com.topjohnwu.magisk.view
import android.content.Context
import android.content.DialogInterface
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.content.res.ColorStateList
import android.graphics.drawable.Drawable
import android.graphics.drawable.InsetDrawable
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
import androidx.appcompat.app.AppCompatDialog
import androidx.appcompat.content.res.AppCompatResources
import androidx.core.view.ViewCompat
import androidx.core.view.updatePadding
import androidx.databinding.Bindable
import androidx.databinding.PropertyChangeRegistry
import androidx.databinding.ViewDataBinding
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.color.MaterialColors
import com.google.android.material.shape.MaterialShapeDrawable
import com.topjohnwu.magisk.BR
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.arch.itemBindingOf
@ -47,36 +46,22 @@ class MagiskDialog(
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
super.setContentView(binding.root)
val surfaceColor = MaterialColors.getColor(context, R.attr.colorSurfaceSurfaceVariant, javaClass.canonicalName)
val materialShapeDrawable = MaterialShapeDrawable(context, null, R.attr.alertDialogStyle, R.style.MaterialAlertDialog_MaterialComponents)
materialShapeDrawable.initializeElevationOverlay(context)
materialShapeDrawable.fillColor = ColorStateList.valueOf(surfaceColor)
materialShapeDrawable.elevation = context.resources.getDimension(R.dimen.margin_generic)
materialShapeDrawable.setCornerSize(context.resources.getDimension(R.dimen.l_50))
val inset = context.resources.getDimensionPixelSize(R.dimen.appcompat_dialog_background_inset)
window?.apply {
setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
setLayout(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT
)
}
val paddingTop = binding.root.paddingTop
val paddingBottom = binding.root.paddingBottom
ViewCompat.setOnApplyWindowInsetsListener(binding.root) { view, insets ->
view.updatePadding(
top = paddingTop + insets.systemWindowInsetTop,
bottom = paddingBottom + insets.systemWindowInsetBottom
)
insets
setBackgroundDrawable(InsetDrawable(materialShapeDrawable, inset, inset, inset, inset))
setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
}
}
override fun setCancelable(flag: Boolean) {
val listener = if (!flag) {
null
} else {
setCanceledOnTouchOutside(true)
View.OnClickListener { dismiss() }
}
binding.dialogBaseOutsideContainer.setOnClickListener(listener)
}
inner class Data: ObservableHost {
inner class Data : ObservableHost {
override var callbacks: PropertyChangeRegistry? = null
@get:Bindable
@ -88,7 +73,7 @@ class MagiskDialog(
set(value) = set(value, field, { field = it }, BR.title)
@get:Bindable
var message : CharSequence = ""
var message: CharSequence = ""
set(value) = set(value, field, { field = it }, BR.message)
val buttonPositive = Button()
@ -101,7 +86,7 @@ class MagiskDialog(
POSITIVE, NEUTRAL, NEGATIVE, IDGAF
}
inner class Button: ObservableHost {
inner class Button : ObservableHost {
override var callbacks: PropertyChangeRegistry? = null
@get:Bindable

View File

@ -12,219 +12,189 @@
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/dialog_base_outside_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:layout_width="match_parent">
<FrameLayout
android:layout_width="0dp"
<androidx.constraintlayout.widget.Guideline
android:id="@+id/dialog_base_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constrainedHeight="true"
app:layout_constrainedWidth="true"
app:layout_constraintBottom_toBottomOf="parent"
android:orientation="vertical"
app:layout_constraintGuide_begin="16dp" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/dialog_base_end"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_end="16dp" />
<ImageView
android:id="@+id/dialog_base_icon"
style="@style/WidgetFoundation.Image.Big"
gone="@{data.icon == null}"
android:layout_gravity="center"
android:layout_marginTop="@dimen/l1"
android:src="@{data.icon}"
app:layout_constraintBottom_toTopOf="@+id/dialog_base_title"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_max="400dp">
tools:src="@drawable/ic_delete_md2" />
<com.google.android.material.card.MaterialCardView
style="@style/WidgetFoundation.Card.Elevated"
<TextView
android:id="@+id/dialog_base_title"
gone="@{data.title.length == 0}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/l1"
android:gravity="center"
android:text="@{data.title}"
android:textAppearance="@style/AppearanceFoundation.Title"
app:layout_constraintEnd_toEndOf="@+id/dialog_base_end"
app:layout_constraintStart_toStartOf="@+id/dialog_base_start"
app:layout_constraintTop_toBottomOf="@+id/dialog_base_icon"
tools:lines="1"
tools:text="@tools:sample/lorem/random" />
<androidx.core.widget.NestedScrollView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/l_50"
android:overScrollMode="ifContentScrolls"
app:layout_constrainedHeight="true"
app:layout_constraintBottom_toTopOf="@+id/dialog_base_space"
app:layout_constraintEnd_toEndOf="@+id/dialog_base_end"
app:layout_constraintStart_toStartOf="@+id/dialog_base_start"
app:layout_constraintTop_toBottomOf="@+id/dialog_base_title">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusable="false"
app:cardElevation="@dimen/margin_generic"
app:cardUseCompatPadding="true">
android:layout_height="wrap_content">
<androidx.constraintlayout.widget.ConstraintLayout
<TextView
android:id="@+id/dialog_base_message"
gone="@{data.message.length == 0}"
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="match_parent"
android:text="@{data.message}"
android:textAppearance="@style/AppearanceFoundation.Body"
tools:lines="3"
tools:text="@tools:sample/lorem/random" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/dialog_base_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_begin="16dp" />
<FrameLayout
android:id="@+id/dialog_base_container"
gone="@{data.message.length != 0}"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/dialog_base_end"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_end="16dp" />
</FrameLayout>
<ImageView
android:id="@+id/dialog_base_icon"
style="@style/WidgetFoundation.Image.Big"
gone="@{data.icon == null}"
android:layout_gravity="center"
android:layout_marginTop="@dimen/l1"
android:src="@{data.icon}"
app:layout_constraintBottom_toTopOf="@+id/dialog_base_title"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:src="@drawable/ic_delete_md2" />
</androidx.core.widget.NestedScrollView>
<TextView
android:id="@+id/dialog_base_title"
gone="@{data.title.length == 0}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/l1"
android:gravity="center"
android:text="@{data.title}"
android:textAppearance="@style/AppearanceFoundation.Title"
app:layout_constraintEnd_toEndOf="@+id/dialog_base_end"
app:layout_constraintStart_toStartOf="@+id/dialog_base_start"
app:layout_constraintTop_toBottomOf="@+id/dialog_base_icon"
tools:lines="1"
tools:text="@tools:sample/lorem/random" />
<Space
android:id="@+id/dialog_base_space"
android:layout_width="wrap_content"
android:layout_height="@dimen/l_50"
app:layout_constraintBottom_toTopOf="@+id/dialog_base_buttons"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<androidx.core.widget.NestedScrollView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/l_50"
android:overScrollMode="ifContentScrolls"
app:layout_constrainedHeight="true"
app:layout_constraintBottom_toTopOf="@+id/dialog_base_space"
app:layout_constraintEnd_toEndOf="@+id/dialog_base_end"
app:layout_constraintStart_toStartOf="@+id/dialog_base_start"
app:layout_constraintTop_toBottomOf="@+id/dialog_base_title">
<androidx.appcompat.widget.ButtonBarLayout
android:id="@+id/dialog_base_buttons"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="bottom|center_horizontal"
android:layoutDirection="locale"
android:orientation="horizontal"
android:paddingStart="12dp"
android:paddingTop="4dp"
android:paddingEnd="12dp"
android:paddingBottom="4dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:id="@+id/dialog_base_button_4"
style="@style/WidgetFoundation.Button.Text"
gone="@{data.buttonIDGAF.icon == 0 &amp;&amp; data.buttonIDGAF.title.length == 0}"
isEnabled="@{data.buttonIDGAF.isEnabled()}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:clickable="@{data.buttonIDGAF.isEnabled()}"
android:filterTouchesWhenObscured="true"
android:focusable="@{data.buttonIDGAF.isEnabled()}"
android:onClick="@{() -> data.buttonIDGAF.clicked()}"
android:text="@{data.buttonIDGAF.title}"
app:icon="@{data.buttonIDGAF.icon}"
tools:icon="@drawable/ic_bug_md2"
tools:text="Button 1" />
<TextView
android:id="@+id/dialog_base_message"
gone="@{data.message.length == 0}"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@{data.message}"
android:textAppearance="@style/AppearanceFoundation.Body"
tools:lines="3"
tools:text="@tools:sample/lorem/random" />
<Button
android:id="@+id/dialog_base_button_2"
style="@style/WidgetFoundation.Button.Text"
gone="@{data.buttonNeutral.icon == 0 &amp;&amp; data.buttonNeutral.title.length == 0}"
isEnabled="@{data.buttonNeutral.isEnabled()}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:clickable="@{data.buttonNeutral.isEnabled()}"
android:filterTouchesWhenObscured="true"
android:focusable="@{data.buttonNeutral.isEnabled()}"
android:onClick="@{() -> data.buttonNeutral.clicked()}"
android:text="@{data.buttonNeutral.title}"
app:icon="@{data.buttonNeutral.icon}"
app:iconGravity="textStart"
tools:icon="@drawable/ic_bug_md2"
tools:text="Button 1" />
<FrameLayout
android:id="@+id/dialog_base_container"
gone="@{data.message.length != 0}"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Space
android:id="@+id/spacer"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"
android:visibility="invisible" />
</FrameLayout>
<Button
android:id="@+id/dialog_base_button_3"
style="@style/WidgetFoundation.Button.Text"
gone="@{data.buttonNegative.icon == 0 &amp;&amp; data.buttonNegative.title.length == 0}"
isEnabled="@{data.buttonNegative.isEnabled()}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:clickable="@{data.buttonNegative.isEnabled()}"
android:filterTouchesWhenObscured="true"
android:focusable="@{data.buttonNegative.isEnabled()}"
android:onClick="@{() -> data.buttonNegative.clicked()}"
android:text="@{data.buttonNegative.title}"
app:icon="@{data.buttonNegative.icon}"
tools:icon="@drawable/ic_bug_md2"
tools:text="Button 1" />
</androidx.core.widget.NestedScrollView>
<Button
android:id="@+id/dialog_base_button_1"
style="@style/WidgetFoundation.Button.Text"
gone="@{data.buttonPositive.icon == 0 &amp;&amp; data.buttonPositive.title.length == 0}"
isEnabled="@{data.buttonPositive.isEnabled()}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:clickable="@{data.buttonPositive.isEnabled()}"
android:filterTouchesWhenObscured="true"
android:focusable="@{data.buttonPositive.isEnabled()}"
android:onClick="@{() -> data.buttonPositive.clicked()}"
android:text="@{data.buttonPositive.title}"
app:icon="@{data.buttonPositive.icon}"
app:iconGravity="textStart"
tools:icon="@drawable/ic_bug_md2"
tools:text="Button 1" />
<Space
android:id="@+id/dialog_base_space"
android:layout_width="wrap_content"
android:layout_height="@dimen/l_50"
app:layout_constraintBottom_toTopOf="@+id/dialog_base_buttons"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<androidx.appcompat.widget.ButtonBarLayout
android:id="@+id/dialog_base_buttons"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="bottom|center_horizontal"
android:layoutDirection="locale"
android:orientation="horizontal"
android:paddingStart="12dp"
android:paddingTop="4dp"
android:paddingEnd="12dp"
android:paddingBottom="4dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<Button
android:id="@+id/dialog_base_button_4"
style="@style/WidgetFoundation.Button.Text"
gone="@{data.buttonIDGAF.icon == 0 &amp;&amp; data.buttonIDGAF.title.length == 0}"
isEnabled="@{data.buttonIDGAF.isEnabled()}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:clickable="@{data.buttonIDGAF.isEnabled()}"
android:filterTouchesWhenObscured="true"
android:focusable="@{data.buttonIDGAF.isEnabled()}"
android:onClick="@{() -> data.buttonIDGAF.clicked()}"
android:text="@{data.buttonIDGAF.title}"
app:icon="@{data.buttonIDGAF.icon}"
tools:icon="@drawable/ic_bug_md2"
tools:text="Button 1" />
<Button
android:id="@+id/dialog_base_button_2"
style="@style/WidgetFoundation.Button.Text"
gone="@{data.buttonNeutral.icon == 0 &amp;&amp; data.buttonNeutral.title.length == 0}"
isEnabled="@{data.buttonNeutral.isEnabled()}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:clickable="@{data.buttonNeutral.isEnabled()}"
android:filterTouchesWhenObscured="true"
android:focusable="@{data.buttonNeutral.isEnabled()}"
android:onClick="@{() -> data.buttonNeutral.clicked()}"
android:text="@{data.buttonNeutral.title}"
app:icon="@{data.buttonNeutral.icon}"
app:iconGravity="textStart"
tools:icon="@drawable/ic_bug_md2"
tools:text="Button 1" />
<Space
android:id="@+id/spacer"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"
android:visibility="invisible" />
<Button
android:id="@+id/dialog_base_button_3"
style="@style/WidgetFoundation.Button.Text"
gone="@{data.buttonNegative.icon == 0 &amp;&amp; data.buttonNegative.title.length == 0}"
isEnabled="@{data.buttonNegative.isEnabled()}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:clickable="@{data.buttonNegative.isEnabled()}"
android:filterTouchesWhenObscured="true"
android:focusable="@{data.buttonNegative.isEnabled()}"
android:onClick="@{() -> data.buttonNegative.clicked()}"
android:text="@{data.buttonNegative.title}"
app:icon="@{data.buttonNegative.icon}"
tools:icon="@drawable/ic_bug_md2"
tools:text="Button 1" />
<Button
android:id="@+id/dialog_base_button_1"
style="@style/WidgetFoundation.Button.Text"
gone="@{data.buttonPositive.icon == 0 &amp;&amp; data.buttonPositive.title.length == 0}"
isEnabled="@{data.buttonPositive.isEnabled()}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:clickable="@{data.buttonPositive.isEnabled()}"
android:filterTouchesWhenObscured="true"
android:focusable="@{data.buttonPositive.isEnabled()}"
android:onClick="@{() -> data.buttonPositive.clicked()}"
android:text="@{data.buttonPositive.title}"
app:icon="@{data.buttonPositive.icon}"
app:iconGravity="textStart"
tools:icon="@drawable/ic_bug_md2"
tools:text="Button 1" />
</androidx.appcompat.widget.ButtonBarLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>
</FrameLayout>
</androidx.appcompat.widget.ButtonBarLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View File

@ -4,11 +4,13 @@
<style name="Base.V17.Theme.Foundation.Light" parent="Theme.MaterialComponents.Light.NoActionBar">
<item name="android:windowBackground">?colorSurface</item>
<item name="android:windowContentOverlay">@null</item>
<item name="dialogTheme">@style/ThemeOverlay.Foundation.Dialog</item>
</style>
<style name="Base.V17.Theme.Foundation" parent="Theme.MaterialComponents.NoActionBar">
<item name="android:windowBackground">?colorSurface</item>
<item name="android:windowContentOverlay">@null</item>
<item name="dialogTheme">@style/ThemeOverlay.Foundation.Dialog</item>
</style>
<style name="Theme.Foundation.Light" parent="Base.V17.Theme.Foundation.Light" />
@ -29,4 +31,11 @@
<style name="Theme.Splash" parent="Base.V17.Theme.Splash" />
<style name="Base.V17.ThemeOverlay.Foundation.Dialog" parent="ThemeOverlay.MaterialComponents.Dialog">
<item name="android:windowMinWidthMajor">@dimen/abc_dialog_min_width_major</item>
<item name="android:windowMinWidthMinor">@dimen/abc_dialog_min_width_minor</item>
</style>
<style name="ThemeOverlay.Foundation.Dialog" parent="Base.V17.ThemeOverlay.Foundation.Dialog" />
</resources>