Ysera
Ysera

Reputation: 45

Recyclerview Adapter onCreateViewHolder method LinearLayout cannot be cast to 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<WorkoutActivityAdapter.MyViewHolder> {
    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:

<?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>

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.

Upvotes: 1

Views: 104

Answers (2)

ianhanniballake
ianhanniballake

Reputation: 200120

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.

<?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. 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.

Upvotes: 2

Gabriele Mariotti
Gabriele Mariotti

Reputation: 365008

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);
    }
}

Upvotes: 1

Related Questions