Android:如何处理放置在RecyclerView中的ImageView上的点击事件

4
我刚从ListView转到RecyclerView,但我遇到了一个问题:我无法使ImageView的onClick事件生效。基本上,我想要的是当用户单击图片时,在新的活动中以全屏模式显示该图像。类似这样:enter image description here 我尝试过以下方法:
@Override
    public PaletteViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.
                from(parent.getContext()).
                inflate(R.layout.card_view, parent, false);

        return new PaletteViewHolder(itemView);

    }
@Override
    public void onBindViewHolder(PaletteViewHolder holder,final int position) {
        Palette palette = palettes.get(position);
        holder.text1.setText(palette.getName());
        holder.text2.setText(palette.getHexValue());
        final Context context = holder.img.getContext();
        Picasso.with(context)
                .load(DaciaData.DaciaModele[position])
                .placeholder(R.drawable.placeholder)
                .error(R.drawable.error)
                .resizeDimen(R.dimen.list_detail_image_size, R.dimen.list_detail_image_size)
                .centerInside()
                .tag(context)
                .into(holder.img);

        holder.img.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Bundle bundle = new Bundle();
                //add data to your bundle
                bundle.putInt("id", position);
                //create intent
                Intent mainIntent = new Intent(context, Extra1.class);
                //add bundle to intent
                mainIntent.putExtras(bundle);
                //start activity
                context.startActivity(mainIntent);
            }
        });
    }

EDIT

The RecyclerItemClickListener:

public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListener {
    private OnItemClickListener mListener;

    public interface OnItemClickListener {
        void onItemClick(View view, int position);
    }

    GestureDetector mGestureDetector;

    public RecyclerItemClickListener(Context context, OnItemClickListener listener) {
        mListener = listener;
        mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
            @Override public boolean onSingleTapUp(MotionEvent e) {
                return true;
            }
        });
    }

    @Override
    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {

    }

    @Override public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) {
        View childView = view.findChildViewUnder(e.getX(), e.getY());
        if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) {
            mListener.onItemClick(childView, view.getChildPosition(childView));
            return true;
        }
        return false;
    }

    @Override public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) { }
}

MainRecyclerView 这里是我定义 RecyclerViewonItemTouchListener 的地方:

@Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.recyclerModels);
        LinearLayoutManager linearLM = new LinearLayoutManager(getActivity());
        linearLM.setOrientation(LinearLayoutManager.VERTICAL);
        recyclerView.setLayoutManager(linearLM);

        recyclerView.addOnItemTouchListener(                 
                new RecyclerItemClickListener(getActivity(), new RecyclerItemClickListener.OnItemClickListener() {
                    @Override
                    public void onItemClick(View view, int position) {
                        Bundle bundle = new Bundle();
                        bundle.putInt("id", position);

                        Intent i = new Intent(getActivity(), MainViewPager.class);
                        i.putExtras(bundle);
                        startActivity(i);
                    }
                })
        );

删除recyclerView.addOnItemTouchListener();将解决图片长按的问题,但是我将无法启动ViewPager,我想可能是RecyclerItemClickListener有问题。


点击图像后会发生什么? - Raghunandan
当单击一行时,ViewPager 会启动并显示选项卡,当单击图像时,同样的事情发生,ViewPager 显示出来... - Alec
那么问题是什么呢? - Raghunandan
就像我之前所说的那样:“基本上我想要的是,当用户点击图像时,在新的活动中以全屏模式显示图像。”现在,当我点击图像时,它的行为就像我点击了行一样,它启动了错误的活动。ImageView 的 onClickListener 没有起作用。 - Alec
使用setTag和getTag - Raghunandan
更新了我的帖子。实际上,您不需要使用setTaggetTag。感谢pskink,我已经更新了我的帖子。 - Raghunandan
5个回答

2

抱歉回复晚了,我最终解决了这个问题。我所需要做的就是移除recyclerView.addOnItemTouchListener(...);,然后在我的适配器中实现View.OnClickListener,接着为TextViewImageView设置OnClickListener方法,如下所示:

