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();
Я пропустил некоторый код, но он не должен влиять на общую структуру моего кода.
Ответы
Ответ 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