内部RecyclerView与外部RecyclerView的点击事件保持一致

先看一张图:

图中的列表是有两个RecyclerVew组合成的,外部RecyclerView的LayoutManager为LinearLayoutManager,内部RecyclerView的LayoutManager为GridLayoutManager。区域1是外部Item,区域2是内部Item,区域3是内部RecyclerView。因为内部RecyclerView的item个数较少,所以才显示出了区域3。

现在如果想让三块区域的点击事件保持一致,应该怎么做呢。

下图为只给外部的RecyclerView的itemView添加点击事件之后的效果:

 

可以看到,区域2和区域3是不响应点击事件的。这是因为内部RecyclerView默认覆盖了外部RecyclerView的点击事件。

如果给内部的RecyclerView的itemView也添加上点击事件,然后把该点击回传给外部的RecyclerView,这样处理的话,你会看到只有区域1和区域2响应了点击事件,区域3依旧无法响应。

为了使3块区域整体响应一个点击事件,接下来提供一种解决方法,先看下效果图。

处理方式:给外部RecyclerView的itemView添加点击事件,给内部RecyclerView添加setOnTouchListener监听,在onTouch方法中模拟外部RecyclerIView itemView的点击事件。 

核心代码:

viewHolder.rvIn.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (event.getAction() == MotionEvent.ACTION_UP) {
                    //模拟父控件的点击
                    viewHolder.getItemView().performClick();
                }
                return false;
            }
        });

 其中getItemView方法是在ViewHolder添加的,可以在外部RecyclerView对应的Adapter源码中看到。

外部RecyclerView对应的Adapter源码:

package com.lct.softkeyboard.adapter;

import android.annotation.SuppressLint;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;

import com.lct.softkeyboard.R;
import com.lct.softkeyboard.bean.OutBean;

import java.util.List;

/**
 * Author:SkySmile
 * Date:2018/11/7
 * Description:外部RecyclerView对应的Adapter
 */
public class RvOutAdapter extends RecyclerView.Adapter<RvOutAdapter.ViewHolder> {
    private Context context;
    private List<OutBean> outBeanList;

    public RvOutAdapter(List<OutBean> outBeans) {
        this.outBeanList = outBeans;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        context = viewGroup.getContext();
        return new ViewHolder(
                LayoutInflater.from(viewGroup.getContext())
                        .inflate(R.layout.rv_out_item, viewGroup, false));
    }

    @SuppressLint("ClickableViewAccessibility")
    @Override
    public void onBindViewHolder(@NonNull final ViewHolder viewHolder, int i) {
        viewHolder.tvOut.setText(outBeanList.get(i).getOutItemText());

        viewHolder.rvIn.setLayoutManager(new GridLayoutManager(context, 5));
        viewHolder.rvIn.setAdapter(new RvInAdapter(outBeanList.get(i).getInBeanList()));
        viewHolder.rvIn.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (event.getAction() == MotionEvent.ACTION_UP) {
                    //模拟父控件的点击
                    viewHolder.getItemView().performClick();
                }
                return false;
            }
        });

        viewHolder.getItemView().setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(context, "点击了外部RecyclerView的item", Toast.LENGTH_SHORT).show();
            }
        });
    }

    @Override
    public int getItemCount() {
        return outBeanList == null ? 0 : outBeanList.size();
    }

    static class ViewHolder extends RecyclerView.ViewHolder {
        private TextView tvOut;
        private RecyclerView rvIn;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            tvOut = itemView.findViewById(R.id.tv_out);
            rvIn = itemView.findViewById(R.id.rv_in);
        }

        public View getItemView() {
            return itemView;
        }
    }
}

内部RecyclerView对应的Adapter源码:

package com.lct.softkeyboard.adapter;

import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.lct.softkeyboard.R;
import com.lct.softkeyboard.bean.OutBean;

import java.util.List;

/**
 * Author:SkySmile
 * Date:2018/11/7
 * Description:内部RecyclerView对应的源码
 */
public class RvInAdapter extends RecyclerView.Adapter<RvInAdapter.ViewHolder> {
    private List<OutBean.InBean> inBeanList;

