为 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>
如果有人可以提供帮助,我正在寻求帮助。我遵循了有关如何为 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>