提问人:Muhammad Yousuf 提问时间:8/31/2023 更新时间:8/31/2023 访问量:26
Android 嵌套包含布局、函数传递和通过 DataBinding 实现
Android Nested Include Layouts Function Passing and Implementation Via DataBinding
问:
我使用 TextInputLayout 和 MaterialAutoCompleteTextView 制作了一个自定义下拉列表,我在同一片段和多个片段中多次使用它们作为包含的布局。我正在使用 DataBinding 在包含的布局之间传递数据。现在问题是下拉列表的点击事件,我如何在包含的布局中传递setOnItemClickListener并在下拉列表中使用它。我尝试使用 BindingAdapters 和其他笨拙的东西,但无法通过布局实现这一点。
下拉列表.xml
<?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="dropDownHint"
type="String" />
<variable
name="dropDownList"
type="java.util.List<String>" />
</data>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/textInputLayout"
style="@style/Theme.TextInputLayout.DropDown.Common"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.textfield.MaterialAutoCompleteTextView
android:id="@+id/dropDown"
style="@style/Theme.MaterialAutoCompleteTextView.DropDown"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:dropDownSelector="@drawable/background_dropdown"
android:hint="@{dropDownHint}"
android:inputType="none"
app:setDropDownBackground="@{@drawable/background_dropdown}"
app:setDropDownItems="@{dropDownList}"
tools:hint="Some Hint" />
</com.google.android.material.textfield.TextInputLayout>
</layout>
layout_textview_dropdown.xml
<?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="tvText"
type="String" />
<variable
name="dropDownHint"
type="String" />
<variable
name="dropDownList"
type="java.util.List<String>" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include
android:id="@+id/layout_textview"
layout="@layout/textview_heading"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:tvText="@{tvText}" />
<include
android:id="@+id/layout_dd_surgical"
layout="@layout/dropdown"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="7dp"
app:dropDownHint="@{dropDownHint}"
app:dropDownList="@{dropDownList}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/layout_textview" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
fragment_step1.xml
<?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="viewModel"
type="SomeViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="@dimen/overall_padding"
tools:context=".ui.patient_scan.step1.Step1Fragment">
<include
android:id="@+id/layout_fc"
layout="@layout/layout_textview_dropdown"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
app:dropDownHint="@{@string/dd_hint_fc}"
app:dropDownList="@{viewModel.fcList}"
app:layout_constraintBottom_toTopOf="@id/layout_healthFacility"
app:layout_constraintTop_toTopOf="parent"
app:tvText="@{@string/tv_text_fc}" />
<include
android:id="@+id/layout_healthFacility"
layout="@layout/layout_textview_dropdown"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/overall_spacing"
app:dropDownHint="@{@string/dd_hint_healthFacility}"
app:dropDownList="@{viewModel.healthFacility}"
app:layout_constraintBottom_toTopOf="@id/cl_date"
app:layout_constraintTop_toBottomOf="@id/layout_fc"
app:tvText="@{@string/tv_text_healthFacility}" />
...
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
材料AutoCompleteTextViewExt.kt
import android.graphics.drawable.Drawable
import androidx.databinding.BindingAdapter
import com.google.android.material.textfield.MaterialAutoCompleteTextView
import com.merisehat.clinicapp.ui.patient_scan.step1.DropDownAdapter
@BindingAdapter("setDropDownBackground")
fun MaterialAutoCompleteTextView.setDropDownBackground(drawable: Drawable) {
setDropDownBackgroundDrawable(drawable)
}
@BindingAdapter("setDropDownItems")
fun MaterialAutoCompleteTextView.setDropDownItems(list: List<String>?) {
if (list.isNullOrEmpty()) return
val adapter = DropDownAdapter(context, list)
setAdapter(adapter)
setOnItemClickListener { _, _, position, _ ->
adapter.setSelectedItem(position)
}
}
DropDownAdapter.kt
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import androidx.databinding.DataBindingUtil
import com.merisehat.clinicapp.data.models.api.dropdown.Country
import com.merisehat.clinicapp.databinding.ItemDropdownBinding
class DropDownAdapter(context: Context, list: List<String>):
ArrayAdapter<String>(context, 0, list) {
private var selectedItemPosition = -1
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
val item = getItem(position)
val binding: ItemDropdownBinding = if (convertView == null) {
val inflater = LayoutInflater.from(context)
ItemDropdownBinding.inflate(inflater, parent, false)
} else {
DataBindingUtil.getBinding(convertView)!!
}
binding.item = item
binding.isSelected = position == selectedItemPosition
return binding.root
}
override fun getDropDownView(position: Int, convertView: View?, parent: ViewGroup): View {
return getView(position, convertView, parent)
}
fun setSelectedItem(position: Int) {
selectedItemPosition = position
notifyDataSetChanged()
}
}
我有一个解决方案,通过它我可以通过 Fragment 实现 setOnItemClickListener,但我正在寻找一个干净的解决方案,我可以通过数据绑定布局实现,这样我就不必使用 Fragments
答: 暂无答案
评论