public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

        protected TextView textView;
        protected ImageView imageView;

        public ContactViewHolder(View v) {
            super(v);
            textView =  (TextView) v.findViewById(R.id.t1);
            imageview = (ImageView)  v.findViewById(R.id.img);

            textView.setOnClickListener(this);
            imageview.setOnClickListener(this);
        }

        @Override
        public void onClick(View v) {    

        if (v.getId() == textView.getId()) {
          Toast.makeText(context, "TextView Clicked!", Toast.LENGTH_LONG).show();
        } else if (v.getId() == imageView.getId()) {
          Toast.makeText(context, "ImageView Clicked!", Toast.LENGTH_LONG).show();
        }
    }

0

试试这段代码,它会帮助你的:

 Intent i = new Intent(this, ShowActivity.class);
                i.putExtra("filepath", filepath.get(position));
                startActivity(i);

在下一个活动中,将此代码正确编写,您可以获取并在全屏显示图像。
 Bundle b=new Bundle();
 if(b!=null){
     String imagepath=b.getString("filepath");
 }
 Bitmap myBitmap = BitmapFactory.decodeFile(filepath.get(position));
 imageview.setImageBitmap(myBitmap);      

0
现在当我点击图片时,它会像我点击行一样,启动错误的活动。ImageView 的 onClickListener 不起作用。
请使用 setTag 和 getTag。
 holder.img.setTag(position);
 holder.img.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            Integer pos = (Integer)view.getTag(); 
            // returns an object hence the casting

            Bundle bundle = new Bundle();
            //add data to your bundle

            Log.i("Position is",""+pos.intValue);

            bundle.putInt("id", pos.intValue());
            // get int value
            //create intent
            Intent mainIntent = new Intent(context, Extra1.class);
            //add bundle to intent
            mainIntent.putExtras(bundle);
            //start activity
            context.startActivity(mainIntent);
        }
    });

编辑:

正如pskink所建议的那样,您可以通过只在ViewHolder中具有单击侦听器来消除setTag和getTag的需要。这将确保您单击正确的行项目并移动到下一个活动。

要获取位置,您可以在RecyclerView视图持有者中使用getLayoutPosition()

https://developer.android.com/reference/android/support/v7/widget/RecyclerView.ViewHolder.html#getAdapterPosition%28%29

编辑2:

代码:

  img.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

            Log.d(TAG, "Element at " + getLayoutPosition () + " clicked.");

            Bundle bundle = new Bundle();
            //add data to your bundle
            bundle.putInt("id", getLayoutPosition());
            //create intent
            Intent mainIntent = new Intent(context, Extra1.class);
            //add bundle to intent
            mainIntent.putExtras(bundle);
            //start activity
            context.startActivity(mainIntent);
            }
        });

编辑3:

你的ViewHolder类可以实现接口View.OnClickListener,而不是使用匿名内部类。

然后只需重写onClick方法并将OnClickListener设置为你的视图即可。


评论不适合进行长时间的讨论;此对话已被移至聊天室 - George Stocker
对于编辑2:我建议使用RecyclerView.ViewHolder实现View.OnClickListener,而不是创建一个内部匿名类(类PaletteViewHolder扩展RecyclerView.ViewHolder并实现View.OnClickListener)。 - pskink

0

我刚遇到了和你完全一样的问题。需要 RecyclerView 实现以下功能:

  • onItemClick
  • onItemLongClick
  • 在行内视图上实现 onClick

如果在行内视图上点击,将会触发视图的 onClick 事件以及行的 onItemClick 事件。

解决方法是,在 RecyclerView 的 onItemClick 中返回 false,并将 onClick 监听器设置为 ViewHolder 的主行布局(与在行内设置视图监听器相同,将其设置为行的主布局)。

在 RecyclerView 的 onItemClick 中返回 false。

@Override 
public boolean onSingleTapUp(MotionEvent e) {
    return false;
}

onBindViewHolder中获取你的主行布局,并在那里设置onClick事件监听器
holder.mainRowLayout.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        // Handle row item click
    }
});

这个是有效的,如果需要任何进一步的帮助,请告诉我。


-1
请使用这段代码:
holder.img.setId(position);
holder.img.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Bundle bundle = new Bundle();
                //add data to your bundle
                bundle.putInt("id", view.getId());
                //create intent
                Intent mainIntent = new Intent(context, Extra1.class);
                //add bundle to intent
                mainIntent.putExtras(bundle);
                //start activity
                context.startActivity(mainIntent);
            }
        });

出现问题了,实际上它弄乱了行:两个TextView重叠在ImageView上。 - Alec
编写OnCreateViewHolder方法 - bGorle

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接