0

I have 2 Activity, MainActivity and ProductDetailsActivity. In MainActivity I am showing 3 layout in RecyclerView such as (Feature, Bioderma and Supplement) and in ProductDetailsActivity I am showing product details with another RecyclerView such as (Related product). Related product RecyclerView is showing perfect data but when I click on MainActivity first product there is no problem and after clicking the second product my app is showing IndexOutOfBoundsException.

I am new in programming and I have tried many different ways but no luck. Please help me.

My ProductAdapter.java is given below:

public class ProductAdapter extends RecyclerView.Adapter<ProductAdapter.ViewHolder> {
    private Context mContext;
    private ArrayList<Product> productList, relatedProductList;
    private int viewType;

    public ProductAdapter(Context mContext, ArrayList<Product> productList, ArrayList<Product> relatedProductList, int viewType) {
        this.mContext = mContext;
        this.productList = productList;
        this.relatedProductList = relatedProductList;
        this.viewType = viewType;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view;
        if (viewType == 1) {
            view = LayoutInflater.from(parent.getContext()).inflate(R.layout.horizontal_product_list, parent, false);

        } else if (viewType == 2) {
            view = LayoutInflater.from(parent.getContext()).inflate(R.layout.circular_horizontal_product_list, parent, false);

        } else if (viewType == 4) {
            view = LayoutInflater.from(parent.getContext()).inflate(R.layout.horizontal_related_product_list, parent, false);

        } else
            view = LayoutInflater.from(parent.getContext()).inflate(R.layout.product_list, parent, false);

        return new ViewHolder(view);
    }

    @Override
    public int getItemViewType(int position) {
        if (viewType == 1) {
            return 1;
        } else if (viewType == 2) {
            return 2;
        } else if (viewType == 4) {
            return 4;
        } else
            return 3;
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {

        if (viewType == 4) {
            holder.productTitle.setText(relatedProductList.get(position).getProductName());

            String imagePath = relatedProductList.get(position).getProductImage();
            Glide.with(mContext)
                    .load(imagePath)
                    .placeholder(R.drawable.loading)
                    .into(holder.productImage);
        } else {
            holder.productTitle.setText(productList.get(position).getProductName());

            //Converting string resource with placeholder
            String salePrice = holder.itemView.getContext().getString(R.string.sale_price, Float.parseFloat(productList.get(position).getSalePrice()));
            String regularPrice = holder.itemView.getContext().getString(R.string.regular_price, Float.parseFloat(productList.get(position).getSalePrice()));

            //Checking for equal price and invisible regular text view
            if (salePrice.equals(regularPrice)) {
                holder.productSalePrice.setText(salePrice);

            } else {

                holder.productSalePrice.setText(salePrice);
                holder.productRegularPrice.setText(regularPrice);
                holder.productRegularPrice.setPaintFlags(holder.productRegularPrice.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
            }

            String imagePath = productList.get(position).getProductImage();
            Glide.with(mContext)
                    .load(imagePath)
                    .placeholder(R.drawable.loading)
                    .into(holder.productImage);
        }
    }

    @Override
    public int getItemCount() {
        if (viewType == 4) {
            return relatedProductList == null ? 0 : relatedProductList.size();

        } else
            return productList == null ? 0 : productList.size();
    }


    public class ViewHolder extends RecyclerView.ViewHolder {
        MaterialTextView productTitle, productRegularPrice, productSalePrice;
        ImageView productImage;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            productImage = itemView.findViewById(R.id.ivProductImageId);
            productTitle = itemView.findViewById(R.id.tvTitleId);
            productRegularPrice = itemView.findViewById(R.id.tvRegularPriceId);
            productSalePrice = itemView.findViewById(R.id.tvSalePriceId);

            //for passing data between activities
            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (viewType == 4) {
                        final int relatedPosition = getAdapterPosition();

                        if (relatedPosition != RecyclerView.NO_POSITION) {
                            Product relatedSelectProduct = relatedProductList.get(relatedPosition);

                            Intent intent = new Intent(mContext, ProductDetailsActivity.class);
                            intent.putExtra("productId", relatedSelectProduct.getProductId());
                            mContext.startActivity(intent);
                        }

                    } else {
                        final int position = getAdapterPosition();

                        if (position != RecyclerView.NO_POSITION) {
                            Product selectedProduct = productList.get(position);

                            Intent intent = new Intent(mContext, ProductDetailsActivity.class);
                            intent.putExtra("productId", selectedProduct.getProductId());
                            mContext.startActivity(intent);

                        }
                    }
                }
            });
        }
    }
}

