为 YouTube 频道和使用 YouTube 查询重新 RecyclerView API (Android)

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

如果有人可以提供帮助,我正在寻求帮助。我遵循了有关如何为 YouTube 注册 API 密钥、在应用程序上创建 RecyclerView 然后使用 JSON 从 YouTube 频道解析信息的指南(在 YouTube 上非常有趣!)为了将该频道的视频和标题附加到 RecylerView。唯一的问题是,每当我在模拟器上启动应用程序时,RecyclerView 都是空白的;它不会在 LogCat 上抛出错误,甚至不会通过任何响应来识别它。任何人都可以看看我的代码,看看他们是否能发现我可能出错的地方吗?这将对我有很大帮助,我将不胜感激。谢谢!

Activity代码:

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

}

}

模型代码:

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

}

适配器代码:

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的:

MainActivity 布局包括带有 RecyclerView 的 ConstraintLayout 和其他布局 'listitem' 包括用于视频缩略图的 ImageView 和用于标题的 TextView。

由于以下错误,RecyclerView 为空白:

1.You 正在解析 JSON 中不存在的 Snippet 属性,将其更改为 snippet,如下所示:

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

2.You 将视频 ID 设置为:md.setVideoId(jsonvideoid.getString("videoId")); 但并非所有项目都具有 videoId 属性,因为其中一些不是视频而是播放列表,因此您必须获取在这种情况下播放列表。要将视频与播放列表区分开来,您可以使用 kind 属性并使用它来获取正确的 ID。示例如下:

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

列表项示例 xml 可以如下所示:

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