Recyclerview适配器的onCreateViewHolder方法中,LinearLayout无法强制转换为TextView。

huangapple go评论85阅读模式
英文:

Recyclerview Adapter onCreateViewHolder method LinearLayout cannot be cast to TextView

问题

这是您提供的代码的翻译部分:

所以我只是试图设置一个简单的Recyclerview来显示来自数组的字符串。这是我设置的适配器:

package com.example.workoutapp1;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.recyclerview.widget.RecyclerView;

public class WorkoutActivityAdapter extends RecyclerView.Adapter<WorkoutActivityAdapter.MyViewHolder> {
    private String[] mDataset;

    // 为每个数据项提供视图的引用
    // 复杂的数据项可能需要多个视图,而且
    // 您可以在视图持有者中为数据项的所有视图提供访问权限
    public static class MyViewHolder extends RecyclerView.ViewHolder {
        public TextView textView;
        public MyViewHolder(TextView v) {
            super(v);
            textView = (TextView) v.findViewById(R.id.workout_text_view);
        }
    }

    // 提供适当的构造函数(取决于数据集的类型)
    public WorkoutActivityAdapter(String[] myDataset) {
        mDataset = myDataset;
    }

    // 创建新视图(由布局管理器调用)
    @Override
    public WorkoutActivityAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        Context context = parent.getContext();
        LayoutInflater inflater = LayoutInflater.from(context);

        // 充气自定义布局
        TextView contactView = (TextView) inflater.inflate(R.layout.workout_item, parent, false);

        // 返回一个新的持有者实例
        WorkoutActivityAdapter.MyViewHolder viewHolder = new WorkoutActivityAdapter.MyViewHolder(contactView);
        return viewHolder;
    }

    // 替换视图的内容(由布局管理器调用)
    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        // - 获取数据集中这个位置的元素
        // - 用该元素的内容替换视图的内容
        holder.textView.setText(mDataset[position]);
    }

    // 返回数据集的大小(由布局管理器调用)
    @Override
    public int getItemCount() {
        return mDataset.length;
    }
}

workout_item.xml 是一个简单的LinearLayout,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingTop="10dp"
    android:paddingBottom="10dp">

    <TextView
        android:id="@+id/workout_text_view"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1" />

</LinearLayout>

每次我运行这个代码,应用程序都会崩溃,因为在尝试充气自定义布局时出现了致命异常:

"java.lang.ClassCastException: android.widget.LinearLayout无法转换为android.widget.TextView"

我很难理解发生了什么,因为我只是在网上按照教程操作。如果有人可以帮助我,将不胜感激。

英文:

So I'm just trying to set up a simple Recyclerview to display strings from an array. Here's the adapter that I have set up:

package com.example.workoutapp1;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.recyclerview.widget.RecyclerView;
public class WorkoutActivityAdapter extends RecyclerView.Adapter&lt;WorkoutActivityAdapter.MyViewHolder&gt; {
private String[] mDataset;
// Provide a reference to the views for each data item
// Complex data items may need more than one view per item, and
// you provide access to all the views for a data item in a view holder
public static class MyViewHolder extends RecyclerView.ViewHolder {
public TextView textView;
public MyViewHolder (TextView v) {
super(v);
textView = (TextView) v.findViewById(R.id.workout_text_view);
}
}
// Provide a suitable constructor (depends on the kind of dataset)
public WorkoutActivityAdapter(String[] myDataset) {
mDataset = myDataset;
}
// Create new views (invoked by the layout manager)
@Override
public WorkoutActivityAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Context context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
// Inflate the custom layout
TextView contactView = (TextView) inflater.inflate(R.layout.workout_item, parent, false);
// Return a new holder instance
WorkoutActivityAdapter.MyViewHolder viewHolder = new WorkoutActivityAdapter.MyViewHolder(contactView);
return viewHolder;
}
// Replace the contents of a view (invoked by the layout manager)
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
// - get element from your dataset at this position
// - replace the contents of the view with that element\
holder.textView.setText(mDataset[position]);
}
// Return the size of your dataset (invoked by the layout manager)
@Override
public int getItemCount() {
return mDataset.length;
}
}

workout_item.xml is a simple linearlayout as follows:

