微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

滚动到下一页时单击时出错

如何解决滚动到下一页时单击时出错

我已成功获得帖子,在前 10 个帖子中,我也收到了帖子内容,但是当我向下滚动以加载更多帖子时,我也可以看到带有特色图片的帖子,但是当我点击这些帖子时,我得到了这个错误:现在我找到答案已经超过 2 周了,请帮忙

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

这是我的 PostDetails 活动:

 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,position);
            mContext.startActivity(intent);
        }
    });
    ( (ImageTypeViewHolder) holder).imageView.setonClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent(mContext,position);
            mContext.startActivity(intent);
        }
    });



    /// dataset.get(position)
}



@Override
public long getItemId(int position) {
    return position;
}

这是适配器:

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("[&hellip;]","");
                    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;
}

最后:

 "allowedCallers": ["5a089b57-xxx-4a2c-xxx-xxxxde5ddd"]

请帮忙,现在我找到答案已经超过 2 周了,请

我也试过这个方法How to handle pagination/load more in Retrofit 2.0?

还有这个What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?

解决方法

代码告诉您正在将点击项位置传递给下一个 Activity 并使用该位置从前一个 Activity 访问模型对象,为什么不直接使用 bundle.putParcelable() 将对象传递给 Intent 对象?

为什么要覆盖 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("[&hellip;]","");
                            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,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 模型类,如下所示。在目标活动的 onCreate() 中放入以下代码:

    Bundle bundle = getIntent().getBundleExtra("my_bundle");
    Model model = bundle.getParcelable("my_key");
    if (model != null){
        Log.d("tisha==>>","Title = "+model.title);
    }
,

我想问题出在您的 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 类似于您更新适配器列表。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。