    public RvInAdapter(List<OutBean.InBean> inBeans) {
        this.inBeanList = inBeans;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        return new ViewHolder(
                LayoutInflater.from(viewGroup.getContext())
                        .inflate(R.layout.rv_in_item, viewGroup, false));
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder viewHolder, int i) {
        viewHolder.tvIn.setText(inBeanList.get(i).getInItemText());
    }

    @Override
    public int getItemCount() {
        return inBeanList == null ? 0 : inBeanList.size();
    }


    static class ViewHolder extends RecyclerView.ViewHolder {
        private TextView tvIn;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            tvIn = itemView.findViewById(R.id.tv_in);
        }
    }
}

外部RecyclerView的item布局 rv_out_item.xml源码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginBottom="5dp"
    android:layout_marginTop="5dp"
    android:orientation="vertical">

    <TextView
        android:id="@+id/tv_out"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="#d97f7f"
        android:gravity="center_vertical"
        android:paddingLeft="5dp"
        android:paddingRight="5dp"
        tools:text="外部RecyclerView的Item" />

    <android.support.v7.widget.RecyclerView
        android:id="@+id/rv_in"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#2cb10f" />

</LinearLayout>

内部RecyclerView的item布局 rv_in_item.xml源码:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginLeft="5dp"
    android:layout_marginRight="5dp">

    <TextView
        android:id="@+id/tv_in"
        android:layout_width="wrap_content"
        android:layout_height="50dp"
        android:background="#61359e"
        android:gravity="center_vertical"
        android:paddingLeft="5dp"
        android:paddingRight="5dp"
        android:textColor="#fff"
        tools:text="内部RecyclerViewItem" />
</android.support.constraint.ConstraintLayout>

实体类源码:

package com.lct.softkeyboard.bean;

import java.util.List;

/**
 * Author:SkySmile
 * Date:2018/11/7
 * Description:测试类
 */
public class OutBean {
    private String outItemText;
    private List<InBean> inBeanList;

    public String getOutItemText() {
        return outItemText;
    }

    public void setOutItemText(String outItemText) {
        this.outItemText = outItemText;
    }

    public List<InBean> getInBeanList() {
        return inBeanList;
    }

    public void setInBeanList(List<InBean> inBeanList) {
        this.inBeanList = inBeanList;
    }

    public static class InBean {
        private String inItemText;

        public String getInItemText() {
            return inItemText;
        }

        public void setInItemText(String inItemText) {
            this.inItemText = inItemText;
        }
    }
}

测试Activity源码:

package com.lct.softkeyboard;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;

import com.lct.softkeyboard.adapter.RvOutAdapter;
import com.lct.softkeyboard.bean.OutBean;

import java.util.ArrayList;
import java.util.List;

public class RecyclerViewItemClickActivity extends AppCompatActivity {
    private RecyclerView rvOut;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_recycler_view_item_click);
        rvOut = findViewById(R.id.rv_out);

        List<OutBean> outBeanList = new ArrayList<>();
        for (int i = 0; i < 2; i++) {
            OutBean outBean = new OutBean();
            List<OutBean.InBean> inBeanList = new ArrayList<>();
            for (int j = 0; j < 2; j++) {
                OutBean.InBean inBean = new OutBean.InBean();
                inBean.setInItemText("内部Item" + j);
                inBeanList.add(inBean);
            }
            outBean.setOutItemText("外部Item" + i);
            outBean.setInBeanList(inBeanList);
            outBeanList.add(outBean);
        }

        rvOut.setLayoutManager(new LinearLayoutManager(this));
        rvOut.setAdapter(new RvOutAdapter(outBeanList));
    }
}

测试Activity对应布局 activity_recycler_view_item_click.xml源码:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".RecyclerViewItemClickActivity">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/rv_out"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</android.support.constraint.ConstraintLayout>

如果你打算用上述代码测试,请别忘在AndroidManifest.xml文件中注册测试用的Activity。

如有疑问,欢迎留言!

发布了31 篇原创文章 · 获赞 20 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/SkySmile1992/article/details/83820223
今日推荐