2015-09-29 21 views
11

Tôi muốn chọn một khoản mục trong recyclerView lập trình, tôi thấy a way làm điều đó:Android recyclerView findViewHolderForAdapterPosition trả về null

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

nhưng nó không làm việc cho tôi, findViewHolderForAdapterPosition chỉ trả về null.

Tôi có bỏ lỡ điều gì đó trong mã của mình không?

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(); 

tôi bỏ qua một số mã, Nhưng nó không ảnh hưởng đến cấu trúc tổng thể của mã của tôi.

+0

Kiểm tra câu trả lời này ra để có được một cách thoải mái thực hiện một chức năng onclick trong recyclerview: http://stackoverflow.com/questions/31174712/android-onclicklistener-for-recyclerviews-childs -ild/31176508 # 31176508 – Smashing

Trả lời

16

Theo official documentation:

nếu notifyDataSetChanged() đã được gọi là nhưng cách bố trí mới có không được tính toán chưa, phương pháp này sẽ trở lại rỗng kể từ khi vị trí mới quan điểm là không xác định cho đến khi bố cục được tính toán.

Không an toàn khi sử dụng findViewHolderForAdapterPosition().

Trong khi bạn gọi phương thức này sau listView.swapAdapter(listadapter, false); bạn sẽ luôn nhận được null do kết quả vì notifyDataSetChanged() sẽ được gọi.

+2

Cảm ơn, tôi không nhận thấy rằng ... –

+0

chúng tôi có thể sử dụng viewtreeobserver không? –

+1

@ J.K. Nó phụ thuộc vào nhu cầu của bạn. Trong trường hợp này, ngay cả ViewTreeObserver cũng không được bảo đảm là vẫn hợp lệ cho thời gian tồn tại của ListView. – Rami

0

Hey Tôi đã giải quyết vấn đề theo cách này:

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; 
    } 
}} 
  1. Added ArrayList mViewholders lĩnh vực bên trong lớp
  2. thêm vào mỗi trường hợp viewholder để mViewHolders ArrayList bên onBindSwipeViewHolder phương pháp
  3. mViewholders sử dụng ArrayList thay vì phương thức findViewHolderForadapterposition bên trong phương thức setTotalSum
12

bạn có thể làm điều này:

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

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

Cảm ơn @Dharmaraj. Làm việc như quyến rũ. http://stackoverflow.com/a/30883242 theo nhận xét yigit điều này xảy ra vì vị trí không được đặt ra (ví dụ: ngoài ranh giới hoặc bị xóa). –

Các vấn đề liên quan