Holder.getAdapterPosition () RecyclerView возвращает -1. Вызывает ArrayIndexOutOfBoundsException - PullRequest
1 голос
/ 03 апреля 2019

Я пытаюсь добавить OnClickListner к элементу внутри recyclerView adapter, остальная функциональность работает хорошо с holder.getAdapterPosition(), но когда я пытаюсь реализовать onClickListner на нем, его показ ArrayIndexOutOfBoundsExceptionошибка.Я использую FlexboxLayoutManager.

My_Adapter_Class

public class SuggestedSkillAdapter extends RecyclerView.Adapter<SuggestedSkillAdapter.ViewHolder> {
public List<String> suggestedSkills;
public List<String> filterList;
Context context;
private int itemlayout;
FragOne fragOne;

public SuggestedSkillAdapter(int skill_badge_layout, List<String> suggestedSkills, Context context, FragOne fragOne) {
    this.itemlayout = skill_badge_layout;
    this.context = context;
    this.suggestedSkills = suggestedSkills;
    this.filterList = suggestedSkills;
    this.fragOne = fragOne;
}

@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext()).inflate(itemlayout, parent, false);
    ViewHolder myViewHolder = new ViewHolder(view);
    return myViewHolder;
}

@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
    holder.skillName.setText(suggestedSkills.get(holder.getAdapterPosition()));
    holder.cardView.setOnClickListener(view -> {
        fragOne.addItemToSkillsToBeReviewed(suggestedSkills.get(holder.getAdapterPosition()));
        suggestedSkills.remove(holder.getAdapterPosition());
        notifyItemRemoved(holder.getAdapterPosition());
        Toast.makeText(context, "" + holder.getAdapterPosition(), Toast.LENGTH_SHORT).show();
    });
}

@Override
public int getItemCount() {
    return suggestedSkills.size();
}

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

public void filterList(ArrayList<String> filterdNames) {
    this.suggestedSkills = filterdNames;
    notifyDataSetChanged();
    notifyItemRangeChanged(0, suggestedSkills.size());
}

public class ViewHolder extends RecyclerView.ViewHolder {
    @BindView(R.id.skillName)
    TextView skillName;
    @BindView(R.id.cardMain)
    CardView cardView;

    public ViewHolder(View itemView) {
        super(itemView);
        ButterKnife.bind(this, itemView);
    }

}
}

Crash_Log

`2019-04-03 11:04:10.774 18117-18117/com.example.addreview D/AndroidRuntime: Shutting down VM
2019-04-03 11:04:10.780 18117-18117/com.example.addreview E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.addreview, PID: 18117
    java.lang.ArrayIndexOutOfBoundsException: length=196; index=-1
        at java.util.ArrayList.get(ArrayList.java:439)
        at com.example.addreview.Adapters.SuggestedSkillAdapter.lambda$onBindViewHolder$0(SuggestedSkillAdapter.java:55)
        at com.example.addreview.Adapters.-$$Lambda$SuggestedSkillAdapter$ib8AJ50Na4r0wQZw7b9CrGCGhkY.onClick(Unknown Source:4)
        at android.view.View.performClick(View.java:6600)
        at android.view.View.performClickInternal(View.java:6577)
        at android.view.View.access$3100(View.java:781)
        at android.view.View$PerformClick.run(View.java:25912)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6912)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:860)`

Как только я начал получать сообщение об ошибке, я проверяю позицию в сообщении Toast,Но я вызываю значения списка из того же метода, и значения отображаются, как и ожидалось.Невозможно решить, почему он показывает -1 как позицию.

Я ожидаю точную позицию от holder.getAdapterPosition()

Ответы [ 3 ]

2 голосов
/ 03 апреля 2019

Создайте настраиваемый прослушиватель внутри адаптера, а затем запустите события вверх до реализации интерфейса, определенной в родительском элементе. Ваша логика кликов должна обрабатываться в рамках действия или фрагмента.

@Override
 public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
 // handle event inside onBindViewHolder  
 holder.someButtonToRemoveItem.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
       // some listener interface method
         onRemoveClickListener.onClick(view, position);
    }
});
}

Присоединение обработчиков щелчков с использованием слушателей в RecyclerView

1 голос
/ 03 апреля 2019

Вы не должны выполнять операции dataSet на onBindViewHolder(). Возвращает -1, потому что recyclerview вычисляет измерения макета.

Даже ClickListeners должен быть определен внутри класса ViewHolder, потому что onBindViewHolder() вызывается постоянно, поэтому операции просмотра будут дорогостоящими, когда мы говорим об аспектах производительности.

Предложение: Переместите весь фрагмент кода onClickListener в класс ViewHolder и посмотрите, что произойдет. Используйте getAdapterPosition() метод RecyclerView.ViewHolder, чтобы получить текущую позицию просмотра.

0 голосов
/ 03 апреля 2019

Используйте значение 'position', которое вы получаете от onBindViewHolder, вместо getAdapterPosition ().

...