androidandroid-studioandroid-recyclerviewandroid-adapterandroid-youtube-api

Query re RecyclerView for YouTube Channel & using YouTube API (Android)


I'm after some assistance please if anybody could help. I've followed a guide (funnily enough on YouTube!) concerning how to register for an API Key for YouTube, create a RecyclerView on an App and then parse info off of a YouTube Channel using JSON in order to attach the videos and titles from that channel to the RecylerView. Only issue is, whenever I go to launch the App on the Emulator, the RecyclerView is blank; it doesn't throw up an error on the LogCat or even so much as identify it with any response. Can anybody take a look at my code and see if they can spot where I might be going wrong please? It will be a big help for me and will be massively appreciated. Thank you!

Activity Code:

public class ThirdActivity extends AppCompatActivity {

RecyclerView recyclerView;
Adapter adapter;
ArrayList<Model> list = new ArrayList<>();

float x1, x2, y1, y2;

public boolean onTouchEvent(MotionEvent touchevent) {
    switch (touchevent.getAction()) {
        case MotionEvent.ACTION_DOWN:
            x1 = touchevent.getX();
            y1 = touchevent.getY();
            break;
        case MotionEvent.ACTION_UP:
            x2 = touchevent.getX();
            y2 = touchevent.getY();
            if (x1 < x2) {
                Intent i = new Intent(ThirdActivity.this, SecondActivity.class);
                startActivity(i);

                overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
                finish();

            }

                if (x2 < x1) {
                    Intent i = new Intent (ThirdActivity.this, FourthActivity.class);
                    startActivity(i);

                    overridePendingTransition(R.anim.fade_in,R.anim.fade_out);
                    finish();

                }

            break;
    }
    return false;
}

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

    recyclerView = findViewById(R.id.recyclerview);
    adapter = new Adapter(ThirdActivity.this,list);
    RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getApplicationContext());
    recyclerView.setLayoutManager(layoutManager);
    recyclerView.setAdapter(adapter);
    fetchdata();

    Button fab = findViewById(R.id.fab);

    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            Intent intent = new Intent();
            intent.setAction(Intent.ACTION_VIEW);
            intent.addCategory(Intent.CATEGORY_BROWSABLE);
            intent.setData(Uri.parse("https://www.youtube.com/channel/UCWzKMFfIlMzHUXKSnYot5HA"));
            startActivity(intent);

        }
    });

}

private void fetchdata(){

    RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
    StringRequest stringRequest = new StringRequest(Request.Method.GET, "https://www.googleapis.com/youtube/v3/search?part=snippet&channelId=UCWzKMFfIlMzHUXKSnYot5HA&maxResults=30&key=AIzaSyC3vmCtdyWWaPr5JLj_wO8_O3QPhDGClJc",

            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);
                    JSONObject jsonvideoid = jsonObject1.getJSONObject("id");
                    JSONObject jsonsnippet = jsonObject1.getJSONObject("Snippet");
                    JSONObject jsonthumbnail = jsonsnippet.getJSONObject("thumbnails").getJSONObject("medium");

                    Model md = new Model();

                    if (i != 1 && i != 2) {

                        md.setVideoId(jsonvideoid.getString("videoId"));
                        md.setTitle(jsonsnippet.getString("title"));
                        md.setUrl(jsonthumbnail.getString("url"));
                        list.add(md);

                    }

                }

                if (list.size() > 0) {

                    adapter.notifyDataSetChanged();

                }

            } catch (JSONException e) {
                e.printStackTrace();

            }
        }

            }, new Response.ErrorListener() {

        @Override
        public void onErrorResponse(VolleyError error) {
            Toast.makeText(ThirdActivity.this,"Error!",Toast.LENGTH_LONG).show();

        }

    });

    requestQueue.add(stringRequest);

}

}

Model Code:

public class Model {

public String videoId, title, url;

public Model(String videoId, String title, String url) {
    this.videoId = videoId;
    this.title = title;
    this.url = url;
}

public Model(){
}

public String getVideoId() {

    return videoId;
}

public void setVideoId(String videoId) {

    this.videoId = videoId;

}

public String getTitle() {

    return title;
}

public void setTitle(String title) {

    this.title = title;
}

public String getUrl() {

    return url;
}

public void setUrl(String url) {

    this.url = url;
}

}

Adapter Code:

public class Adapter extends RecyclerView.Adapter<Adapter.MyViewHolder> {

Context context;
ArrayList<Model> list;

public Adapter(Context context, ArrayList<Model> model){
    this.context = context;
    this.list = model;

}

@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

    View itemview = LayoutInflater.from(parent.getContext()).inflate(R.layout.listitem,parent,false);

    return new MyViewHolder(itemview);

}

@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
    final Model model = list.get(position);
    holder.textView.setText(model.getTitle());
    Picasso.get().load(model.getUrl()).into(holder.imageView);

}

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

}

public class MyViewHolder extends RecyclerView.ViewHolder{

    public ImageView imageView;
    public TextView textView;

    public MyViewHolder(@NonNull View itemView) {
        super(itemView);
        imageView = itemView.findViewById(R.id.imageView);
        textView = itemView.findViewById(R.id.title);

    }
}

}

XML's:

MainActivity Layout includes a ConstraintLayout with the RecyclerView & other Layout 'listitem' includes the ImageView for the video thumbnails and TextView for the titles.


Solution

  • The RecyclerView is blank due to the below errors:

    1.You are parsing a Snippet attribute which does not exists in JSON, change it to snippet like the below:

    JSONObject jsonsnippet = jsonObject1.getJSONObject("snippet");
    

    2.You are settting the video Id like: md.setVideoId(jsonvideoid.getString("videoId")); but not all the items have the videoId attribute because some of them are not videos but playlists so you have to get the playlistId in that case. To distinguish the video from the playlist you can use the kind attribute and use it to get the correct Id. An example is like the below:

    Model md = new Model();
    String kind = jsonvideoid.optString("kind", "");
    switch (kind){
        case "youtube#video":
            md.setVideoId(jsonvideoid.getString("videoId")); //here you have a video ID
            break;
        case "youtube#playlist":
            md.setVideoId(jsonvideoid.getString("playlistId")); //here you have a playlistId ID (its better to have something like md.setPlayListId() here)
            break;
    }
    md.setTitle(jsonsnippet.getString("title"));
    md.setUrl(jsonthumbnail.getString("url"));
    list.add(md);
    

    Sample of the list item xml can be like the below:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    
        <ImageView
            android:id="@+id/imageView"
            android:layout_width="100dp"
            android:layout_height="100dp"/>
    
        <TextView
            android:id="@+id/title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_toEndOf="@+id/imageView"
            android:layout_centerVertical="true"
            android:layout_marginStart="10dp"
            android:layout_marginEnd="10dp"
            tools:text="Title"/>
    
    </RelativeLayout>