Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 如何使用不同类型的项目(文本视图、按钮、微调器)实现通用的RecyclerView?_Android_Kotlin_Android Recyclerview - Fatal编程技术网

Android 如何使用不同类型的项目(文本视图、按钮、微调器)实现通用的RecyclerView?

Android 如何使用不同类型的项目(文本视图、按钮、微调器)实现通用的RecyclerView?,android,kotlin,android-recyclerview,Android,Kotlin,Android Recyclerview,我正在Kotlin开发一个Android应用程序,允许智能手机通过BLE与nRF52840通信以读取/写入数据 我正在开发显示此数据的视图。此视图以不同参数的形式出现,可以对其进行操作(使用按钮或微调器),也可以不操作(包含数据的简单TextView) 因此,我首先为每种类型的视图(带有TextView、Button或Spinner的参数)创建了一个RecyclerView activity.xml: <androidx.recyclerview.widget.RecyclerView

我正在Kotlin开发一个Android应用程序,允许智能手机通过BLE与nRF52840通信以读取/写入数据

我正在开发显示此数据的视图。此视图以不同参数的形式出现,可以对其进行操作(使用按钮或微调器),也可以不操作(包含数据的简单TextView)

因此,我首先为每种类型的视图(带有TextView、Button或Spinner的参数)创建了一个RecyclerView

activity.xml:

<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/rv_parameters_text"
    tools:listitem="@layout/parameter_text"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:nestedScrollingEnabled="false"
    app:layout_constraintTop_toBottomOf="@id/currentConnexion"
    app:layout_constraintBottom_toTopOf="@+id/rv_parameters_spinner"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"/>

<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/rv_parameters_spinner"
    tools:listitem="@layout/parameter_spinner"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:layout_constraintTop_toBottomOf="@id/rv_parameters_text"
    app:layout_constraintBottom_toTopOf="@+id/rv_parameters_button"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"/>

<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/rv_parameters_button"
    tools:listitem="@layout/parameter_button"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:layout_constraintTop_toBottomOf="@id/rv_parameters_spinner"
    app:layout_constraintBottom_toTopOf="@+id/disconnect"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"/>

您能帮助我吗?

您需要创建自己的
RecyclerView.Adapter
,它将通过支持不同的视图类型来提供不同的
视图持有者。备份适配器的数据将包含这些类型(文本、微调器、按钮),每个类型都有相应的
ViewHolder
s

这是我快速输入的示例实现,目的是让您了解:

sealed class MyData {
    data class Data1(val name: String)
    data class Data2(val number: Int)
}

