簡體   English   中英

為什么有時不調用我的 RecyclerView.ViewHolder 的 onClick 方法?

[英]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();
    }
}

完整可行的代碼鏈接在這里 LINK2

編輯:您可能必須在ViewHolder類中聲明textview

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM