0

I am using 2 activities (Main and VideoPlayActivity).it shows a recycler view and when clicked on any item the app stop working.

I am trying to create an intent for onCLickItem to run a new activity I am getting this error

2020-09-06 09:48:56.601 15956-15956/? E/Zygote: isWhitelistProcess - Process is Whitelisted
2020-09-06 09:48:58.827 15956-15956/com.currentmedia.channel E/RecyclerView: No adapter attached; skipping layout
2020-09-06 09:49:10.757 15956-15956/com.currentmedia.channel E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.currentmedia.channel, PID: 15956
    java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.currentmedia.channel.VideoDetails.getVideoId()' on a null object reference
        at com.currentmedia.channel.adapter$1.onClick(adapter.java:54)
        at android.view.View.performClick(View.java:6935)
        at android.view.View$PerformClick.run(View.java:26214)
        at android.os.Handler.handleCallback(Handler.java:790)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:7025)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:441)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1408)

my adatper class is like this

public class adapter extends RecyclerView.Adapter<adapter.ViewHolder> {
    LayoutInflater inflater;
    ArrayList<VideoDetails> videoDetailsArrayList;
    Context ctx;
    VideoDetails videoDetails;
    RecyclerView recyclerView;


//Constructor for adaptor
    public adapter(Context ctx, ArrayList<VideoDetails> videoDetailsArrayList)
    {
        this.videoDetailsArrayList=videoDetailsArrayList;
        //this.videoDetails=videoDetails;
        this.ctx=ctx;
        this.inflater=LayoutInflater.from(ctx);

    }


    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view=inflater.inflate(R.layout.custom_layout,parent,false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        holder.textView.setText(videoDetailsArrayList.get(position).getTitle());
        holder.imageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent i=new Intent(ctx, VideoPlayActivity.class);
                i.putExtra("videoId", videoDetails.getVideoId());
                ctx.startActivity(i);
            }
        });
        final VideoDetails videoDetails=(VideoDetails)
                this.videoDetailsArrayList.get(position);

       // final VideoDetails videoDetails=(VideoDetails) this.videoDetailsArrayList.get(position);

        Picasso.get().load(videoDetails.getUrl()).into(holder.imageView);


    }

    @Override
    public int getItemCount()                                                                                                                           {
        return videoDetailsArrayList.size();
    }

    public static class ViewHolder extends RecyclerView.ViewHolder {
        TextView textView;
        ImageView imageView;

        public ViewHolder(View itemView) {
            super(itemView);
            textView=itemView.findViewById(R.id.mytitle);
            imageView=itemView.findViewById(R.id.imageView);
            

                }

        }
    }

My MAinActivity is as follows

public class MainActivity extends AppCompatActivity {
        RecyclerView recyclerView;
        ArrayList<VideoDetails> videoDetailsoArrayList;
    String API_Key = "";
    String url="https://www.googleapis.com/youtube/v3/search?part=snippet&channelId=UCVMWWQ985A_-SESZUy_SsVQ&maxResults=50&key=";
    adapter adapter;
    Context ctx;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        recyclerView=findViewById(R.id.listView);
        videoDetailsoArrayList= new ArrayList<>();
        adapter=new adapter(MainActivity.this,videoDetailsoArrayList);