class CustomAdapter(private val dataSet: Array<MyData>) :
        RecyclerView.Adapter<CustomAdapter.ViewHolder>() {

    sealed class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        class ViewHolder1(itemView: View) : ViewHolder(itemView) {
            val textView: TextView
            init {
                textView = view.findViewById(R.id.textView1)
            }
        class ViewHolder2(itemView: View) : ViewHolder(itemView) {
            val textView: TextView
            init {
                textView = view.findViewById(R.id.textView2)
            }
        }
    }

    override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ViewHolder {
        if (viewType == 1) {
            val view = LayoutInflater.from(viewGroup.context)
                .inflate(R.layout.text_row_item1, viewGroup, false)
            return ViewHolder1(view)
        } else {
            val view = LayoutInflater.from(viewGroup.context)
                .inflate(R.layout.text_row_item2, viewGroup, false)
            return ViewHolder2(view)
        }
    }

    override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {
        when (viewHolder) {
            is ViewHolder1 -> viewHolder.textView = "${dataSet[position]}"
            is ViewHolder2 -> viewHolder.textView = "${dataSet[position]}"
        }
    }

    override fun getItemViewType(int position) = when (dataSet[position]) {
      is MyData.Data1 -> 1
      is MyData.Data2 -> 2
    }

    override fun getItemCount() = dataSet.size
}
密封类MyData{
数据类Data1(val名称:String)
数据类Data2(val编号:Int)
}
类CustomAdapter(专用val数据集:数组):
RecyclerView.Adapter(){
密封类ViewHolder(视图:视图):RecyclerView.ViewHolder(视图){
类ViewHolder1(项目视图:视图):ViewHolder(项目视图){
val textView:textView
初始化{
textView=view.findViewById(R.id.textView1)
}
类ViewHolder2(项目视图:视图):ViewHolder(项目视图){
val textView:textView
初始化{
textView=view.findViewById(R.id.textView2)
}
}
}
覆盖创建ViewHolder(viewGroup:viewGroup,viewType:Int):ViewHolder{
如果(viewType==1){
val view=LayoutInflater.from(viewGroup.context)
.充气(R.layout.text\u row\u item1,视图组,false)
返回视图保持器1(视图)
}否则{
val view=LayoutInflater.from(viewGroup.context)
.充气(R.layout.text\u row\u item2,视图组,false)
返回视图保持器2(视图)
}
}
覆盖BindViewHolder(viewHolder:viewHolder,位置:Int){
何时(视图持有者){
is ViewHolder1->viewHolder.textView=“${dataSet[position]}”
is ViewHolder2->viewHolder.textView=“${dataSet[position]}”
}
}
覆盖getItemViewType(int位置)=何时(数据集[位置]){
是MyData.Data1->1吗
是MyData.Data2->2吗
}
重写getItemCount()=dataSet.size
}

您需要创建自己的
RecyclerView.Adapter
,它将通过支持不同的视图类型来提供不同的
ViewHolder
。备份适配器的数据将包含这些类型(文本、微调器、按钮),并且您将为每种类型提供相应的
ViewHolder

这是我快速输入的示例实现,目的是让您了解:

sealed class MyData {
    data class Data1(val name: String)
    data class Data2(val number: Int)
}

class CustomAdapter(private val dataSet: Array<MyData>) :
        RecyclerView.Adapter<CustomAdapter.ViewHolder>() {

    sealed class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        class ViewHolder1(itemView: View) : ViewHolder(itemView) {
            val textView: TextView
            init {
                textView = view.findViewById(R.id.textView1)
            }
        class ViewHolder2(itemView: View) : ViewHolder(itemView) {
            val textView: TextView
            init {
                textView = view.findViewById(R.id.textView2)
            }
        }
    }

    override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ViewHolder {
        if (viewType == 1) {
            val view = LayoutInflater.from(viewGroup.context)
                .inflate(R.layout.text_row_item1, viewGroup, false)
            return ViewHolder1(view)
        } else {
            val view = LayoutInflater.from(viewGroup.context)
                .inflate(R.layout.text_row_item2, viewGroup, false)
            return ViewHolder2(view)
        }
    }

    override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {
        when (viewHolder) {
            is ViewHolder1 -> viewHolder.textView = "${dataSet[position]}"
            is ViewHolder2 -> viewHolder.textView = "${dataSet[position]}"
        }
    }

    override fun getItemViewType(int position) = when (dataSet[position]) {
      is MyData.Data1 -> 1
      is MyData.Data2 -> 2
    }

    override fun getItemCount() = dataSet.size
}
密封类MyData{
数据类Data1(val名称:String)
数据类Data2(val编号:Int)
}
类CustomAdapter(专用val数据集:数组):
RecyclerView.Adapter(){
密封类ViewHolder(视图:视图):RecyclerView.ViewHolder(视图){
类ViewHolder1(项目视图:视图):ViewHolder(项目视图){
val textView:textView
初始化{
textView=view.findViewById(R.id.textView1)
}
类ViewHolder2(项目视图:视图):ViewHolder(项目视图){
val textView:textView
初始化{
textView=view.findViewById(R.id.textView2)
}
}
}
覆盖创建ViewHolder(viewGroup:viewGroup,viewType:Int):ViewHolder{
如果(viewType==1){
val view=LayoutInflater.from(viewGroup.context)
.充气(R.layout.text\u row\u item1,视图组,false)
返回视图保持器1(视图)
}否则{
val view=LayoutInflater.from(viewGroup.context)
.充气(R.layout.text\u row\u item2,视图组,false)
返回视图保持器2(视图)
}
}
覆盖BindViewHolder(viewHolder:viewHolder,位置:Int){
何时(视图持有者){
is ViewHolder1->viewHolder.textView=“${dataSet[position]}”
is ViewHolder2->viewHolder.textView=“${dataSet[position]}”
}
}
覆盖getItemViewType(int位置)=何时(数据集[位置]){
是MyData.Data1->1吗
是MyData.Data2->2吗
}
重写getItemCount()=dataSet.size
}

这可能不是最好的方法,但我编辑了updateValue函数,如下所示:

private fun updateValue(index: Int, value: ParameterText) {
    parametersList.removeAt(index)
    parametersList.insert(index, value)
    rv_parameters.adapter?.notifyItemChanged(index)
}

这可能不是最好的方法,但我编辑了updateValue函数,如下所示:

private fun updateValue(index: Int, value: ParameterText) {
    parametersList.removeAt(index)
    parametersList.insert(index, value)
    rv_parameters.adapter?.notifyItemChanged(index)
}

谢谢你的帮助!请看下面我的答案。谢谢你的帮助!请看下面我的答案。
// Adapter
private val parametersList = emptyDataSourceTyped<Any>()
private fun updateValue(index: Int, value: String) {
    //parametersList[index].parameterValue = value
    rv_parameters.adapter?.notifyDataSetChanged()
}
sealed class MyData {
    data class Data1(val name: String)
    data class Data2(val number: Int)
}

class CustomAdapter(private val dataSet: Array<MyData>) :
        RecyclerView.Adapter<CustomAdapter.ViewHolder>() {

    sealed class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        class ViewHolder1(itemView: View) : ViewHolder(itemView) {
            val textView: TextView
            init {
                textView = view.findViewById(R.id.textView1)
            }
        class ViewHolder2(itemView: View) : ViewHolder(itemView) {
            val textView: TextView
            init {
                textView = view.findViewById(R.id.textView2)
            }
        }
    }

    override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ViewHolder {
        if (viewType == 1) {
            val view = LayoutInflater.from(viewGroup.context)
                .inflate(R.layout.text_row_item1, viewGroup, false)
            return ViewHolder1(view)
        } else {
            val view = LayoutInflater.from(viewGroup.context)
                .inflate(R.layout.text_row_item2, viewGroup, false)
            return ViewHolder2(view)
        }
    }

    override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {
        when (viewHolder) {
            is ViewHolder1 -> viewHolder.textView = "${dataSet[position]}"
            is ViewHolder2 -> viewHolder.textView = "${dataSet[position]}"
        }
    }

    override fun getItemViewType(int position) = when (dataSet[position]) {
      is MyData.Data1 -> 1
      is MyData.Data2 -> 2
    }

    override fun getItemCount() = dataSet.size
}
private fun updateValue(index: Int, value: ParameterText) {
    parametersList.removeAt(index)
    parametersList.insert(index, value)
    rv_parameters.adapter?.notifyItemChanged(index)
}