Reputation: 45
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
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:
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"
/>
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
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