先看一张图:
图中的列表是有两个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 {
private Context context;
private List outBeanList;
public RvOutAdapter(List 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 {
private List inBeanList;
public RvInAdapter(List 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源码:
内部RecyclerView的item布局 rv_in_item.xml源码:
实体类源码:
package com.lct.softkeyboard.bean;
import java.util.List;
/**
* Author:SkySmile
* Date:2018/11/7
* Description:测试类
*/
public class OutBean {
private String outItemText;
private List inBeanList;
public String getOutItemText() {
return outItemText;
}
public void setOutItemText(String outItemText) {
this.outItemText = outItemText;
}
public List getInBeanList() {
return inBeanList;
}
public void setInBeanList(List 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 outBeanList = new ArrayList<>();
for (int i = 0; i < 2; i++) {
OutBean outBean = new OutBean();
List 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源码:
如果你打算用上述代码测试,请别忘在AndroidManifest.xml文件中注册测试用的Activity。
如有疑问,欢迎留言!