Android 如何修复Recyclerview返回相同的项目
我检查了很多问题来解决我的问题,但没有成功。这将为我解决3个问题,一个大问题 我正在使用Gson和改型解析我的YouTube视频,它成功地显示了,但在最后的结果之后,它一遍又一遍地返回相同的项目 在这里,我调用用于解析视频的函数Android 如何修复Recyclerview返回相同的项目,android,android-studio,Android,Android Studio,我检查了很多问题来解决我的问题,但没有成功。这将为我解决3个问题,一个大问题 我正在使用Gson和改型解析我的YouTube视频,它成功地显示了,但在最后的结果之后,它一遍又一遍地返回相同的项目 在这里,我调用用于解析视频的函数 // NestedScrollView used instead of using // RecyclerView as NestedScrollView disables // scroll listeners of recycler so, we use neste
// NestedScrollView used instead of using
// RecyclerView as NestedScrollView disables
// scroll listeners of recycler so, we use nested.
NestedScrollView nestedScrollView = findViewById(R.id.nested_scrollview);
nestedScrollView.setOnScrollChangeListener((NestedScrollView.OnScrollChangeListener) (v, scrollX, scrollY, oldScrollX, oldScrollY) -> {
if ((scrollY >= (v.getChildAt(v.getChildCount() - 1).getMeasuredHeight() - v.getMeasuredHeight())) && scrollY > oldScrollY) {
getJson();
}
});
if (videoList.size() == 0) {
getJson();
}
}
这是我的getJson,它解析我的视频
// Get Json Data
private void getJson() {
shimmer.setVisibility(View.VISIBLE);
// Parsed Url
String url = YoutubeAPI.BASE_URL + YoutubeAPI.SEARCH + YoutubeAPI.KEY + YoutubeAPI.CHANNNEL_ID + YoutubeAPI.ORDER + YoutubeAPI.MAX_RESULTS + YoutubeAPI.PART;
if (!nextPageToken.equals("")) {
// Add page token to new url
url += (YoutubeAPI.NEXT_PAGE_TOKEN + nextPageToken);
shimmer.setVisibility(View.GONE);
}
if (nextPageToken == null) {
return;
}
Call<YoutubeMain> data = YoutubeAPI.getMainVideo().getYoutube(url);
data.enqueue(new Callback<YoutubeMain>() {
@Override
public void onResponse(Call<YoutubeMain> call, Response<YoutubeMain> response) {
if (response.errorBody() != null) {
Log.v("TAG", "onResponse: " + response.errorBody());
shimmer.setVisibility(View.GONE);
// Print error code
Toast.makeText(YoutubeActivity.this, response.errorBody().toString(), Toast.LENGTH_SHORT).show();
} else {
YoutubeMain youtubeMain = response.body();
assert youtubeMain != null;
videoList.addAll(youtubeMain.getItems());
adapter.notifyDataSetChanged();
shimmer.setVisibility(View.GONE);
// Get nextPageToken to assign it to new url
if (youtubeMain.getNextPageToken() != null) {
nextPageToken = youtubeMain.getNextPageToken();
}
// Get creatorName to assign it to author
if (youtubeMain.getItems().get(0).getSnippet().getChannelTitle() != null) {
author.setText(youtubeMain.getItems().get(0).getSnippet().getChannelTitle());
}
}
}
@Override
public void onFailure(Call<YoutubeMain> call, Throwable t) {
shimmer.setVisibility(View.GONE);
// Print error code
Toast.makeText(YoutubeActivity.this, t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
//获取Json数据
私有void getJson(){
微光设置可见性(视图可见);
//解析Url
字符串url=YoutubeAPI.BASE\u url+YoutubeAPI.SEARCH+YoutubeAPI.KEY+YoutubeAPI.channel\u ID+YoutubeAPI.ORDER+YoutubeAPI.MAX\u RESULTS+YoutubeAPI.PART;
如果(!nextPageToken.equals(“”){
//将页面标记添加到新url
url+=(YoutubeAPI.NEXT_PAGE_TOKEN+nextPageToken);
微光。设置可见性(视图。消失);
}
if(nextPageToken==null){
返回;
}
Call data=YoutubeAPI.getMainVideo().getYoutube(url);
data.enqueue(新回调(){
@凌驾
公共void onResponse(调用、响应){
if(response.errorBody()!=null){
Log.v(“TAG”,“onResponse:+response.errorBody());
微光。设置可见性(视图。消失);
//打印错误代码
Toast.makeText(YoutubeActivity.this,response.errorBody().toString(),Toast.LENGTH_SHORT.show();
}否则{
YoutubeMain YoutubeMain=response.body();
断言youtubeMain!=null;
videoList.addAll(youtubeMain.getItems());
adapter.notifyDataSetChanged();
微光。设置可见性(视图。消失);
//让nextPageToken将其分配给新url
if(youtubeMain.getNextPageToken()!=null){
nextPageToken=youtubeMain.getNextPageToken();
}
//获取creatorName以将其分配给作者
if(youtubeMain.getItems().get(0.getSnippet().getChannelTitle()!=null){
author.setText(youtubeMain.getItems().get(0.getSnippet().getChannelTitle());
}
}
}
@凌驾
失败时公共无效(调用调用,可丢弃的t){
微光。设置可见性(视图。消失);
//打印错误代码
Toast.makeText(YoutubeActivity.this,t.getMessage(),Toast.LENGTH_SHORT.show();
}
});
}
这是我的适配器
public class YoutubeMainAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<YoutubeVideo> videoList;
private final OnYoutubeItemClickListener listener;
private String formatted_date;
public YoutubeMainAdapter(Context context, List<YoutubeVideo> videoList, OnYoutubeItemClickListener listener) {
this.videoList = videoList;
this.listener = listener;
}
class YoutubeHolder extends RecyclerView.ViewHolder {
ImageView thumbnail;
TextView title, description, publishedAt;
YoutubeHolder(@NonNull View itemView) {
super(itemView);
thumbnail = itemView.findViewById(R.id.ImageThumb);
title = itemView.findViewById(R.id.textViewTitle);
description = itemView.findViewById(R.id.textViewDes);
publishedAt = itemView.findViewById(R.id.textViewDate);
}
public void setData(YoutubeVideo data) {
String getTitle = data.getSnippet().getTitle();
String getDescription = data.getSnippet().getDescription();
String getPublishedAt = format_date(data.getSnippet().getPublishedAt());
String getThumbnail = data.getSnippet().getThumbnails().getHigh().getUrl();
title.setText(getTitle);
description.setText(getDescription);
publishedAt.setText(getPublishedAt);
Picasso.get()
.load(getThumbnail)
.into(thumbnail);
}
void bind(final YoutubeVideo item, final OnYoutubeItemClickListener listener) {
itemView.setOnClickListener(v -> listener.onItemClick(item));
}
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.activity_youtube_listitem, parent, false);
return new YoutubeHolder(view);
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
YoutubeVideo youtubeVideo = videoList.get(position);
YoutubeHolder youtubeHolder = (YoutubeHolder) holder;
youtubeHolder.setData(youtubeVideo);
youtubeHolder.bind(videoList.get(position), listener);
}
private String format_date(String publishedAt) {
try {
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.getDefault());
@SuppressLint("SimpleDateFormat") SimpleDateFormat format = new SimpleDateFormat("dd, MMM yyyy • hh:mm a");
Date date = dateFormat.parse(publishedAt);
assert date != null;
formatted_date = format.format(date);
} catch (ParseException e) {
e.printStackTrace();
}
return formatted_date;
}
@Override
public int getItemCount() {
return videoList.size();
}
}
公共类YoutubeMainAdapter扩展了RecyclerView.Adapter{
私人列表视频列表;
私有最终OnYoutubeItemClickListener监听器;
私有字符串格式的\u日期;
public YoutubeMainAdapter(上下文上下文、列表视频列表、OnYoutubeItemClickListener侦听器){
this.videoList=视频列表;
this.listener=listener;
}
类YoutubeHolder扩展了RecyclerView.ViewHolder{
图像视图缩略图;
文本视图标题、描述、发布数据;
YoutubeHolder(@NonNull View itemView){
超级(项目视图);
缩略图=itemView.findViewById(R.id.ImageThumb);
title=itemView.findviewbyd(R.id.textViewTitle);
description=itemView.findviewbyd(R.id.textViewDes);
publishedAt=itemView.findviewbyd(R.id.textViewDate);
}
公共void setData(YoutubeVideo数据){
字符串getTitle=data.getSnippet().getTitle();
字符串getDescription=data.getSnippet().getDescription();
字符串getPublishedAt=格式\日期(data.getSnippet().getPublishedAt());
字符串getThumbnail=data.getSnippet().getThumbnails().getHigh().getUrl();
title.setText(getTitle);
description.setText(getDescription);
publishedAt.setText(getPublishedAt);
毕加索
.加载(缩略图)
.插入(缩略图);
}
无效绑定(最终YoutubeVideo项,最终OnYoutubeItemClickListener侦听器){
setOnClickListener(v->listener.onItemClick(item));
}
}
@非空
@凌驾
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup父级,int-viewType){
View View=LayoutInflater.from(parent.getContext()).flate(R.layout.activity\u youtube\u listitem,parent,false);
返回新的YoutubeHolder(视图);
}
@凌驾
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder,int位置){
YoutubeVideo YoutubeVideo=videoList.get(位置);
YoutubeHolder YoutubeHolder=(YoutubeHolder)持有人;
setData(youtubeVideo);
bind(videoList.get(position),listener);
}
私有字符串格式\u日期(字符串发布日期){
试一试{
DateFormat DateFormat=新的SimpleDataFormat(“yyyy-MM-dd'HH:MM:ss.SSS'Z',Locale.getDefault());
@SuppressLint(“SimpleDataFormat”)SimpleDataFormat格式=新的SimpleDataFormat(“dd,MMM yyyy•hh:mm a”);
Date-Date=dateFormat.parse(publishedAt);
断言日期!=null;
formatted_date=format.format(日期);
}捕获(解析异常){
e、 printStackTrace();
}
返回日期;
}
@凌驾
public int getItemCount(){
返回videoList.size();
}
}
我尝试了很多次来修复它,但都没有成功,在检查了一些与此问题相关的问题后,所有的答案都是for(for循环),带有常规的Json解析,没有Gson。提前感谢您的帮助。您的适配器是正确的 因为您注意到:
在上次结果之后,它会一次又一次地返回相同的项。
这是因为nextpGetOken
将在上次返回null
,并且如果(youtubeMain.getnextpGetOken()!=null)nextpGetOken=youtubeMain.getnextpGetOken(),您将保留上次引用代码>
哟