滚动到下一页时单击时出错
Getting Error On Click When Scrolled To Next Page
我已成功获取 posts,在前 10 posts,我也获取了 post 内容,但是当我向下滚动以加载更多 posts 时,我也可以看到带有特色图片的 posts,但是当我点击那些 posts 时,我得到了这个错误:现在距离我找到答案已经超过 2 周了,请帮助
Caused by: java.lang.IndexOutOfBoundsException: Index: 11, Size: 10
at java.util.ArrayList.get(ArrayList.java:437)
at com.punjabidharti.myapplication.PostDetails.onCreate(PostDetails.java:30)
这是我的帖子详情activity:
Intent i = getIntent();
int position = i.getExtras().getInt("itemPosition");
Log.e("PostDetails ", "title is " + MainActivity.mListPost.get(position).getTitle().getRendered());
this.title = (TextView) findViewById(R.id.title);
title.setText(Html.fromHtml(MainActivity.mListPost.get(position).getTitle().getRendered()));
String data = String.valueOf((Html.fromHtml(MainActivity.mListPost.get(position).getContent().getRendered())));
WebView webview = (WebView)this.findViewById(R.id.postwebview);
webview.getSettings().setJavaScriptEnabled(true);
webview.loadData(data, "text/html; charset=utf-8", "UTF-8");
这是适配器:
private ArrayList<Model> dataset;
private Context mContext;
int total_types;
public RecyclerViewAdapter(ArrayList<Model> mlist, Context context) {
this.dataset = mlist;
this.mContext = context;
total_types = dataset.size();
}
@Override
public int getItemCount() {
return dataset.size();
}
public static class ImageTypeViewHolder extends RecyclerView.ViewHolder{
TextView title, subtitle;
ImageView imageView;
public ImageTypeViewHolder(View itemView) {
super(itemView);
this.title = (TextView) itemView.findViewById(R.id.title);
this.subtitle = (TextView) itemView.findViewById(R.id.subtitle);
//at the moment, it is displaying an icon for all posts
this.imageView = (ImageView) itemView.findViewById(R.id.Icon);
}
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from( parent.getContext()).inflate(R.layout.postdetails, parent, false);
return new ImageTypeViewHolder(view) ;
}
@Override
public int getItemViewType(int position) {
return position;
}
@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
final Model object = dataset.get(position);
( (ImageTypeViewHolder) holder).title.setText( object.title );
( (ImageTypeViewHolder) holder).subtitle.setText( object.subtitle );
Glide.with(mContext)
.load(object.Image)
.dontAnimate()
.placeholder(R.drawable.icon)
.into(((ImageTypeViewHolder) holder).imageView);
( (ImageTypeViewHolder) holder).title.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(mContext, PostDetails.class);
intent.putExtra("itemPosition", position);
mContext.startActivity(intent);
}
});
( (ImageTypeViewHolder) holder).subtitle.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(mContext, PostDetails.class);
intent.putExtra("itemPosition", position);
mContext.startActivity(intent);
}
});
( (ImageTypeViewHolder) holder).imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(mContext, PostDetails.class);
intent.putExtra("itemPosition", position);
mContext.startActivity(intent);
}
});
/// dataset.get(position)
}
@Override
public long getItemId(int position) {
return position;
}
这是我的 MainActivity:
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
progressBar = (ProgressBar) findViewById(R.id.progressbar);
mLayoutManager = new LinearLayoutManager(MainActivity.this, LinearLayoutManager.VERTICAL, false);
recyclerView.setLayoutManager(mLayoutManager);
list = new ArrayList<Model>();
getRetrofit();
adapter = new RecyclerViewAdapter( list, MainActivity.this);
recyclerView.setAdapter(adapter);
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
if (dy > 0) { //check for scroll down
visibleItemCount = mLayoutManager.getChildCount();
totalItemCount = mLayoutManager.getItemCount();
pastVisiblesItems = mLayoutManager.findFirstVisibleItemPosition();
if (loading) {
if ((visibleItemCount + pastVisiblesItems) >= totalItemCount) {
loading = false;
Log.v("...", "Last Item Wow !");
// Do pagination.. i.e. fetch new data
getRetrofit();
adapter = new RecyclerViewAdapter( list, MainActivity.this);
recyclerView.setAdapter(adapter);
}
}
}
}
});
这是我在 mainactivity 中的改造:
public void getRetrofit(){
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseURL)
.addConverterFactory(GsonConverterFactory.create())
.build();
RetrofitArrayApi service = retrofit.create(RetrofitArrayApi.class);
String yourURl = yourURL.replace(baseURL,"");
Call<List<WPPost>> call = service.getPostInfo( yourURl);
call.enqueue(new Callback<List<WPPost>>() {
@Override
public void onResponse(Call<List<WPPost>> call, Response<List<WPPost>> response) {
Log.e("mainactivyt", " response "+ response.body());
mListPost = response.body();
progressBar.setVisibility(View.GONE);
if (response.body() != null) {
for (int i = 0; i < response.body().size(); i++ ) {
Log.e("size", list.size() + "");
System.out.println("The shortest word i is:" + i );
Log.e("main ", " title " + response.body().get(i).getTitle().getRendered() + " " +
response.body().get(i).getId());
String tempdetails = response.body().get(i).getExcerpt().getRendered().toString();
tempdetails = tempdetails.replace("<p>", "");
tempdetails = tempdetails.replace("</p>", "");
tempdetails = tempdetails.replace("[…]", "");
list.add(new Model(Model.IMAGE_TYPE, response.body().get(i).getTitle().getRendered(),
tempdetails,
response.body().get(i).getImages().getMedium()));
adapter.notifyDataSetChanged();
}
progressBar.setVisibility(View.GONE);
} else {
progressBar.setVisibility(View.GONE);
}
}
@Override
public void onFailure(Call<List<WPPost>> call, Throwable t) {
}
});
}
最后:
public static List<WPPost> getList(){
return mListPost;
}
请帮忙,我找到答案已经两周多了,拜托
我也试过这个方法:
还有这个What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?
我想问题出在您的 MainActivity 上,您在其中尝试使用
获取列表项
Log.e("PostDetails ", "title is " + MainActivity.mListPost.get(position).getTitle().getRendered());
在这种情况下,每次调用 Retrofit 时,您的 mList 都会刷新,这意味着,您的 RecyclerView 列表可能包含 10 个以上的元素,但您的列表将始终包含 10 个元素。因此,在您的情况下,当您单击列表的第 12 个(甚至可能是第 11 个)项时会发生崩溃,这是因为您的列表始终包含 10 个最近使用改造获取的项目。
要解决这个问题,你不应该每次都重新分配你的列表,而应该将新项目添加到列表中,或者你可以在意图中发送完整的对象而不是仅仅传递项目位置,因为它是主题改变。
发生这种情况是因为 MainActivity.mListPost 只有最新的响应,在您的情况下通常是 10 件商品,因为您一次需要 10 件商品。
但是,如果您看到传递给适配器的列表随着每次新调用而增加,因为您在列表中使用“添加”。
因此,您的适配器将随着对下一页的每个新 API 调用而增长,但是您的 MainActivity.mListPost 只会获取最新的 10 个项目。
请确保像更新适配器列表一样更新您的 MainActivity.mListPost。
代码告诉您正在将点击项目位置传递给下一个 Activity 并使用来自上一个 activity 的这个位置访问模型对象,为什么不直接使用 bundle.putParcelable()
将对象传递给意图对象 ?
为什么要覆盖 getItemViewType(int position)
,因为您没有在 Adapter 中使用多视图类型?。在 getRetrofit()
方法中你调用了 adapter.notifyDataSetChanged();
虽然你没有完全替换你的列表,你只是将新项目添加到 list ,所以 notifyItemRangeInserted()
应该在这里使用。我制作了示例项目只是为了解决您的问题。让我们看看:-
public class RecyclerViewTestActivity extends AppCompatActivity {
private MyAdapter adapter;
private boolean loading = false;
int pastVisiblesItems, visibleItemCount, totalItemCount;
LinearLayoutManager mLayoutManager;
String baseURL = "https://my.backend.url";
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseURL)
.addConverterFactory(GsonConverterFactory.create())
.build();
RetrofitArrayApi service = retrofit.create(RetrofitArrayApi.class);
String yourURl = yourURL.replace(baseURL,"");
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recycler_view_test);
RecyclerView recyclerView = findViewById(R.id.recycler_view);
mLayoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(mLayoutManager);
adapter = new MyAdapter(new ArrayList<>());
recyclerView.setAdapter(adapter);
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
if (dy > 0) { //check for scroll down
visibleItemCount = mLayoutManager.getChildCount();
totalItemCount = mLayoutManager.getItemCount();
pastVisiblesItems = mLayoutManager.findFirstVisibleItemPosition();
if ((visibleItemCount + pastVisiblesItems) >= totalItemCount) {
Log.d("tisha==>>","Is loading = "+loading);
// Do pagination.. i.e. fetch new data
if (!loading){
adapter.showHideProgress(true);
loading = true;
getRetrofit();
}
}
}
}
});
getRetrofit();
}
void getRetrofit(){
// fetching data from remote server.....
try {
List<Model> list = new ArrayList<>();
Call<List<WPPost>> call = service.getPostInfo( yourURl);
call.enqueue(new Callback<List<WPPost>>() {
@Override
public void onResponse(Call<List<WPPost>> call, Response<List<WPPost>> response) {
Log.d("==>>", " response "+ response.body());
mListPost = response.body();
progressBar.setVisibility(View.GONE);
if (response.body() != null) {
for (int i = 0; i < response.body().size(); i++ ) {
Log.d("==>>", list.size() + "");
Log.d("==>>", " title " + response.body().get(i).getTitle().getRendered() + " " +
response.body().get(i).getId());
String tempdetails = response.body().get(i).getExcerpt().getRendered().toString();
tempdetails = tempdetails.replace("<p>", "");
tempdetails = tempdetails.replace("</p>", "");
tempdetails = tempdetails.replace("[…]", "");
list.add(new Model(Model.IMAGE_TYPE, response.body().get(i).getTitle().getRendered(),
tempdetails,
response.body().get(i).getImages().getMedium()));
}
if (loading){
loading = false;
adapter.showHideProgress(false);
}
adapter.addItemsToList(list);
progressBar.setVisibility(View.GONE);
} else {
progressBar.setVisibility(View.GONE);
}
}
@Override
public void onFailure(Call<List<WPPost>> call, Throwable t) {
}
});
}catch (Exception exception){
Log.d("tisha==>>"," "+exception.getLocalizedMessage());
}
}
// Customize Model Class as per your requirement-----------------
class Model implements Parcelable {
String title;
String subTitle;
String imageUrl;
Model(String title, String subTitle, String imageUrl){
this.title = title;
this.subTitle = subTitle;
this.imageUrl = imageUrl;
}
protected Model(Parcel in) {
title = in.readString();
subTitle = in.readString();
imageUrl = in.readString();
}
public static final Creator<Model> CREATOR = new Creator<Model>() {
@Override
public Model createFromParcel(Parcel in) {
return new Model(in);
}
@Override
public Model[] newArray(int size) {
return new Model[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(title);
dest.writeString(subTitle);
dest.writeString(imageUrl);
}
}
class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
List<Model> modelList;
int viewTypeData = 0,viewTypeProgress = 1;
MyAdapter(List<Model> list){
modelList = list;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
mContext = parent.getContext();
if (viewType == viewTypeData){
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_item_view,parent,false);
return new MyDataHolder(view);
}else {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_item_loading,parent,false);
return new MyProgressHolder(view);
}
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
Model model = modelList.get(position);
if (holder instanceof MyDataHolder){
((MyDataHolder)holder).showModel(model);
}else
((MyProgressHolder)holder).show();
}
@Override
public int getItemCount() {
return modelList.size();
}
@Override
public int getItemViewType(int position){
if (modelList.get(position).title.equals("progress"))
return viewTypeProgress;
else
return viewTypeData;
}
void showHideProgress(boolean shouldShowProgress){
if (shouldShowProgress){
modelList.add(new Model("progress","",""));
notifyItemInserted(modelList.size()-1);
}else {
Log.d("tisha==>>","Size before removal = "+modelList.size());
modelList.remove(modelList.size()-1);
notifyItemRemoved(modelList.size()-1);
Log.d("tisha==>>","Size after removal = "+modelList.size());
}
}
void addItemsToList(List<Model> newItems){
if (modelList.isEmpty()){
modelList.addAll(newItems);
notifyDataSetChanged();
Log.d("tisha==>>","First time List size = "+modelList.size());
}else {
int lastItemPosition = modelList.size() -1;
Log.d("tisha==>>","Old list size = "+modelList.size()+ "Last Item position= "+lastItemPosition);
modelList.addAll(newItems);
Log.d("tisha==>>","Update List size = "+modelList.size());
notifyItemRangeInserted(lastItemPosition,newItems.size());
}
}
static class MyDataHolder extends RecyclerView.ViewHolder{
TextView titleView,subTitleView;
ImageView imageView;LinearLayout rootView;
// Use Glide to load image to image view
public MyDataHolder(@NonNull View itemView) {
super(itemView);
titleView = itemView.findViewById(R.id.recycler_item_title_tv);
subTitleView =
itemView.findViewById(R.id.recycler_item_subtitle_tv);
imageView = itemView.findViewById(R.id.recycler_img_view);
rootView = itemView.findViewById(R.id.recycler_item_root_view);
rootView.setOnClickListener(v -> {
Bundle bundle = new Bundle();
bundle.putParcelable("my_key",modelList.get(getAdapterPosition()));
Intent intent = new Intent(mContext, DetialsActivity.class);
intent.putExtra("my_bundle",bundle);
mContext.startActivity(intent);
});
}
void showModel(Model model){
titleView.setText(model.title);
subTitleView.setText(model.subTitle);
}
}
static class MyProgressHolder extends RecyclerView.ViewHolder{
ProgressBar progressBar;
public MyProgressHolder(@NonNull View itemView) {
super(itemView);
progressBar = itemView.findViewById(R.id.recycler_item_progress);
}
void show(){
progressBar.setVisibility(View.VISIBLE);
}
}
}
recycler_item_view.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:id="@+id/recycler_item_root_view">
<ImageView
android:id="@+id/recycler_img_view"
android:layout_width="50dp"
android:layout_height="50dp"/>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_weight="1"
android:layout_gravity="center_vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/recycler_item_title_tv"
android:gravity="center">
</TextView>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/recycler_item_subtitle_tv"
android:gravity="start">
</TextView>
</LinearLayout>
recycler_item_loading.xml
<ProgressBar
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="50dp"
android:id="@+id/recycler_item_progress"
android:indeterminate="true">
在 NextActivity 中获取 Parcelable 模型 Class,如下所示。在 Target Activity 的 onCreate() 内部放置以下代码:
Bundle bundle = getIntent().getBundleExtra("my_bundle");
Model model = bundle.getParcelable("my_key");
if (model != null){
Log.d("tisha==>>","Title = "+model.title);
}
我已成功获取 posts,在前 10 posts,我也获取了 post 内容,但是当我向下滚动以加载更多 posts 时,我也可以看到带有特色图片的 posts,但是当我点击那些 posts 时,我得到了这个错误:现在距离我找到答案已经超过 2 周了,请帮助
Caused by: java.lang.IndexOutOfBoundsException: Index: 11, Size: 10
at java.util.ArrayList.get(ArrayList.java:437)
at com.punjabidharti.myapplication.PostDetails.onCreate(PostDetails.java:30)
这是我的帖子详情activity:
Intent i = getIntent();
int position = i.getExtras().getInt("itemPosition");
Log.e("PostDetails ", "title is " + MainActivity.mListPost.get(position).getTitle().getRendered());
this.title = (TextView) findViewById(R.id.title);
title.setText(Html.fromHtml(MainActivity.mListPost.get(position).getTitle().getRendered()));
String data = String.valueOf((Html.fromHtml(MainActivity.mListPost.get(position).getContent().getRendered())));
WebView webview = (WebView)this.findViewById(R.id.postwebview);
webview.getSettings().setJavaScriptEnabled(true);
webview.loadData(data, "text/html; charset=utf-8", "UTF-8");
这是适配器:
private ArrayList<Model> dataset;
private Context mContext;
int total_types;
public RecyclerViewAdapter(ArrayList<Model> mlist, Context context) {
this.dataset = mlist;
this.mContext = context;
total_types = dataset.size();
}
@Override
public int getItemCount() {
return dataset.size();
}
public static class ImageTypeViewHolder extends RecyclerView.ViewHolder{
TextView title, subtitle;
ImageView imageView;
public ImageTypeViewHolder(View itemView) {
super(itemView);
this.title = (TextView) itemView.findViewById(R.id.title);
this.subtitle = (TextView) itemView.findViewById(R.id.subtitle);
//at the moment, it is displaying an icon for all posts
this.imageView = (ImageView) itemView.findViewById(R.id.Icon);
}
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from( parent.getContext()).inflate(R.layout.postdetails, parent, false);
return new ImageTypeViewHolder(view) ;
}
@Override
public int getItemViewType(int position) {
return position;
}
@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
final Model object = dataset.get(position);
( (ImageTypeViewHolder) holder).title.setText( object.title );
( (ImageTypeViewHolder) holder).subtitle.setText( object.subtitle );
Glide.with(mContext)
.load(object.Image)
.dontAnimate()
.placeholder(R.drawable.icon)
.into(((ImageTypeViewHolder) holder).imageView);
( (ImageTypeViewHolder) holder).title.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(mContext, PostDetails.class);
intent.putExtra("itemPosition", position);
mContext.startActivity(intent);
}
});
( (ImageTypeViewHolder) holder).subtitle.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(mContext, PostDetails.class);
intent.putExtra("itemPosition", position);
mContext.startActivity(intent);
}
});
( (ImageTypeViewHolder) holder).imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(mContext, PostDetails.class);
intent.putExtra("itemPosition", position);
mContext.startActivity(intent);
}
});
/// dataset.get(position)
}
@Override
public long getItemId(int position) {
return position;
}
这是我的 MainActivity:
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
progressBar = (ProgressBar) findViewById(R.id.progressbar);
mLayoutManager = new LinearLayoutManager(MainActivity.this, LinearLayoutManager.VERTICAL, false);
recyclerView.setLayoutManager(mLayoutManager);
list = new ArrayList<Model>();
getRetrofit();
adapter = new RecyclerViewAdapter( list, MainActivity.this);
recyclerView.setAdapter(adapter);
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
if (dy > 0) { //check for scroll down
visibleItemCount = mLayoutManager.getChildCount();
totalItemCount = mLayoutManager.getItemCount();
pastVisiblesItems = mLayoutManager.findFirstVisibleItemPosition();
if (loading) {
if ((visibleItemCount + pastVisiblesItems) >= totalItemCount) {
loading = false;
Log.v("...", "Last Item Wow !");
// Do pagination.. i.e. fetch new data
getRetrofit();
adapter = new RecyclerViewAdapter( list, MainActivity.this);
recyclerView.setAdapter(adapter);
}
}
}
}
});
这是我在 mainactivity 中的改造:
public void getRetrofit(){
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseURL)
.addConverterFactory(GsonConverterFactory.create())
.build();
RetrofitArrayApi service = retrofit.create(RetrofitArrayApi.class);
String yourURl = yourURL.replace(baseURL,"");
Call<List<WPPost>> call = service.getPostInfo( yourURl);
call.enqueue(new Callback<List<WPPost>>() {
@Override
public void onResponse(Call<List<WPPost>> call, Response<List<WPPost>> response) {
Log.e("mainactivyt", " response "+ response.body());
mListPost = response.body();
progressBar.setVisibility(View.GONE);
if (response.body() != null) {
for (int i = 0; i < response.body().size(); i++ ) {
Log.e("size", list.size() + "");
System.out.println("The shortest word i is:" + i );
Log.e("main ", " title " + response.body().get(i).getTitle().getRendered() + " " +
response.body().get(i).getId());
String tempdetails = response.body().get(i).getExcerpt().getRendered().toString();
tempdetails = tempdetails.replace("<p>", "");
tempdetails = tempdetails.replace("</p>", "");
tempdetails = tempdetails.replace("[…]", "");
list.add(new Model(Model.IMAGE_TYPE, response.body().get(i).getTitle().getRendered(),
tempdetails,
response.body().get(i).getImages().getMedium()));
adapter.notifyDataSetChanged();
}
progressBar.setVisibility(View.GONE);
} else {
progressBar.setVisibility(View.GONE);
}
}
@Override
public void onFailure(Call<List<WPPost>> call, Throwable t) {
}
});
}
最后:
public static List<WPPost> getList(){
return mListPost;
}
请帮忙,我找到答案已经两周多了,拜托
我也试过这个方法:
还有这个What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?
我想问题出在您的 MainActivity 上,您在其中尝试使用
获取列表项Log.e("PostDetails ", "title is " + MainActivity.mListPost.get(position).getTitle().getRendered());
在这种情况下,每次调用 Retrofit 时,您的 mList 都会刷新,这意味着,您的 RecyclerView 列表可能包含 10 个以上的元素,但您的列表将始终包含 10 个元素。因此,在您的情况下,当您单击列表的第 12 个(甚至可能是第 11 个)项时会发生崩溃,这是因为您的列表始终包含 10 个最近使用改造获取的项目。
要解决这个问题,你不应该每次都重新分配你的列表,而应该将新项目添加到列表中,或者你可以在意图中发送完整的对象而不是仅仅传递项目位置,因为它是主题改变。
发生这种情况是因为 MainActivity.mListPost 只有最新的响应,在您的情况下通常是 10 件商品,因为您一次需要 10 件商品。 但是,如果您看到传递给适配器的列表随着每次新调用而增加,因为您在列表中使用“添加”。 因此,您的适配器将随着对下一页的每个新 API 调用而增长,但是您的 MainActivity.mListPost 只会获取最新的 10 个项目。 请确保像更新适配器列表一样更新您的 MainActivity.mListPost。
代码告诉您正在将点击项目位置传递给下一个 Activity 并使用来自上一个 activity 的这个位置访问模型对象,为什么不直接使用 bundle.putParcelable()
将对象传递给意图对象 ?
为什么要覆盖 getItemViewType(int position)
,因为您没有在 Adapter 中使用多视图类型?。在 getRetrofit()
方法中你调用了 adapter.notifyDataSetChanged();
虽然你没有完全替换你的列表,你只是将新项目添加到 list ,所以 notifyItemRangeInserted()
应该在这里使用。我制作了示例项目只是为了解决您的问题。让我们看看:-
public class RecyclerViewTestActivity extends AppCompatActivity {
private MyAdapter adapter;
private boolean loading = false;
int pastVisiblesItems, visibleItemCount, totalItemCount;
LinearLayoutManager mLayoutManager;
String baseURL = "https://my.backend.url";
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseURL)
.addConverterFactory(GsonConverterFactory.create())
.build();
RetrofitArrayApi service = retrofit.create(RetrofitArrayApi.class);
String yourURl = yourURL.replace(baseURL,"");
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recycler_view_test);
RecyclerView recyclerView = findViewById(R.id.recycler_view);
mLayoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(mLayoutManager);
adapter = new MyAdapter(new ArrayList<>());
recyclerView.setAdapter(adapter);
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
if (dy > 0) { //check for scroll down
visibleItemCount = mLayoutManager.getChildCount();
totalItemCount = mLayoutManager.getItemCount();
pastVisiblesItems = mLayoutManager.findFirstVisibleItemPosition();
if ((visibleItemCount + pastVisiblesItems) >= totalItemCount) {
Log.d("tisha==>>","Is loading = "+loading);
// Do pagination.. i.e. fetch new data
if (!loading){
adapter.showHideProgress(true);
loading = true;
getRetrofit();
}
}
}
}
});
getRetrofit();
}
void getRetrofit(){
// fetching data from remote server.....
try {
List<Model> list = new ArrayList<>();
Call<List<WPPost>> call = service.getPostInfo( yourURl);
call.enqueue(new Callback<List<WPPost>>() {
@Override
public void onResponse(Call<List<WPPost>> call, Response<List<WPPost>> response) {
Log.d("==>>", " response "+ response.body());
mListPost = response.body();
progressBar.setVisibility(View.GONE);
if (response.body() != null) {
for (int i = 0; i < response.body().size(); i++ ) {
Log.d("==>>", list.size() + "");
Log.d("==>>", " title " + response.body().get(i).getTitle().getRendered() + " " +
response.body().get(i).getId());
String tempdetails = response.body().get(i).getExcerpt().getRendered().toString();
tempdetails = tempdetails.replace("<p>", "");
tempdetails = tempdetails.replace("</p>", "");
tempdetails = tempdetails.replace("[…]", "");
list.add(new Model(Model.IMAGE_TYPE, response.body().get(i).getTitle().getRendered(),
tempdetails,
response.body().get(i).getImages().getMedium()));
}
if (loading){
loading = false;
adapter.showHideProgress(false);
}
adapter.addItemsToList(list);
progressBar.setVisibility(View.GONE);
} else {
progressBar.setVisibility(View.GONE);
}
}
@Override
public void onFailure(Call<List<WPPost>> call, Throwable t) {
}
});
}catch (Exception exception){
Log.d("tisha==>>"," "+exception.getLocalizedMessage());
}
}
// Customize Model Class as per your requirement-----------------
class Model implements Parcelable {
String title;
String subTitle;
String imageUrl;
Model(String title, String subTitle, String imageUrl){
this.title = title;
this.subTitle = subTitle;
this.imageUrl = imageUrl;
}
protected Model(Parcel in) {
title = in.readString();
subTitle = in.readString();
imageUrl = in.readString();
}
public static final Creator<Model> CREATOR = new Creator<Model>() {
@Override
public Model createFromParcel(Parcel in) {
return new Model(in);
}
@Override
public Model[] newArray(int size) {
return new Model[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(title);
dest.writeString(subTitle);
dest.writeString(imageUrl);
}
}
class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
List<Model> modelList;
int viewTypeData = 0,viewTypeProgress = 1;
MyAdapter(List<Model> list){
modelList = list;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
mContext = parent.getContext();
if (viewType == viewTypeData){
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_item_view,parent,false);
return new MyDataHolder(view);
}else {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_item_loading,parent,false);
return new MyProgressHolder(view);
}
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
Model model = modelList.get(position);
if (holder instanceof MyDataHolder){
((MyDataHolder)holder).showModel(model);
}else
((MyProgressHolder)holder).show();
}
@Override
public int getItemCount() {
return modelList.size();
}
@Override
public int getItemViewType(int position){
if (modelList.get(position).title.equals("progress"))
return viewTypeProgress;
else
return viewTypeData;
}
void showHideProgress(boolean shouldShowProgress){
if (shouldShowProgress){
modelList.add(new Model("progress","",""));
notifyItemInserted(modelList.size()-1);
}else {
Log.d("tisha==>>","Size before removal = "+modelList.size());
modelList.remove(modelList.size()-1);
notifyItemRemoved(modelList.size()-1);
Log.d("tisha==>>","Size after removal = "+modelList.size());
}
}
void addItemsToList(List<Model> newItems){
if (modelList.isEmpty()){
modelList.addAll(newItems);
notifyDataSetChanged();
Log.d("tisha==>>","First time List size = "+modelList.size());
}else {
int lastItemPosition = modelList.size() -1;
Log.d("tisha==>>","Old list size = "+modelList.size()+ "Last Item position= "+lastItemPosition);
modelList.addAll(newItems);
Log.d("tisha==>>","Update List size = "+modelList.size());
notifyItemRangeInserted(lastItemPosition,newItems.size());
}
}
static class MyDataHolder extends RecyclerView.ViewHolder{
TextView titleView,subTitleView;
ImageView imageView;LinearLayout rootView;
// Use Glide to load image to image view
public MyDataHolder(@NonNull View itemView) {
super(itemView);
titleView = itemView.findViewById(R.id.recycler_item_title_tv);
subTitleView =
itemView.findViewById(R.id.recycler_item_subtitle_tv);
imageView = itemView.findViewById(R.id.recycler_img_view);
rootView = itemView.findViewById(R.id.recycler_item_root_view);
rootView.setOnClickListener(v -> {
Bundle bundle = new Bundle();
bundle.putParcelable("my_key",modelList.get(getAdapterPosition()));
Intent intent = new Intent(mContext, DetialsActivity.class);
intent.putExtra("my_bundle",bundle);
mContext.startActivity(intent);
});
}
void showModel(Model model){
titleView.setText(model.title);
subTitleView.setText(model.subTitle);
}
}
static class MyProgressHolder extends RecyclerView.ViewHolder{
ProgressBar progressBar;
public MyProgressHolder(@NonNull View itemView) {
super(itemView);
progressBar = itemView.findViewById(R.id.recycler_item_progress);
}
void show(){
progressBar.setVisibility(View.VISIBLE);
}
}
}
recycler_item_view.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:id="@+id/recycler_item_root_view">
<ImageView
android:id="@+id/recycler_img_view"
android:layout_width="50dp"
android:layout_height="50dp"/>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_weight="1"
android:layout_gravity="center_vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/recycler_item_title_tv"
android:gravity="center">
</TextView>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/recycler_item_subtitle_tv"
android:gravity="start">
</TextView>
</LinearLayout>
recycler_item_loading.xml
<ProgressBar
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="50dp"
android:id="@+id/recycler_item_progress"
android:indeterminate="true">
在 NextActivity 中获取 Parcelable 模型 Class,如下所示。在 Target Activity 的 onCreate() 内部放置以下代码:
Bundle bundle = getIntent().getBundleExtra("my_bundle");
Model model = bundle.getParcelable("my_key");
if (model != null){
Log.d("tisha==>>","Title = "+model.title);
}