ImageButton in RecyclerView

Viewed 249

I'm pretty new to Android Studio and I'm having some issues with the ImageButton in my RecyclerViews. My RecyclerView contains an item along with the ImageButton. The item which is a TextView leads to another activity when you click on it. I want the ImageButton to do the same thing but I didn't figure out yet how to do so.

I tried this code in my MainActivity but it makes the app to crash whenever I excecute it:

    ImageButton button = (ImageButton) findViewById(R.id.btn_piechart);
        button.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v){
                Intent intent = new Intent(MainActivity.this, ResultatsActivity.class);
                startActivity(intent);
            }
        });

Here is the error message:

    Attempt to invoke virtual method 'void android.widget.ImageButton.setOnClickListener(android.view.View$OnClickListener)' on a null object reference

Here is the XML of my item view:

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

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


    <ImageButton
        android:id="@+id/btn_piechart"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:srcCompat="@drawable/ic_baseline_pie_chart_24" />



</LinearLayout>

Here is the XML of my main activity:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <Button
            android:layout_width="match_parent"
            android:layout_margin="20dp"
            android:layout_height="50dp"
            android:text="Ajouter"
            android:id="@+id/btnAjouter" />
    </LinearLayout>

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"

        />

</LinearLayout>

Here is my adapter:

    public class QuestionAdapter extends RecyclerView.Adapter<QuestionAdapter.MyViewHolder> {
        public List<Question> list;
        private MyViewHolder.OnQuestionListener mOnQuestionListener;
    
        public static class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
            
            public TextView tvNom;
            OnQuestionListener onQuestionListener;        
    
    
            public MyViewHolder(LinearLayout v, OnQuestionListener onQuestionListener) {
                super(v);
                tvNom = v.findViewById(R.id.tvNom);
                this.onQuestionListener = onQuestionListener;           
                itemView.setOnClickListener(this);
                
            }
    
            @Override
            public void onClick(View view) {
                onQuestionListener.onQuestionClick(getAdapterPosition());
    
            }
    
            public interface OnQuestionListener{
                void onQuestionClick(int position);
            }
        }
    
        
        public QuestionAdapter(MyViewHolder.OnQuestionListener onQuestionListener) {
            list = new ArrayList<>();
            this.mOnQuestionListener = onQuestionListener;
    
        }
    
        
        @Override
        public QuestionAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent,
                                                               int viewType) {
            
            LinearLayout v = (LinearLayout) LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.question_item, parent, false);
            MyViewHolder vh = new MyViewHolder(v, mOnQuestionListener);
    
    
            return vh;
        }
    
        // Replace the contents of a view (invoked by the layout manager)
        @Override
        public void onBindViewHolder(MyViewHolder holder, int position) {       
            Question QuestionCourante = list.get(position);
            holder.tvNom.setText(QuestionCourante.nom);
        }
        @Override
        public int getItemCount() {
            return list.size();
        }

}

Thank you for your helps.

1 Answers

Your issue is quite simple. you are failung to reference your imageButton in the adapter. where exactly did you place the code that is causing the exception? your adapter basically needs you to tell it which view in your adapter layout is the imageButton. here the code with the correction

 public class QuestionAdapter extends RecyclerView.Adapter<QuestionAdapter.MyViewHolder> {
        public List<Question> list;
        private MyViewHolder.OnQuestionListener mOnQuestionListener;
    
        public static class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
            
            public TextView tvNom;
            ImageButton imageButtom;
            OnQuestionListener onQuestionListener;        
    
    
            public MyViewHolder(LinearLayout v, OnQuestionListener onQuestionListener) {
                super(v);
                tvNom = v.findViewById(R.id.tvNom);
                this.onQuestionListener = onQuestionListener;           
                itemView.setOnClickListener(this);
                imagebutton= (ImageButton) findViewById(R.id.btn_piechart);
                
            }
    
            @Override
            public void onClick(View view) {
                onQuestionListener.onQuestionClick(getAdapterPosition());
    
            }
    
            public interface OnQuestionListener{
                void onQuestionClick(int position);
            }
        }
    
        
        public QuestionAdapter(MyViewHolder.OnQuestionListener onQuestionListener) {
            list = new ArrayList<>();
            this.mOnQuestionListener = onQuestionListener;
    
        }
    
        
        @Override
        public QuestionAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent,
                                                               int viewType) {
            
            LinearLayout v = (LinearLayout) LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.question_item, parent, false);
            MyViewHolder vh = new MyViewHolder(v, mOnQuestionListener);
    
    
            return vh;
        }
    
        // Replace the contents of a view (invoked by the layout manager)
        @Override
        public void onBindViewHolder(MyViewHolder holder, int position) {       
            Question QuestionCourante = list.get(position);
            holder.tvNom.setText(QuestionCourante.nom);
            holder.imageButton.setOnClickListener(new View.OnClickListener(){
                @Override
                public void onClick(View v){
                Intent intent = new Intent(MainActivity.this, ResultatsActivity.class);
                holder.imageButton.getContext()startActivity(intent);
            }
        });
        }
        @Override
        public int getItemCount() {
            return list.size();
        }

}

please note how I added the view in your viewHolder and in the OnBindViewHolder method

The following code does NOT belong in MainActivity, just delete it from there:

ImageButton button = (ImageButton) findViewById(R.id.btn_piechart);
        button.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v){
                Intent intent = new Intent(MainActivity.this, ResultatsActivity.class);
                startActivity(intent);
            }
        });
Related