My IDE is pointing to this bold line of code:

else {
                        final int position = getAdapterPosition();

                        if (position != RecyclerView.NO_POSITION) {
                            **Product selectedProduct = productList.get(position);**

                            Intent intent = new Intent(mContext, ProductDetailsActivity.class);
                            intent.putExtra("productId", selectedProduct.getProductId());
                            mContext.startActivity(intent);

                        }

My logcat is showing this error:

java.lang.IndexOutOfBoundsException: Index: 6, Size: 0
        at java.util.ArrayList.get(ArrayList.java:411)
        at com.themessenger.epharma.adapter.ProductAdapter$ViewHolder$1.onClick(ProductAdapter.java:146)
        at android.view.View.performClick(View.java:5637)
        at android.view.View$PerformClick.run(View.java:22429)
        at android.os.Handler.handleCallback(Handler.java:751)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:154)
        at android.app.ActivityThread.main(ActivityThread.java:6119)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
Delowar Hossain
  • 687
  • 10
  • 18
  • Please read [mcve] and pay special attention to the link at the bottom about debugging small programs. – AdrianHHH Mar 06 '20 at 09:43
  • It's very difficult to debug a crash without a stack trace. Please see [Unfortunately MyApp has stopped. How can I solve this?](https://stackoverflow.com/questions/23353173/unfortunately-myapp-has-stopped-how-can-i-solve-this) for Android-specific advice, and [What is a stack trace, and how can I use it to debug my application errors?](https://stackoverflow.com/questions/3988788/what-is-a-stack-trace-and-how-can-i-use-it-to-debug-my-application-errors) for advice on what to do once you have the stack trace. If you still need help, please edit your question to include the stack trace. – Ryan M Mar 06 '20 at 09:43
  • Sorry for my little knowledge, I have updated my code. I am fetching product data from an api using Volley library. Do I need to update my all code snippet regarding MainActivity? – Delowar Hossain Mar 06 '20 at 10:05

2 Answers2

0

From your stacktrace, productList has a size of 0. So when you get adapter position somewhere like 1,2,3 etc. and you try to get item from list, it throws IndexOutOfBoundsException. I suggest you look into your list data, and make sure that list is populated correctly. Also, if you have two lists with item count 4 in same adapter, adapter position might be 7, so when you try to get item from a list, you will still get the same exception, since none of the lists has more than 4 items. Maybe try to merge lists into single list, i think it will solve many of your problems.

Samir Spahic
  • 542
  • 2
  • 10
  • I have already tried merging in single list but still throws exception. Related product recyclerview is in another activity. If I disable Related product code by commenting recyclerview code than all code work well. – Delowar Hossain Mar 06 '20 at 12:39
  • Something with you data must be wrong, since the stracktrace shows that your list has 0 elements. – Samir Spahic Mar 06 '20 at 15:44
  • Thanks for your reply and I will check things as per your instruction – Delowar Hossain Mar 06 '20 at 15:46
0

I have found my solution. I am using 3 RecyclerView in MainActivity and 1 RecyclerView to ProductDetailsActivity. When I move from MainActivity to ProductDetailsActivity than my MainActivity product list array size is cleared and for this reason when I go back to MainActivity by onBackPresssed() my product list size set to 0.

What I did, in MainActivity I override onRestart() life cycle method and fetched the data from web by setting Volley data fetching method. I don't know what will be the consequences but it saved my day.

Thanks everyone for your support.

Delowar Hossain
  • 687
  • 10
  • 18