【问题标题】:Attach click listener to each component of recycler view items [duplicate]将点击侦听器附加到回收器视图项的每个组件[重复]
【发布时间】:2020-01-21 03:15:21
【问题描述】:

我正在学习 Android 开发。自 24 小时以来一直在努力解决此问题,需要帮助。

在我的每个回收视图项目中,我有两个视图 ePaper 和网站。我想在整个项目、电子纸视图和网站视图上附加不同的点击监听器

在上图中,我需要放置 3 个点击监听器 1.点击红色块1 - 做X(意图另一个活动) 2. 点击红色方块 2 - 做 Y (Intent to another activity) 3. 点击绿色方块,整个项目视图 - do Z (Dialog)

尝试了许多解决方案。但是,当我点击红色块时,除了红色块中的侦听器之外,绿色块中的侦听器也会起作用。

在 MainActivity 中

recyclerView.addOnItemTouchListener(new RecyclerTouchListener(getApplicationContext(),
            recyclerView, new ClickListener() {
        String userid = Utils.getUserId(getApplicationContext());
        @Override
        public void onClick(View view, final int position) {
            // Set listeners here for complete card view
            final NewsPapersDataModel currentPaper = newsPapersList.get(position);
            Log.d("TAG","Clicked 1");

                newsSelectionDialog(currentPaper.getEpaper(),currentPaper.getWebsite());
        }
        @Override
        public void onLongClick(View view, int position) {
            Toast.makeText(MainActivity.this, "Long press on position :" + position, Toast.LENGTH_LONG).show();
        }
    }));

在 NewsPaperAdapter 中

    public void onBindViewHolder(@NonNull final CustomViewHolder holder, int position) {
    //  Log.d("TAG","Holder is "+newsList);

    final NewsPapersDataModel currentItem = newsList.get(position);
    final String ePaperUrl = currentItem.getEpaper();
    final String webSiteUrl = currentItem.getWebsite();
    final String paperName = currentItem.getName();

    holder.paperNameView.setText(newsList.get(position).getName());

    if (TextUtils.isEmpty(currentItem.getEpaper())) {
        //  Log.d("TAGG","ePaper - "+currentItem.getEpaper()+" Website - "+currentItem.getWebsite());
        holder.ePaperView.setVisibility(View.GONE);

    } else if (TextUtils.isEmpty(currentItem.getWebsite())) {
        holder.websiteView.setVisibility(View.GONE);

    }

    holder.ePaperView.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View view) {

            saveLinksToDb(userid, "ePaper", ePaperUrl);
            Intent intent = new Intent(context, NewsAdvancedWebViewActivity.class);
            intent.putExtra("url", ePaperUrl);
            context.startActivity(intent);

        }
    });

    holder.websiteView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            saveLinksToDb(userid, "Website", webSiteUrl);
            Intent intent = new Intent(context, NewsAdvancedWebViewActivity.class);
            intent.putExtra("url", webSiteUrl);
            intent.putExtra("paperName",paperName);
            context.startActivity(intent);

        }
    });

}

请帮帮我。

【问题讨论】:

标签: android


【解决方案1】:

您需要在您的适配器中为点击监听器创建一个接口,并为您想要的每个项目添加 onclick 方法。

请查看下面的代码。

在你的适配器中,创建接口

public interface OnClickListener {
    void onPaperViewClick(View view, int position);
    void onWebsiteViewClick(View view, int position);
}

并创建方法来从活动中设置点击监听器

public void setOnClickListener(OnClickListener listener) {
    this.onClickListener= listener;
}

在你的 onBindViewHolder 方法中,

