Reputation: 51
My RecyclerView's Adapter seems to be crashing, I have visited a few questions but I cannot seem to understand what is going on. The questions I had visited mention that a list has been initialised again but I don't think I am initialising any list.
The link of the most relatable question: Link 1
Logcat
java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.get(ArrayList.java:437)
at com.example.android.predictious.ui.market.voucher.VoucherAdapter.onBindViewHolder(VoucherAdapter.java:61)
VoucherAdapter.java
public class VoucherAdapter extends RecyclerView.Adapter<VoucherAdapter.VoucherViewHolder> {
private final LayoutInflater mInflater;
private final String TAG = "VoucherAdapter";
private List<String> mTitle;
public VoucherAdapter(Context context, List<String> mTitle) {
this.mInflater = LayoutInflater.from(context);
this.mTitle = mTitle;
Log.d(TAG, "Constructor");
}
@NonNull
@Override
public VoucherAdapter.VoucherViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = mInflater.inflate(R.layout.voucher_card_view, parent, false);
VoucherViewHolder viewHolder = new VoucherViewHolder(view);
Log.d(TAG, "onCreateViewHolder");
return viewHolder;
}
@Override
public void onBindViewHolder(@NonNull VoucherAdapter.VoucherViewHolder holder, int position) {
Log.d(TAG, "onBindViewHolder");
String title = mTitle.get(position);
holder.voucherTitle.setText(title);
}
@Override
public int getItemCount() {
return mTitle.size();
}
public void setTitle(List<String> Title) {
this.mTitle = Title;
notifyDataSetChanged();
}
public class VoucherViewHolder extends RecyclerView.ViewHolder {
TextView voucherTitle;
public VoucherViewHolder(@NonNull View itemView) {
super(itemView);
Log.d(TAG, "ViewHolder Class");
voucherTitle = itemView.findViewById(R.id.voucherTitleText);
}
}
}
VoucherFragment.java
mViewModel.getmTitleLiveData().observe(getViewLifecycleOwner(), new Observer<List<String>>() {
@Override
public void onChanged(List<String> titleList) {
mTitle.addAll(titleList);
adapter.setTitle(mTitle);
Log.d(TAG, "Data sent to Adapter");
}
});
ViewModel.java
public MutableLiveData<List<String>> getmTitleLiveData() {
repository
.getVoucherCol()
.whereEqualTo("category", categoryTitle)
.addSnapshotListener(new EventListener<QuerySnapshot>() {
@Override
public void onEvent(@Nullable QuerySnapshot queryDocumentSnapshots, @Nullable FirebaseFirestoreException e) {
if (e != null) {
mTitleLiveData = null;
Log.d(TAG, "Could not receive TITLE data \n " + e);
return;
}
List<String> titleList = new ArrayList<>();
for (QueryDocumentSnapshot doc: queryDocumentSnapshots) {
if (doc.get("title") != null) {
titleList.add((String) doc.get("title"));
}
}
mTitleLiveData.postValue(titleList);
Log.d(TAG, "Successfully retrieved TITLE data" + titleList);
}
});
return mTitleLiveData;
}
Upvotes: 0
Views: 742
Reputation: 924
Here
@Override
public void onBindViewHolder(@NonNull VoucherAdapter.VoucherViewHolder holder, int position) {
Log.d(TAG, "onBindViewHolder");
String title = mTitle.get(position);
holder.voucherTitle.setText(title);
}
yout mTitle
is empty when you create your adapter, so that is way you get the exeption. You need to change it to this one:
if (mTitle.size()>0){
String title = mTitle.get(position);
holder.voucherTitle.setText(title);
}
You suppose to add values to it not like you do here:
public void setTitle(List<String> Title) {
this.mTitle = Title;
notifyDataSetChanged();
}
I strongly recomend you to remove this setTitle method. Pass this list via your adapter constructor. If you need to change this list - change it in your VoucherFragment. You can do it two ways - the way you did with little changes:
mViewModel.getmTitleLiveData().observe(getViewLifecycleOwner(), new Observer<List<String>>() {
@Override
public void onChanged(List<String> titleList) {
mTitle.addAll(titleList);
adapter.notifyDataSetChanged;
Log.d(TAG, "Data sent to Adapter");
}
});
or another way:
mViewModel.getmTitleLiveData().observe(getViewLifecycleOwner(), new Observer<List<String>>() {
@Override
public void onChanged(List<String> titleList) {
yourRecyclerView.setAdapter(new VoucherAdapter(getContext, titleList))
Log.d(TAG, "Data sent to Adapter");
}
Hope that helps
Upvotes: 1