&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;LinearLayout
xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
android:orientation=&quot;horizontal&quot;
android:layout_width=&quot;match_parent&quot;
android:layout_height=&quot;wrap_content&quot;
android:paddingTop=&quot;10dp&quot;
android:paddingBottom=&quot;10dp&quot; &gt;
&lt;TextView
android:id=&quot;@+id/workout_text_view&quot;
android:layout_width=&quot;0dp&quot;
android:layout_height=&quot;wrap_content&quot;
android:layout_weight=&quot;1&quot; /&gt;
&lt;/LinearLayout&gt;

Every time I run this, the app crashes, as there is a fatal exception where I'm trying to Inflate the custom layout:

> "java.lang.ClassCastException: android.widget.LinearLayout cannot be cast to android.widget.TextView"

I'm having trouble understanding what's going on, as I'm simply following tutorials online.
If anybody could help me out, that would be greatly appreciated.

答案1

得分: 2

当你执行inflater.inflate(R.layout.workout_item, parent, false)时,你正在膨胀(inflate)你的XML文件的整个布局。该XML文件的最顶层元素是一个LinearLayout,因此返回的膨胀布局是一个LinearLayout,而不是一个TextView

你有两个选项:

  1. 完全移除LinearLayout。

这意味着你的布局将仅包含单个TextView,这将使你的强制转换成功。

<?xml version="1.0" encoding="utf-8"?>
<TextView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/workout_text_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingTop="10dp"
    android:paddingBottom="10dp"
/>
  1. 更新你的ViewHolder以包含整个布局。

在这种情况下,你需要更新你的WorkoutActivityAdapter.MyViewHolder,以包含整个布局,并使用view.findViewById(R.id.workout_text_view)来从布局中获取TextView。这将适用于你的布局中有多个视图的情况。

英文:

When you do inflater.inflate(R.layout.workout_item, parent, false), you are inflating the full layout of your XML file. The topmost element of that XML file is a LinearLayout, so the returned inflated layout is a LinearLayout, not a TextView.

You have two options:

  1. Remove the LinearLayout entirely.

This would mean your layout would only contain your single TextView, which would make your casting succeed.

&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;TextView
xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
android:id=&quot;@+id/workout_text_view&quot;
android:layout_width=&quot;match_parent&quot;
android:layout_height=&quot;wrap_content&quot;
android:paddingTop=&quot;10dp&quot;
android:paddingBottom=&quot;10dp&quot;
/&gt;
  1. Update your ViewHolder to take the full layout.

Here you'd update your WorkoutActivityAdapter.MyViewHolder to take the full layout and use view.findViewById(R.id.workout_text_view) to get the TextView out of your layout. This would be appropriate if you had more than one view in your layout.

答案2

得分: 1

问题出在 onCreateViewHolder 方法上。

你正在使用:

TextView contactView = (TextView) inflater.inflate(R.layout.workout_item, parent, false);

但是 workout_item 布局的根视图是一个 LinearLayout,你不能将 LinearLayout 强制转换为 TextView

可以使用以下代码替代:

@Override
public WorkoutActivityAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    Context context = parent.getContext();
    LayoutInflater inflater = LayoutInflater.from(context);

    // Inflate the custom layout
    View view = inflater.inflate(R.layout.workout_item, parent, false);

    // Return a new holder instance
    WorkoutActivityAdapter.MyViewHolder viewHolder = new WorkoutActivityAdapter.MyViewHolder(view);
    return viewHolder;
}

以及:

public static class MyViewHolder extends RecyclerView.ViewHolder {
    public TextView textView;
    public MyViewHolder (View v) {
        super(v);
        textView = (TextView) v.findViewById(R.id.workout_text_view);
    }
}
英文:

The issue is on the onCreateViewHolder method.

You are using

TextView contactView = (TextView) inflater.inflate(R.layout.workout_item, parent, false);

but the root view of the workout_item layout is a LinearLayout and you can not cast a LinearLayout to a TextView.

Use something:

    @Override
public WorkoutActivityAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Context context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
// Inflate the custom layout
View view = inflater.inflate(R.layout.workout_item, parent, false);
// Return a new holder instance
WorkoutActivityAdapter.MyViewHolder viewHolder = new WorkoutActivityAdapter.MyViewHolder(view);
return viewHolder;
}

and:

public static class MyViewHolder extends RecyclerView.ViewHolder {
public TextView textView;
public MyViewHolder (View v) {
super(v);
textView = (TextView) v.findViewById(R.id.workout_text_view);
}
}

huangapple
  • 本文由 发表于 2020年8月4日 07:09:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/63238120.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定