[英]Why is the onClick method of my RecyclerView.ViewHolder not called sometimes?
我的ViewHolder
實現了View.OnClickListener
因為它在這個答案中建議。 除此之外,我仔細檢查了我的適配器類是否與官方文檔中的示例相似。
public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private View view;
public ViewHolder(View view) {
super(view);
view.setOnClickListener(this);
this.view = view;
}
public View getView() {
return view;
}
@Override
public void onClick(View view) {
Context context = view.getContext();
Intent intent = new Intent(context, DetailsActivity.class);
context.startActivity(intent);
}
}
但是,如果我正在測試我的應用程序,我會觀察到這種非常奇怪的行為:如果我點擊啟動時可見的行,則onClick
方法會按預期執行。 現在我向下滾動使其他一些行可見。 我點擊某處,沒有任何反應,第二次點擊 - 無論是否在同一行 - 再次起作用。 如果我滾動回頂部,也會發生同樣的事情,我必須點擊兩次才能調用我的onClick
方法。
任何想法為什么會發生這種情況?
編輯:完整代碼,現在在onBindViewHolder
設置偵聽onBindViewHolder
:
public class ComposersAdapter extends RecyclerView.Adapter<ComposersAdapter.ViewHolder> {
public static class ViewHolder extends RecyclerView.ViewHolder {
private View view;
public ViewHolder(View view) {
super(view);
this.view = view;
}
public View getView() {
return view;
}
}
private final String EXTRA_COMPOSER_ID = "composerId";
private List<Composer> composers;
public ComposersAdapter(List<Composer> composers) {
this.composers = composers;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.text_layout, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
View view = holder.getView();
TextView textView = view.findViewById(R.id.textView);
textView.setText(composers.get(position).getTitle());
holder.getView().setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Context context = view.getContext();
Intent intent = new Intent(context, ComposerActivity.class);
intent.putExtra(EXTRA_COMPOSER_ID, holder.getAdapterPosition());
context.startActivity(intent);
}
});
}
@Override
public int getItemCount() {
return composers.size();
}
}
更新:這個問題似乎與 RecyclerView 所在的活動的工具欄有關。我已經設置了app:layout_scrollFlags="scroll|enterAlways"
並且如果我刪除了這個問題就不存在了。 也許這與工具欄捕獲觸摸事件有關? 我沒有足夠的經驗來檢查自己。
在onBindViewHolder(RecyclerView.ViewHolder holder, int position)
分配點擊監聽onBindViewHolder(RecyclerView.ViewHolder holder, int position)
。
onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// start some activity
}
});
}
On Bind View Holder 是當一個 viewholder 正確綁定到適配器並且視圖的單個實例在這里可用時。
holder.itemView
將為您提供對 viewHolder 的視圖實例的引用。 因此,您不像 ViewHolder 中的方法那樣使用getView()
。
ViewHolder描述了一個項目視圖和關於它在RecyclerView 中的位置的元數據。
RecyclerView.Adapter實現應該子類化 ViewHolder 並添加用於緩存潛在昂貴的findViewById(int)結果的字段。
我在項目中有類似的問題,我做了一些示例,你可以看看這可能有助於解決你的問題。
public class ProductAdapter extends RecyclerView.Adapter<ProductAdapter.ViewHolder> {
private List<Ad> adsList= new ArrayList<>();
private Context mContext;
static OnItemClickListener mItemClickListener;
//Provide a reference to the views for each data item
public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
@BindView(R.id.mainHolder)
public RelativeLayout placeHolder;
@BindView(R.id.tv_ad_name)
public TextView tvAdName;
@BindView(R.id.tv_no_of_rating)
public TextView tvNoOfRating;
@BindView(R.id.tv_minOs)
public TextView tvMinOs;
@BindView(R.id.iv_product_thumbnail)
public ImageView ivPrductThumbnail;
public ViewHolder(View v) {
super(v);
ButterKnife.bind(this, v);
placeHolder.setOnClickListener(this);
}
@Override
public void onClick(View v) {
if (mItemClickListener != null) {
mItemClickListener.onItemClick(itemView, getPosition());
}
}
}
public interface OnItemClickListener {
void onItemClick(View view, int position);
}
public void setOnItemClickListener(final OnItemClickListener mItemClickListener) {
this.mItemClickListener = mItemClickListener;
}
//Provide a suitable constructor
public ProductAdapter(Context context){
mContext = context;
}
public void setAd(List<Ad> aList) {
adsList.clear();
adsList.addAll(aList);
notifyDataSetChanged();
}
//Create new views (invoked by the layout manager)
@Override
public ProductAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//Creating a new view
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.product_list_items,parent,false);
ViewHolder vh = new ViewHolder(v);
return vh;
}
//Replace the contents of a view (invoked by the layout manager
@Override
public void onBindViewHolder(ProductAdapter.ViewHolder holder, int position) {
// - replace the contents of the view with that element
Ad ad = adsList.get(position);
holder.tvAdName.setText(ad.getProductName());
holder.tvNoOfRating.setText(ad.getNumberOfRatings());
holder.tvMinOs.setText(ad.getMinOSVersion());
Glide.with(mContext)
.load(ad.getProductThumbnail())
.into(holder.ivPrductThumbnail);
}
@Override
public int getItemCount() {
return adsList.size();
}
}
編輯:您可能必須在ViewHolder類中聲明textview 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.