首页 > 解决方案 > 使用多种类型视图的 ReyclerView 不起作用

问题描述

我正在 Kotlin 中开发一个 Android 应用程序,并实现了一个 RecyclerView。

此 RecyclerView 的每一项都包含以下 3 种组合之一:

我的问题只是没有显示任何内容!我不明白我的错误,你能帮我吗?

这是我的适配器:

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

    sealed class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        class TextViewHolder(itemView: View) : ViewHolder(itemView) {
            val textViewName: TextView = itemView.findViewById(R.id.parameterName)
            val textViewValue: TextView = itemView.findViewById(R.id.parameterValue)
        }
        class ButtonViewHolder(itemView: View) : ViewHolder(itemView) {
            var textViewName: TextView = itemView.findViewById(R.id.parameterName)
            val buttonViewValue: Button = itemView.findViewById(R.id.parameterButton)
        }
        class SpinnerViewHolder(itemView: View) : ViewHolder(itemView) {
            val textViewName: TextView = itemView.findViewById(R.id.parameterName)
            val spinnerViewValue: Spinner = itemView.findViewById(R.id.parameterSpinner)
        }
    }

    override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ViewHolder {
        return when (viewType) {
            0 -> {
                val view = LayoutInflater.from(viewGroup.context)
                        .inflate(R.layout.parameter_text, viewGroup, false)
                ViewHolder.TextViewHolder(view)
            }
            1 -> {
                val view = LayoutInflater.from(viewGroup.context)
                        .inflate(R.layout.parameter_button, viewGroup, false)
                ViewHolder.ButtonViewHolder(view)
            }
            2 -> {
                val view = LayoutInflater.from(viewGroup.context)
                        .inflate(R.layout.parameter_spinner, viewGroup, false)
                ViewHolder.SpinnerViewHolder(view)
            }
            else -> throw IllegalArgumentException("Invalid view type")
        }
    }

    override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {
        when (viewHolder) {
            is ViewHolder.TextViewHolder -> {
                viewHolder.textViewName.text = dataSet[position].parameterName
                viewHolder.textViewValue.text = dataSet[position].parameterValue as CharSequence?
            }
            is ViewHolder.ButtonViewHolder -> {
                viewHolder.textViewName.text = dataSet[position].parameterName
                viewHolder.buttonViewValue.text = dataSet[position].parameterValue as CharSequence?
            }
            is ViewHolder.SpinnerViewHolder -> {
                viewHolder.textViewName.text = dataSet[position].parameterName
                viewHolder.spinnerViewValue.adapter = dataSet[position].parameterValue as SpinnerAdapter?
            }
        }
    }

    override fun getItemViewType(position: Int) : Int {
        return dataSet[position].parameterType
    }


    override fun getItemCount() = dataSet.size
}

从类 Parameter 继承的每种不同类型的参数:

open class Parameter(open var parameterName: String? = "", open var parameterType: Int = 0, open var parameterValue: Any) {
}

参数文本类:

class ParameterText(override var parameterName: String?, override var parameterValue: Any = "") : Parameter(parameterName, parameterValue = parameterValue!!) {
    override var parameterType: Int = 0
}

参数按钮类:

class ParameterButton(override var parameterName: String?, override var parameterValue: Any = "") : Parameter(parameterName, parameterValue = parameterValue!!) {
    override var parameterType: Int = 1
}

ParameterSpinner 类:

class ParameterSpinner(override var parameterName: String?, override var parameterValue: Any) : Parameter(parameterName, parameterValue = parameterValue) {
    override var parameterType: Int = 2
}

在 OnCreate 方法中,我初始化了 RecyclerView:

rv_parameters.layoutManager = LinearLayoutManager(this)
rv_parameters.adapter = CustomAdapter(parametersList)

这是我的参数列表:

private val parametersList = emptyArray<Parameter>()

最后,这是我向此列表添加参数的方法:

append(parametersList, ParameterText("Temperature", "24°C"))

使用这种方法:

fun append(arr: Array<Parameter>, element: Parameter): Array<Parameter?> {
    val array = arrayOfNulls<Parameter>(arr.size + 1)
    System.arraycopy(arr, 0, array, 0, arr.size)
    array[arr.size] = element
    return array
}

编辑 1:(按照 Tenfour04 的回答)

我的适配器:

class CustomAdapter(private var dataSet: List<Parameter?>) :
        RecyclerView.Adapter<CustomAdapter.ViewHolder>() {

    sealed class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        class TextViewHolder(itemView: View) : ViewHolder(itemView) {
            val textViewName: TextView = itemView.findViewById(R.id.parameterName)
            val textViewValue: TextView = itemView.findViewById(R.id.parameterValue)
        }
        class ButtonViewHolder(itemView: View) : ViewHolder(itemView) {
            var textViewName: TextView = itemView.findViewById(R.id.parameterName)
            val buttonViewValue: Button = itemView.findViewById(R.id.parameterButton)
        }
        class SpinnerViewHolder(itemView: View) : ViewHolder(itemView) {
            val textViewName: TextView = itemView.findViewById(R.id.parameterName)
            val spinnerViewValue: Spinner = itemView.findViewById(R.id.parameterSpinner)
        }
    }

    override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ViewHolder {
        return when (viewType) {
            0 -> {
                val view = LayoutInflater.from(viewGroup.context)
                        .inflate(R.layout.parameter_text, viewGroup, false)
                ViewHolder.TextViewHolder(view)
            }
            1 -> {
                val view = LayoutInflater.from(viewGroup.context)
                        .inflate(R.layout.parameter_button, viewGroup, false)
                ViewHolder.ButtonViewHolder(view)
            }
            2 -> {
                val view = LayoutInflater.from(viewGroup.context)
                        .inflate(R.layout.parameter_spinner, viewGroup, false)
                ViewHolder.SpinnerViewHolder(view)
            }
            else -> throw IllegalArgumentException("Invalid view type")
        }
    }

    override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {
        when (viewHolder) {
            is ViewHolder.TextViewHolder -> {
                viewHolder.textViewName.text = dataSet[position]!!.parameterName
                viewHolder.textViewValue.text = dataSet[position]!!.parameterValue as CharSequence?
            }
            is ViewHolder.ButtonViewHolder -> {
                viewHolder.textViewName.text = dataSet[position]!!.parameterName
                viewHolder.buttonViewValue.text = dataSet[position]!!.parameterValue as CharSequence?
            }
            is ViewHolder.SpinnerViewHolder -> {
                viewHolder.textViewName.text = dataSet[position]!!.parameterName
                viewHolder.spinnerViewValue.adapter = dataSet[position]!!.parameterValue as SpinnerAdapter?
            }
        }
    }

    override fun getItemViewType(position: Int) : Int {
        return dataSet[position]!!.parameterType
    }


    override fun getItemCount() = dataSet.size
}

在 OnCreate 方法中,我初始化了 RecyclerView:

rv_parameters.layoutManager = LinearLayoutManager(this)
rv_parameters.adapter = CustomAdapter(parametersList)

这是我的参数列表:

private var parametersList = emptyList<Parameter?>()

最后,这是我向此列表添加参数的方法:

with(rv_parameters.adapter) {
    parametersList += ParameterText("Temperature", "24°C")
    this?.notifyDataSetChanged()
}

标签: androidkotlinandroid-recyclerview

解决方案


虽然它不在 Kotlin 中,但我认为它会对您有所帮助

