So after a long time, I've finally found a way to display an Horizontal RecyclerView
into another RecyclerView
.
I followed this tutorial: http://mithunkumarc.blogspot.com/2016/09/nested-recyclerview-or-inner-recycler.html
To put some context, I am fetching some JSON
data, into an object called "Application". I have three different fragments. These fragments are displaying RecyclerView
with the previous data.
Into these applications, I have for each one a list of photos. So I followed the mentionned tutorial to display these photos into another RecyclerView
(Sounds a lot like Nested RecyclerView
)
But when I launch my first fragment
, I encounter the following error:
java
2019-08-28 10:11:40.120 6403-6403/com.example.applicationpro E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.applicationpro, PID: 6403 java.lang.IndexOutOfBoundsException: Index: 1, Size: 1 at java.util.ArrayList.get(ArrayList.java:411) at com.example.applicationpro.adapter.PhotoAdapter.onBindViewHolder(PhotoAdapter.java:38) at com.example.applicationpro.adapter.PhotoAdapter.onBindViewHolder(PhotoAdapter.java:17) at android.support.v7.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:6781) at android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:6823) at android.support.v7.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:5752) at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6019) at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5858) at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5854) at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2230) at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1557) at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1517) at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:612) at android.support.v7.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3924) at android.support.v7.widget.RecyclerView.onMeasure(RecyclerView.java:3336) at android.view.View.measure(View.java:20132) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6282) at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1705) at android.widget.LinearLayout.measureHorizontal(LinearLayout.java:1279) at android.widget.LinearLayout.onMeasure(LinearLayout.java:659) at android.view.View.measure(View.java:20132) at android.widget.HorizontalScrollView.measureChildWithMargins(HorizontalScrollView.java:1274) at android.widget.FrameLayout.onMeasure(FrameLayout.java:214) at android.widget.HorizontalScrollView.onMeasure(HorizontalScrollView.java:315) at android.view.View.measure(View.java:20132) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6282) at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1705) at android.widget.LinearLayout.measureVertical(LinearLayout.java:797) at android.widget.LinearLayout.onMeasure(LinearLayout.java:657) at android.view.View.measure(View.java:20132) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6282) at android.widget.FrameLayout.onMeasure(FrameLayout.java:214) at android.support.v7.widget.CardView.onMeasure(CardView.java:260) at android.view.View.measure(View.java:20132) at android.support.v7.widget.RecyclerView$LayoutManager.measureChildWithMargins(RecyclerView.java:9119) at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1583) at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1517) at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:612) at android.support.v7.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3924) at android.support.v7.widget.RecyclerView.onMeasure(RecyclerView.java:3336) at android.view.View.measure(View.java:20132) at android.support.constraint.ConstraintLayout.internalMeasureChildren(ConstraintLayout.java:1227) at android.support.constraint.ConstraintLayout.onMeasure(ConstraintLayout.java:1572) at android.view.View.measure(View.java:20132) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6282) at android.widget.FrameLayout.onMeasure(FrameLayout.java:214) at android.view.View.measure(View.java:20132) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6282) at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1705) at android.widget.LinearLayout.measureVertical(LinearLayout.java:797) 2019-08-28 10:11:40.121 6403-6403/com.example.applicationpro E/AndroidRuntime: at android.widget.LinearLayout.onMeasure(LinearLayout.java:657) at android.view.View.measure(View.java:20132)
Parent adapter (onBindViewHolder & onCreateViewHolder methods)
// PHOTO PART
if (mApplication.getmListOfViews() != null) {
mListOfPhotos.addAll(mApplication.getmListOfViews());
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int i) {
mApplicationItem = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_application, parent, false);
mContext = parent.getContext();
return new ViewHolder(mApplicationItem);
}
@Override
public void onBindViewHolder(@NonNull final ViewHolder holder, int position) {
final Application mApplication = mListOfApplications.get(position);
holder.mApplicationCV.setTag(position);
int mCreditUsed = mApplication.getmDelay().getmCost();
holder.mApplicationBrandNameTV.setText(mContext.getString(R.string.request, mApplication.getmApplicationArticle().getmBrand().getmName()));
holder.mApplicationStartDateTV.setText(mContext.getString(R.string.creationDate, mDateInterface.convertDateToString(mApplication.getmCreationDate())));
switch (mCreditUsed) {
case 8:
holder.mApplicationDelayTV.setText(R.string.consEightCredit);
break;
case 12:
holder.mApplicationDelayTV.setText(R.string.consTwelveCredit);
break;
case 14:
holder.mApplicationDelayTV.setText(R.string.consFourteenCredit);
break;
case 26:
holder.mApplicationDelayTV.setText(R.string.consTwentySixCredit);
break;
case 30:
holder.mApplicationDelayTV.setText(R.string.consThirtyCredit);
break;
case 42:
holder.mApplicationDelayTV.setText(R.string.consFortyTwoCredit);
break;
default:
holder.mApplicationDelayTV.setText(R.string.consNoDelayFound);
break;
}
holder.mApplicationEstimationTV.setText(mContext.getString(R.string.estimationDate, mDateInterface.convertDateToString(mApplication.getmDelay().getmDateEstimation())));
// SPECIMEN PART
if (mApplication.getmCertificate() != null) {
if (!mApplication.getmCertificate().equals("")) {
if (mApplication.getmStatus().equals("Authentique")) {
holder.mApplicationSpecimenIV.setImageResource(R.drawable.specimen_valid);
holder.mApplicationSpecimenIV.setVisibility(View.VISIBLE);
} else if (mApplication.getmStatus().equals("Non conforme")) {
holder.mApplicationSpecimenIV.setImageResource(R.drawable.specimen_not_valid);
holder.mApplicationSpecimenIV.setVisibility(View.VISIBLE);
}
holder.mApplicationSpecimenIV.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent mBrowserIntent = new Intent();
mBrowserIntent.setAction(Intent.ACTION_VIEW);
mBrowserIntent.setData(Uri.parse(mListOfApplications.get(holder.getAdapterPosition()).getmCertificate()));
mActivity.startActivity(mBrowserIntent);
}
});
}
}
// PHOTO PART
if (mApplication.getmListOfViews() != null) {
mListOfPhotos.addAll(mApplication.getmListOfViews());
}
LinearLayoutManager mLinearLayout = new LinearLayoutManager(this.mActivity, LinearLayoutManager.HORIZONTAL, false);
holder.mApplicationPhotosRV.setLayoutManager(mLinearLayout);
holder.mApplicationPhotosRV.setHasFixedSize(true);
PhotoAdapter mPhotoAdapter = new PhotoAdapter(this.mActivity, mListOfApplications, mListOfPhotos);
holder.mApplicationPhotosRV.setAdapter(mPhotoAdapter);
if (mApplication.getmInformations() == null || mApplication.getmInformations().isEmpty()) {
if (mApplication.getmStatus().equals("Archivé ou annulé") || mApplication.getmStatus().equals("Ne se prononce pas")) {
holder.mApplicationInfoLL.setVisibility(View.VISIBLE);
holder.mApplicationInfosTV.setText(mContext.getString(R.string.status, mApplication.getmStatus()));
}
} else {
holder.mApplicationInfoLL.setVisibility(View.VISIBLE);
if (mApplication.getmStatus().equals("Archivé ou annulé") || mApplication.getmStatus().equals("Ne se prononce pas")) {
holder.mApplicationInfosTV.setText(mContext.getString(R.string.informations, mApplication.getmInformations(), mApplication.getmStatus()));
} else {
holder.mApplicationInfosTV.setText(mContext.getString(R.string.informations, mApplication.getmInformations(), null));
}
}
holder.mApplicationIDTV.setText(mContext.getString(R.string.ID, mApplication.getmIDApplication()));
holder.mApplicationReferenceTV.setText(mContext.getString(R.string.reference, mApplication.getmReference()));
}
Child Adapter (also onCreateViewHolder & onBindViewHolder)
@NonNull
@Override
public PhotoAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View mPhotoItem = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_application_photo, parent, false);
return new ViewHolder(mPhotoItem);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
final Application mApplication = mListOfApplications.get(position);
if (mApplication != null) {
if (!mApplication.getmListOfViews().isEmpty()) {
for (int i = 0; i < mApplication.getmListOfViews().size(); i++) {
String mPath = mApplication.getmListOfViews().get(i)
.replaceAll("\\[", "")
.replaceAll("\"", "")
.replaceAll("\\]", "");
mApplication.getmListOfViews().set(i, mPath);
}
for (int j = 0; j < mApplication.getmListOfViews().size(); j++) {
ImageView mImageView = holder.mPhotoIV;
int width = mImageView.getLayoutParams().width;
int height = mImageView.getLayoutParams().height;
Picasso.get()
.load(mApplication.getmListOfViews().get(j)).resize(width, height)
.error(R.drawable.ic_no_photo_foreground).into(mImageView, new com.squareup.picasso.Callback() {
@Override
public void onSuccess() {
}
@Override
public void onError(Exception e) {
}
});
}
}
}
}
EDIT: Method getItemCount from PhotoAdapter
@Override
public int getItemCount() {
return mListOfPhotos.size();
}
I have debugged my application, mListOfApplications
and mListOfPhotos
have the right and expected data.
What am I missing :)?