android - 使用多种类型视图的 ReyclerView 不起作用
问题描述
我正在 Kotlin 中开发一个 Android 应用程序,并实现了一个 RecyclerView。
此 RecyclerView 的每一项都包含以下 3 种组合之一:
- 一个文本视图 + 一个文本视图
- 一个 TextView + 一个按钮
- 一个 TextView + 一个 Spinner
我的问题只是没有显示任何内容!我不明白我的错误,你能帮我吗?
这是我的适配器:
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()
}
解决方案
虽然它不在 Kotlin 中,但我认为它会对您有所帮助
公共类 BeneficiaryIndicatorAdapter 扩展 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();
}
}
推荐阅读
- javascript - contenteditable div 在光标位置设置 PX 字体大小
- javascript - 无法在js上将blob作为文本加载
- android - 根据结果更改 Alertdialog 的 Imageview
- c# - 加入Linq时如何使用表达式获取动态谓词
- c# - 如何防止使用 SQL 加载的浮点 Excel 数据被截断
- google-analytics - 在 Google Analytics 中:如何在一份报告中组合来自多个子域的数据?
- html - 打印带有固定标题的html表格
- django - 如何强制插入 wagtail Draftail 编辑器中的外部 URL 在新选项卡上打开?
- html - 垂直对齐列表组引导
- docker - docker run 打开一个 X 窗口并保持空闲