        displayVideos();

    }


    private void displayVideos ()
    {
        RequestQueue requestQueue= Volley.newRequestQueue(this);
        StringRequest stringRequest=new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {


            @Override
            public void onResponse(String response) {
                    try {
                        JSONObject jsonObject = new JSONObject(response);
                        JSONArray jsonArray = jsonObject.getJSONArray("items");
                        for (int i = 0; i < jsonArray.length(); i++) {
                            JSONObject jsonObject1 = jsonArray.getJSONObject(i);
                            if (jsonObject1.has("id")){
                                JSONObject jsonVideoId=jsonObject1.getJSONObject("id");
                                if (jsonVideoId.has("kind")){
                                    if(jsonVideoId.getString("kind").equals("youtube#video")){
                                        JSONObject jsonObjectSnippet = jsonObject1.getJSONObject("snippet");
                                        JSONObject jsonObjectDefault=jsonObjectSnippet.getJSONObject("thumbnails").getJSONObject("medium");

                                        String video_id=jsonVideoId.getString("videoId");

                                        VideoDetails vd=new VideoDetails();

                                        vd.setVideoId(video_id);
                                        vd.setTitle(jsonObjectSnippet.getString("title"));
                                        vd.setDescription(jsonObjectSnippet.getString("description"));
                                        vd.setUrl(jsonObjectDefault.getString("url"));

                                        videoDetailsoArrayList.add(vd);
                                    }
                                  //  recyclerView.setAdapter(adapter);
                                   // adapter.notifyDataSetChanged();
                                }
                            }
                        }
                    }catch (JSONException e) {
                        e.printStackTrace();
                    }

                recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
                    adapter= new adapter(getApplicationContext(),videoDetailsoArrayList);
                recyclerView.setAdapter(adapter);
                           }

            }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Toast.makeText(getApplicationContext(),error.getMessage(), LENGTH_LONG).show();
            }
        });
        requestQueue.add(stringRequest);
         }
}

I have tried the stackover solutions No adapter attached; skipping layout : RecyclerView , No adapter attach,skipping layout , Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName() on getActivity() , I have also applied the NPE declaration method in the adapter constructor ctx=ctx

summyia haris
  • 121
  • 1
  • 15

1 Answers1

1

Your Viewholder.ctx does not have context reference in that object hence the error, we don't set the onClickListener in ViewHolder class, look at the below.

public class adapter extends RecyclerView.Adapter<adapter.ViewHolder> {
LayoutInflater inflater;
ArrayList<VideoDetails> videoDetailsArrayList;
Context ctx;
VideoDetails videoDetails;
RecyclerView recyclerView;


//Constructor for adaptor
public adapter(Context ctx, ArrayList<VideoDetails> videoDetailsArrayList)
{
    this.inflater=LayoutInflater.from(ctx);
    this.videoDetailsArrayList=videoDetailsArrayList;
    this.videoDetails=videoDetails;
}


@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view=inflater.inflate(R.layout.custom_layout,parent,false);
    return new ViewHolder(view);
}

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    holder.textView.setText(videoDetailsArrayList.get(position).getTitle());
    holder.imageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent i=new Intent(ctx, VideoPlayActivity.class);
                i.putExtra("videoId", videoDetails.getVideoId());
                ctx.startActivity(i);
            }
            });
    final VideoDetails videoDetails=(VideoDetails) 
   this.videoDetailsArrayList.get(position);

    Picasso.get().load(videoDetails.getUrl()).into(holder.imageView);
}

@Override
public int getItemCount() {
    return videoDetailsArrayList.size();
}

public class ViewHolder extends RecyclerView.ViewHolder {
    TextView textView;
    ImageView imageView;
    Context ctx;

    public ViewHolder(View itemView) {
        super(itemView);
        textView=itemView.findViewById(R.id.mytitle);
        imageView=itemView.findViewById(R.id.imageView);
       }
    }
  }

By this, you dont need to pass context to ViewHolder as Context ctx reference is already there in Adapter class.

Harish Rn
  • 98
  • 1
  • 9
  • I tried this but same error.on clicking image the app crashes – summyia haris Sep 05 '20 at 20:53
  • 1
    My bad, you are not assigning ctx in adapter's constructor. Make sure you do this.ctx=ctx. Please google on coding guidelines for Java and follow it. :) – Harish Rn Sep 05 '20 at 22:02
  • I have edited the question with your given suggestion and included my MainActivity but the results are same. – summyia haris Sep 06 '20 at 04:29
  • 1
    final VideoDetails videoDetails=(VideoDetails) this.videoDetailsArrayList.get(position); but be above the placed above onClickListener. Please remove api keys, you dont want others using it. – Harish Rn Sep 06 '20 at 07:13
  • how can I add click activity on both image and text? when I shift picasso below ```holder.textView.setText(videoDetailsArrayList.get(position).getTitle());``` and apply setOnClickListener on holder then app crashes @HarishRn – summyia haris Sep 06 '20 at 17:20