如何在 MaterialAlertDialog 中使用数据绑定?
How to use Databinding in MaterialAlertDialog?
我想在我的 MaterialAlertDialog 中使用数据绑定,以便在我的对话框显示时更改文本,但几乎没有关于此的教程。有人知道这样做吗?
对话框布局
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<data>
<variable
name="loginUserId"
type="String" />
<variable
name="loginOperation"
type="String" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ProgressBar
android:id="@+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="16dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:visibility="visible" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/materialTextView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:text="Example Verifizierung:"
android:textSize="@dimen/textDescriptionNormal2"
app:layout_constraintStart_toEndOf="@+id/progressBar"
app:layout_constraintTop_toTopOf="@+id/progressBar" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/materialTextView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:text="@{loginUserId}"
android:textSize="@dimen/textDescriptionNormal2"
app:layout_constraintStart_toEndOf="@+id/progressBar"
app:layout_constraintTop_toBottomOf="@+id/materialTextView2" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/materialTextView4"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:paddingBottom="@dimen/big16dpMargin"
android:text="@{loginOperation}"
android:textSize="@dimen/textDescriptionNormal2"
app:layout_constraintEnd_toEndOf="@+id/materialTextView3"
app:layout_constraintStart_toEndOf="@+id/progressBar"
app:layout_constraintTop_toBottomOf="@+id/materialTextView3" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
对话生成器
fun Fragment.buildLoginDialog() {
return MaterialAlertDialogBuilder(requireContext(), R.style.LoginDialogTheme)
.setTitle(R.string.loading_login_title)
.setView(R.layout.login_loading_screen)
.setCancelable(true)
}
片段(我想要的)
// Somewhere in fragment
val dialog = buildLoginDialog()
private fun observerSignInStatus() {
loginViewModel.signInResult.observe(viewLifecycleOwner) { status ->
dialog.show()
when(status) {
is LoginStateEvent.Loading -> {
dialog.changeText(status.message)
}
is LoginStateEvent.LoggedIn -> {
dialog.dismiss()
}
is LoginStateEvent.Error -> {
dialog.dismiss()
}
}
}
}
对话框图片
我在这里看到 2 个选项。您可以创建一个继承自 DialogFragment
的 class。 Dialogfragments
对于以对话框方式显示更复杂的布局非常有用,允许您控制和操作您的自定义布局。它们的行为类似于常规 Fragment,这意味着您必须覆盖 onCreateView()
& onViewCreated()
才能使用 databinding
.
显示您的自定义视图
或
您再次创建了一个继承自 DialogFragment
的 class,但现在您需要覆盖 onCreateDialog()
以使其使用 onCreateView()
& onViewCreated()
显示和管理 Fragment 的布局,如下所示:
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return MaterialAlertDialogBuilder(requireContext(), theme).apply {
dialogView = onCreateView(LayoutInflater.from(requireContext()), null, savedInstanceState)
dialogView?.let { onViewCreated(it, savedInstanceState) }
setView(dialogView)
}.create()
}
那么你还需要:
override fun getView(): View? { return dialogView }
好的,我设法找到了解决方案,但没有创建 dialogFragment。事实上,可以轻松地在 Alertdialog 中使用数据绑定。如果我对 lifecycleowner 的实现是正确的,那么我不是 100%。
实施
class CustomDialog(context: Context, private val mLifecycleOwner: LifecycleOwner): AlertDialog(context, R.style.LoginDialogTheme) {
private var _binding: LoginLoadingScreenBinding? = null
private val binding: LoginLoadingScreenBinding get() = _binding!!
override fun onCreate(savedInstanceState: Bundle?) {
initDialog()
super.onCreate(savedInstanceState)
}
override fun show() {
_binding = LoginLoadingScreenBinding.inflate(layoutInflater).apply { lifecycleOwner = mLifecycleOwner }
super.show()
}
override fun dismiss() {
_binding = null
super.dismiss()
}
fun onChangeUserId(mText: String) {
binding.userId.text = mText
}
fun onChangeLoginOperation(mText: String) {
binding.loginOperation.text = mText
}
private fun initDialog() {
setTitle(R.string.loading_login_title)
setCancelable(true)
setView(binding.root)
}
}
主叫方
// fragment
val dialog = CustomDialog(requireContext(), viewLifecyleOwner)
dialog.show()
dialog.onChangeUserId("New Id")
dialog.OnChangeLoginOperation("New Operation")
我想在我的 MaterialAlertDialog 中使用数据绑定,以便在我的对话框显示时更改文本,但几乎没有关于此的教程。有人知道这样做吗?
对话框布局
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<data>
<variable
name="loginUserId"
type="String" />
<variable
name="loginOperation"
type="String" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ProgressBar
android:id="@+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="16dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:visibility="visible" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/materialTextView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:text="Example Verifizierung:"
android:textSize="@dimen/textDescriptionNormal2"
app:layout_constraintStart_toEndOf="@+id/progressBar"
app:layout_constraintTop_toTopOf="@+id/progressBar" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/materialTextView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:text="@{loginUserId}"
android:textSize="@dimen/textDescriptionNormal2"
app:layout_constraintStart_toEndOf="@+id/progressBar"
app:layout_constraintTop_toBottomOf="@+id/materialTextView2" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/materialTextView4"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:paddingBottom="@dimen/big16dpMargin"
android:text="@{loginOperation}"
android:textSize="@dimen/textDescriptionNormal2"
app:layout_constraintEnd_toEndOf="@+id/materialTextView3"
app:layout_constraintStart_toEndOf="@+id/progressBar"
app:layout_constraintTop_toBottomOf="@+id/materialTextView3" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
对话生成器
fun Fragment.buildLoginDialog() {
return MaterialAlertDialogBuilder(requireContext(), R.style.LoginDialogTheme)
.setTitle(R.string.loading_login_title)
.setView(R.layout.login_loading_screen)
.setCancelable(true)
}
片段(我想要的)
// Somewhere in fragment
val dialog = buildLoginDialog()
private fun observerSignInStatus() {
loginViewModel.signInResult.observe(viewLifecycleOwner) { status ->
dialog.show()
when(status) {
is LoginStateEvent.Loading -> {
dialog.changeText(status.message)
}
is LoginStateEvent.LoggedIn -> {
dialog.dismiss()
}
is LoginStateEvent.Error -> {
dialog.dismiss()
}
}
}
}
对话框图片
我在这里看到 2 个选项。您可以创建一个继承自 DialogFragment
的 class。 Dialogfragments
对于以对话框方式显示更复杂的布局非常有用,允许您控制和操作您的自定义布局。它们的行为类似于常规 Fragment,这意味着您必须覆盖 onCreateView()
& onViewCreated()
才能使用 databinding
.
或
您再次创建了一个继承自 DialogFragment
的 class,但现在您需要覆盖 onCreateDialog()
以使其使用 onCreateView()
& onViewCreated()
显示和管理 Fragment 的布局,如下所示:
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return MaterialAlertDialogBuilder(requireContext(), theme).apply {
dialogView = onCreateView(LayoutInflater.from(requireContext()), null, savedInstanceState)
dialogView?.let { onViewCreated(it, savedInstanceState) }
setView(dialogView)
}.create()
}
那么你还需要:
override fun getView(): View? { return dialogView }
好的,我设法找到了解决方案,但没有创建 dialogFragment。事实上,可以轻松地在 Alertdialog 中使用数据绑定。如果我对 lifecycleowner 的实现是正确的,那么我不是 100%。
实施
class CustomDialog(context: Context, private val mLifecycleOwner: LifecycleOwner): AlertDialog(context, R.style.LoginDialogTheme) {
private var _binding: LoginLoadingScreenBinding? = null
private val binding: LoginLoadingScreenBinding get() = _binding!!
override fun onCreate(savedInstanceState: Bundle?) {
initDialog()
super.onCreate(savedInstanceState)
}
override fun show() {
_binding = LoginLoadingScreenBinding.inflate(layoutInflater).apply { lifecycleOwner = mLifecycleOwner }
super.show()
}
override fun dismiss() {
_binding = null
super.dismiss()
}
fun onChangeUserId(mText: String) {
binding.userId.text = mText
}
fun onChangeLoginOperation(mText: String) {
binding.loginOperation.text = mText
}
private fun initDialog() {
setTitle(R.string.loading_login_title)
setCancelable(true)
setView(binding.root)
}
}
主叫方
// fragment
val dialog = CustomDialog(requireContext(), viewLifecyleOwner)
dialog.show()
dialog.onChangeUserId("New Id")
dialog.OnChangeLoginOperation("New Operation")