IndexOutOfBoundsException в Adapter.onBindViewHolder в Android - PullRequest
0 голосов
/ 28 мая 2020

Адаптер моего RecyclerView, похоже, дает сбой, я посетил несколько вопросов, но не могу понять, что происходит. В вопросах, которые я посетил, упоминается, что список был снова инициализирован, но я не думаю, что инициализирую какой-либо список.

Ссылка на наиболее интересный вопрос: Ссылка 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;
    }

1 Ответ

1 голос
/ 28 мая 2020

Здесь

@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 пуст, когда вы создаете свой адаптер, поэтому вы получаете исключение. Вам нужно изменить его на этот:

if (mTitle.size()>0){
String title = mTitle.get(position);
            holder.voucherTitle.setText(title);
}

Вы предполагаете добавить к нему значения, а не как здесь:

 public void setTitle(List<String> Title) {
        this.mTitle = Title;
        notifyDataSetChanged();
    }

Я настоятельно рекомендую вам удалить этот метод setTitle. Передайте этот список через конструктор вашего адаптера. Если вам нужно изменить этот список - измените его в вашем VoucherFragment. Вы можете сделать это двумя способами - как вы сделали с небольшими изменениями:

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

или другим способом:

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

Надеюсь, что это поможет

...