公共类 BeneficiaryIndi​​catorAdapter 扩展 RecyclerView.Adapter<RecyclerView.ViewHolder> {

private List<Indicator> dataSet;
private Context mContext;

public BeneficiaryIndicatorAdapter(List<Indicator> dataSet, Context mContext) {
    this.dataSet = dataSet;
    this.mContext = mContext;
}

public static class EdittextViewHolder extends RecyclerView.ViewHolder{
    AppCompatTextView indicator_number, indicator_en_tv, indicator_bn_tv, save_tv;
    TextInputEditText answer_tf;
    public EdittextViewHolder(@NonNull View itemView) {
        super(itemView);

        this.indicator_number = itemView.findViewById (R.id.indicator_number);
        this.indicator_en_tv = itemView.findViewById (R.id.indicator_en_tv);
        this.indicator_bn_tv = itemView.findViewById (R.id.indicator_bn_tv);
        this.answer_tf = itemView.findViewById (R.id.answer_tf);
        this.save_tv = itemView.findViewById (R.id.save_tv);



    }
}

public static class DatePickerHolder extends RecyclerView.ViewHolder{
    AppCompatTextView indicator_number, indicator_en_tv, indicator_bn_tv, select_date_tv, save_tv;
    RelativeLayout transaction_date_layout;

    public DatePickerHolder(@NonNull View itemView) {
        super(itemView);

        this.indicator_number = itemView.findViewById (R.id.indicator_number);
        this.indicator_en_tv = itemView.findViewById (R.id.indicator_en_tv);
        this.indicator_bn_tv = itemView.findViewById (R.id.indicator_bn_tv);
        this.select_date_tv = itemView.findViewById (R.id.select_date_tv);
        this.transaction_date_layout = itemView.findViewById (R.id.transaction_date_layout);
        this.save_tv = itemView.findViewById (R.id.save_tv);
    }
}

public static class SpinnerPickerHolder extends RecyclerView.ViewHolder{
    AppCompatTextView indicator_number, indicator_en_tv, indicator_bn_tv, save_tv;
    AppCompatSpinner answerSpinner;
    public SpinnerPickerHolder(@NonNull View itemView) {
        super(itemView);
        this.indicator_number = itemView.findViewById (R.id.indicator_number);
        this.indicator_en_tv = itemView.findViewById (R.id.indicator_en_tv);
        this.indicator_bn_tv = itemView.findViewById (R.id.indicator_bn_tv);
        this.answerSpinner = itemView.findViewById (R.id.answerSpinner);
        this.save_tv = itemView.findViewById (R.id.save_tv);
    }
}

public static class MultiSelectHolder extends RecyclerView.ViewHolder{
    AppCompatTextView indicator_number, indicator_en_tv, indicator_bn_tv, save_tv, select_data_tv;
    public MultiSelectHolder(@NonNull View itemView) {
        super(itemView);
        this.indicator_number = itemView.findViewById (R.id.indicator_number);
        this.indicator_en_tv = itemView.findViewById (R.id.indicator_en_tv);
        this.indicator_bn_tv = itemView.findViewById (R.id.indicator_bn_tv);
        this.select_data_tv = itemView.findViewById (R.id.select_data_tv);

        this.save_tv = itemView.findViewById (R.id.save_tv);
    }
}



@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    View view;
    mContext = parent.getContext();

    if (viewType == 1){
        view = LayoutInflater.from(parent.getContext()).inflate(R.layout.single_questionear_edittext_layout, parent, false);
        return new EdittextViewHolder(view);
    }if (viewType == 2){
        view = LayoutInflater.from(parent.getContext()).inflate(R.layout.single_questionear_edittext_layout, parent, false);
        return new EdittextViewHolder(view);
    }if (viewType == 3){
        view = LayoutInflater.from(parent.getContext()).inflate(R.layout.single_questionear_edittext_layout, parent, false);
        return new EdittextViewHolder(view);
    } else if (viewType == 4){
        view = LayoutInflater.from(parent.getContext()).inflate(R.layout.single_questionear_datepicker_layout, parent, false);
        return new DatePickerHolder(view);
    } else if(viewType == 5){
        view = LayoutInflater.from(parent.getContext()).inflate(R.layout.single_questionear_spinner_layout, parent, false);
        return new SpinnerPickerHolder(view);
    } else if(viewType == 6){
        view = LayoutInflater.from(parent.getContext()).inflate(R.layout.single_questionear_mulilist_layout, parent, false);
        return new MultiSelectHolder(view);
    }

    return null;
}

@Override
public int getItemViewType(int position) {

    switch (dataSet.get(position).getColumnDataType()) {
        case 1:
            return Indicator.INT_TYPE;
        case 2:
            return Indicator.VARCHAR_TYPE;
        case 3:
            return Indicator.DECIMAL_TYPE;
        case 4:
            return Indicator.DATETIME_TYPE;
        case 5:
            return Indicator.BOOLEAN_TYPE;
        case 6:
            return Indicator.LIST_TYPE;
        default:
            return position;
    }

}

@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {

    Indicator beneficiaryIndicator = dataSet.get(position);

    if (beneficiaryIndicator !=null){
        int i = 0;
        List<String> values = beneficiaryIndicator.getValues();


        if (beneficiaryIndicator != null) {

            switch (beneficiaryIndicator.getColumnDataType()) {
                case Indicator.INT_TYPE:
                    break;

                case Indicator.VARCHAR_TYPE:
                    break;

                case Indicator.DECIMAL_TYPE:
                
                    break;

                case Indicator.DATETIME_TYPE:
                    
                    break;

                case Indicator.BOOLEAN_TYPE:
                    break;

                case Indicator.LIST_TYPE:
                    break;
            }
        }
    }
}


@Override
public int getItemCount() {
    return dataSet.size();
}

}


推荐阅读