Подтвердить что ты не робот

Android recyclerView findViewHolderForAdapterPosition возвращает null

Я хочу программно выбрать элемент в recyclerView, я нашел способ:

recyclerView.findViewHolderForAdapterPosition(0).itemView.performClick();

но это не работает для меня, findViewHolderForAdapterPosition просто возвращает null.

Я что-то пропустил в своем коде?

HistoryListAdapter:

public class HistoryListAdapter extends RecyclerView.Adapter<HistoryListAdapter.ViewHolder> {
private static ArrayList<RecordItem> recordItems;
private static FragmentActivity activity;
private static RecordList recordList;

public HistoryListAdapter(ArrayList<RecordItem> recordItems, FragmentActivity FA, RecordList FRL) {
    this.recordItems = recordItems;
    this.activity = FA;
    this.recordList = FRL;
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    // create a new view
    View itemLayoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.recorditem, parent, false);
    return new ViewHolder(itemLayoutView);
}

@Override
public void onBindViewHolder(final ViewHolder viewHolder, final int position) {
    // TextView setText ...
}

// Return the size of the itemsData (invoked by the layout manager)
@Override
public int getItemCount() {
    return recordItems.size();
}

// inner class to hold a reference to each item of RecyclerView
public static class ViewHolder extends RecyclerView.ViewHolder{
    public TextView result, datetime;

    public ViewHolder(View itemLayoutView) {
        super(itemLayoutView);
        itemLayoutView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (activity != null) {
                    // do something...
                }
            }
        });
        result = (TextView) itemLayoutView.findViewById(R.id.result);
        heartrate = (TextView) itemLayoutView.findViewById(R.id.heartrate);
        datetime = (TextView) itemLayoutView.findViewById(R.id.datetime);
    }
}
}

RecordList:

RecyclerView listView = (RecyclerView) layoutView.findViewById(R.id.listView);
HistoryListAdapter listadapter = new HistoryListAdapter(itemsToShow, getActivity(), RecordList.this);
listView.swapAdapter(listadapter, false);
listView.findViewHolderForAdapterPosition(0).itemView.performClick();

Я пропустил некоторый код, но он не должен влиять на общую структуру моего кода.

4b9b3361

Ответ 1

В соответствии с официальной документацией :

если notifyDataSetChanged() был вызван, но новый макет имеет не был рассчитан еще, этот метод вернет null, поскольку новый позиции просмотров неизвестны до расчета макета.

Нельзя использовать findViewHolderForAdapterPosition().

Пока вы вызываете этот метод после listView.swapAdapter(listadapter, false);, вы всегда получите результат null, потому что будет вызываться notifyDataSetChanged().

Ответ 2

вы можете сделать это:

   listView.postDelayed(new Runnable()
            {
                @Override
                public void run()
                {
                    if(listView.findViewHolderForAdapterPosition(0)!=null )
                    {

                        listView.findViewHolderForAdapterPosition(0).itemView.performClick();
                    }
                }
            },50);

Ответ 3

Эй, я решил проблему таким образом:

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {

private TextView mTotalSum;
protected int mSum;
protected ArrayList<BasketRVAdapter.ViewHolder> mViewHolders;

public BasketRVAdapter(JSONArray recyclerItems, Context context, TextView totalSum) {
    super(recyclerItems, context);
    mTotalSum = totalSum;
    mViewHolders = new ArrayList<>();
}

@Override
public RecyclerView.ViewHolder onCreateSwipeViewHolder(ViewGroup parent, int i) {
    View view = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.view_basket_rv_item, parent, true);

    return new ViewHolder(view);
}

@Override
public void onBindSwipeViewHolder(final RecyclerView.ViewHolder viewHolder, int position) {
    final BasketRVAdapter.ViewHolder holder = (BasketRVAdapter.ViewHolder) viewHolder;

    JSONObject object;
    try {
        object = mRecyclerItems.getJSONObject(position);
        final int priceValue = object.getInt("price");
        final int quantityValue = object.getInt("quantity");

        holder.setId(object.getInt("id"));
        holder.title.setText(object.getString("title"));
        holder.price.setText(String.format(mContext.getString(R.string.price), priceValue));
        holder.quantity.setText(String.valueOf(quantityValue));
        holder.sum.setText(String.valueOf(priceValue * quantityValue));

        holder.quantity.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void afterTextChanged(Editable editable) {
                String value = holder.quantity.getText().toString();

                if (value.equals("")) {
                    return;
                }

                if (value.equals("0")) {
                    Toast.makeText(mContext, R.string.null_value_error, Toast.LENGTH_SHORT).show();
                    return;
                }
                holder.sum.setText(String.valueOf(priceValue * Integer.valueOf(value)));
                setTotalSum();
            }

        });

        mViewHolders.add(holder);
        mSum += priceValue * quantityValue;

        if (position == getItemCount() - 1) {
            mTotalSum.setText(String.format(mContext.getString(R.string.total_sum), mSum));
        }
    } catch (JSONException e) {
        e.printStackTrace();
    }
}

@Override
public SwipeConfiguration onCreateSwipeConfiguration(Context context, int i) {
    return new SwipeConfiguration.Builder(context)
                                 .setLeftSwipeBehaviour(SwipeConfiguration.SwipeBehaviour.NORMAL_SWIPE)
                                 .setRightSwipeBehaviour(SwipeConfiguration.SwipeBehaviour.NO_SWIPE)
                                 .setLeftBackgroundColorResource(R.color.dt_basket_deleted)
                                 .setLeftUndoDescription(R.string.deleted)
                                 .setDescriptionTextColorResource(R.color.dt_white)
                                 .setLeftUndoable(true)
                                 .build();
}

@Override
public void onSwipe(int i, int i1, RecyclerView.ViewHolder holder) {
    try {
        if (i1 == SWIPE_LEFT) {
            remove(i);
            notifyItemRemoved(i);
            mViewHolders.remove(i);
            setTotalSum();
        }
    } catch (JSONException e) {
        e.printStackTrace();
    }
}

public int getSum() {
    return mSum;
}

public void setTotalSum() {
    int totalSum = 0;

    for (BasketRVAdapter.ViewHolder holder : mViewHolders) {
        totalSum += Integer.valueOf(holder.sum.getText().toString());
    }

    mSum = totalSum;
    mTotalSum.setText(String.format(mContext.getString(R.string.total_sum), totalSum));
}

public static class ViewHolder extends RecyclerView.ViewHolder {

    @Bind(R.id.trade_title)
    public TextView title;
    @Bind(R.id.trade_price)
    public TextView price;
    @Bind(R.id.trade_quantity)
    public EditText quantity;
    @Bind(R.id.sum)
    public TextView sum;

    private int mId;

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

    public int getId() {
        return mId;
    }

    public void setId(int id) {
        mId = id;
    }
}}
  • Добавлено поле ArrayList mViewholders внутри класса
  • добавлен каждый экземпляр экземпляра в mViewHolders arraylist внутри метода onBindSwipeViewHolder.
  • используется mViewholders arraylist вместо метода findViewHolderForadapter в методе setTotalSum