holder.ePaperView.setOnClickListener(new View.OnClickListener() {

    @Override
    public void onClick(View view) {

        onClickListener.onPaperViewClick(view, position);
});

holder.websiteView.setOnClickListener(new View.OnClickListener() {

    @Override
    public void onClick(View view) {

        onClickListener.onWebsiteViewClick(view, position);
});

最后,在你的活动中,设置

recyclerViewAdapter.setOnClickListener(new NewsPaperAdapter.OnClickListener(){
    @override
    void onPaperViewClick(View view, int position){
         // code to handle paper click
    }

    @override
    void onPaperViewClick(View view, int position){
        // code to handle website click
    }
};

【讨论】:

    【解决方案2】:

    从 MainActivity 中删除您的 TouchListener 并在您的适配器中添加 ClickListener/ LonCkickListener

    onBindViewHolder(){
        //rest of your code
    
        holder.itemView.setOnClickListener(new OnClickListener{
            @Override
            public void onClick(View view) {
               // Click implementation here
            }
            @Override
            public void onLongClick(View view) {
               // Long click implementation here
            }
    
        })
    }
    

    在你的CustomViewHolder

    public class CustomViewHolder extends RecyclerView.ViewHolder{
        // Other fields
    
        View itemView;
        public CustomViewHolder(View view){
        // rest of initialization
    
        itemView = view;
        }
    }
    

    EDIT(OP 想要在 Activity 中处理应用程序逻辑)

    创建一个名为RecyclerViewActionListener的接口类:

    public interface RecyclerViewActionListener {
        void onViewClicked(int clickedViewId, int clickedItemPosition);
        void onViewLongClicked(int clickedViewId, int clickedItemPosition);
    }
    

    然后修改您的RecyclerViewAdpater 以在构造函数中添加一个附加字段。当我们创建适配器时,我们会将监听器从 Activity 传递给这个适配器:

    public class RecyclerViewAdpater extends RecyclerView.Adapter<RecyclerViewAdpater.CustomViewHolder>{
    
        private RecyclerViewActionListener mListener;
    
        public RecyclerViewAdpater(ArrayList<Object> yourData,RecyclerViewActionListener mListener) {
            this.mListener = mListener;
        }
    
        @NonNull
        @Override
        public CustomViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false );
            final CustomViewHolder holder = new CustomViewHolder(view);
    
            holder.webView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    mListener.onViewClicked(view.getId(), holder.getAdapterPosition());
                }
            });
            holder.paperView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    mListener.onViewClicked(view.getId(), holder.getAdapterPosition());
                }
            });
            holder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    mListener.onViewClicked(view.getId(), holder.getAdapterPosition());
                }
            });
            holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View view) {
                    mListener.onViewLongClicked(view.getId(), holder.getAdapterPosition());
                    return false;
                }
            });
            return holder;
        }
    
        public class CustomViewHolder extends RecyclerView.ViewHolder{
            // Other fields
    
            View itemView;
            View webView;
            View paperView;
            public CustomViewHolder(View view){
                super(view);
                // rest of initialization
    
                itemView = view;
            }
        }
    }
    

    然后在您的 Activity 中实现 RecyclerViewActionListener 并覆盖 RecyclerViewActionListener 中的方法:

    public class MainActivity extends AppCompatActivity implements RecyclerViewActionListener {
    
    
        RecyclerViewAdpater adapter;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main3);
    
            // Skipped for the sake of brevity
            // Pass your listener to adapter here
            adapter = new RecyclerViewAdpater(yourData, this );
        }
    
        @Override
        public void onViewClicked(int clickedViewId, int clickedItemPosition) {
            switch (clickedItemPosition){
                case R.id.web_view:
                    // Application logic when webview clicked
                    break;
                case R.id.paper_view:
                    // Application logic when paperview clicked
                    break;
                case R.id.recyclerview_item:
                    // Application logic when whole item clicked
                    break;
            }
        }
    
        @Override
        public void onViewLongClicked(int clickedViewId, int clickedItemPosition) {
            switch (clickedViewId){
                case R.id.recyclerview_item:
                    // Application logic when whole item long-clicked
                    break;
            }
        }
    }
    

    并且在您的 xml 文件中不要忘记为您的视图分配 ID。因为我们正在检测带有 ID 的点击视图。

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/recyclerview_item"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <ImageView
            android:id="@+id/web_view"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"/>
    
        <ImageView
            android:id="@+id/paper_view"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
    
    </RelativeLayout>
    

    【讨论】:

    • 谢谢哥们。这帮助我实现了我想要的。但是,我在一些帖子中读到,在适配器中添加点击侦听器不是一个好习惯。应该在活动中完成。请您指教一下。
    • 不要在 bindview() 上使用 onlick 对内存不好
    • @PradeepBehera,请检查编辑后的答案
    • 谢谢@Farid,我明天试试这个并告诉你。
    【解决方案3】:

    尝试在您的 NewsPaperAdapteronClickListner 中使用适配器的父布局,如下所示

    holder.parentLayout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
    
             final NewsPapersDataModel currentPaper = newsPapersList.get(position);
                Log.d("TAG","Clicked 1");
    
                    newsSelectionDialog(currentPaper.getEpaper(),currentPaper.getWebsite());
            }
        });
    

    这里parentLayout 是您的适配器项目布局根视图,例如Relative/Linear Layout

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-08-02
      • 2019-01-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-01
      • 2018-03-08
      • 1970-01-01
      相关资源
      最近更新 更多