目录
功能说明
设计流程
核心代码详解
总结
源码开源地址(gitee)
一、功能说明
1.在微信通讯录页面添加列表项,使用RecycleView实现二级列表
2.在上一列表页面的基础上进行点击跳转设计
二、设计流程
1.item设计
为RecyclerView内的元素设定xml样式,将二级列表分为两个部分——父列表以及可折叠的子列表,因此需要设计两类item,分别表示父子列表
item_child
item_parent
2.Adapter
(1)搭建二级列表框架,对控件做点击事件,点击展开或点击闭合
(2)实现点击跳转
3.结果(点击联系人跳转至微信界面)
三、核心代码详解
1.Fragment.java
获取RecyclerView对象,初始化数据,实例化适配器,设置线性排列,控件水平放置
public class Fragment2 extends Fragment {
RecyclerView rvContent;
Myadpter myadpter;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
/*
原本文件中无view的相关方法
但,原文件中最后结果返回view,可进行拆分,引入view相关方法
*/
View view;
// Inflate the layout for this fragment
view=inflater.inflate(R.layout.fragment_2, container, false);
rvContent=view.findViewById(R.id.rv_content);
//初始化数据
List<IType> data=new ArrayList<>();
{
for (int i = 0; i < 4; i++) {
DataBean.ParentBean parentBean = new DataBean.ParentBean();
parentBean.setTitle("分组"+i);
List<DataBean.ChildBean> childData=new ArrayList<>();
for (int j = 0; j < 5; j++) {
DataBean.ChildBean childBean = new DataBean.ChildBean();
childBean.setTitle("联系人"+j);
childData.add(childBean);
}
parentBean.setChild(childData);
data.add(parentBean);
}
}
//获取变量的环境值
Context context=getContext(); //下述需要两个context,统一context
myadpter=new Myadpter(data,context);
LinearLayoutManager manager=new LinearLayoutManager(context);
manager.setOrientation(RecyclerView.VERTICAL);
rvContent.setLayoutManager(manager); // 线性排列 控件水平/垂直铺开
rvContent.setAdapter(myadpter);
return view;
}
}
2. Myadapter.java
(1)返回item位置的视图类型,以便进行视图回收。
@Override
public int getItemViewType(int position) {
TypeEnum itemType = data.get(position).getItemType();
if (itemType == TypeEnum.TYPE_PARENT) {
return TYPE_PARENT;
} else if (itemType == TypeEnum.TYPE_CHILD) {
return TYPE_CHILD;
}
return super.getItemViewType(position);
}
(2) 构建ViewHolder,返回每一项的布局
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
/*
构建ViewHolder,返回每一项的布局
inflater:将xml文件压缩为view
*/
if (viewType == TYPE_PARENT) {
return new ParentHolder(LayoutInflater.from(context).inflate(R.layout.item_parent, parent, false));
} else if (viewType == TYPE_CHILD) {
return new ChildHolder(LayoutInflater.from(context).inflate(R.layout.item_child, parent, false));
}
return null;
}
(3) 绑定数据和空间,实现点击操作,点击跳转至微信界面
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, @SuppressLint("RecyclerView") int position) {
/*
将数据和控件绑定
*/
//若ParentHolder是holder的实例...
if (holder instanceof ParentHolder) {
ParentHolder parentHolder = (ParentHolder) holder;
DataBean.ParentBean parentBean = (DataBean.ParentBean) data.get(position);
// 对控件做点击事件 点击展开/闭合
parentHolder.tvContent.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//若当前是展开状态,点击完之后是闭合状态
if (parentBean.isExpand()) {
closeItem(position);
} else {
openItem(position);
}
parentBean.setExpand(!parentBean.isExpand());
}
});
//绑定数据
DataBean.ParentBean parentData = (DataBean.ParentBean) data.get(position);
parentHolder.tvContent.setText(parentData.getTitle());
}
//若ChildHolder是holder的实例...
if (holder instanceof ChildHolder) {
ChildHolder childHolder = (ChildHolder) holder;
DataBean.ChildBean childBean = (DataBean.ChildBean) data.get(position);
// 对控件做点击事件 点击跳转
childHolder.tvContent.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (Objects.equals(childBean.getTitle(), "联系人0")) {
Intent Intent0 = new Intent(context,Fragment1.class);
context.startActivity(Intent0);
}
}
});
childHolder.tvContent.setText(childBean.getTitle());
}
}
(4) 创建内部类即RecyclerView.ViewHolder类的子类,并初始化item的控件
public static class ParentHolder extends RecyclerView.ViewHolder {
/*
内部类,绑定控件
*/
private final TextView tvContent;
public ParentHolder(@NonNull View itemView) {
super(itemView);
tvContent = itemView.findViewById(R.id.parent_content);
}
}
public static class ChildHolder extends RecyclerView.ViewHolder {
/*
内部类,绑定控件
*/
private final TextView tvContent;
public ChildHolder(@NonNull View itemView) {
super(itemView);
tvContent = itemView.findViewById(R.id.child_content);
}
}
(5) 实现列表的展开和合并
//展开
private void openItem(int position) {
DataBean.ParentBean parentBean = (DataBean.ParentBean) data.get(position);
List<DataBean.ChildBean> child = parentBean.getChild();
data.addAll(position + 1, child);
//展开动画
notifyItemRangeInserted(position + 1, child.size());
notifyItemRangeChanged(position + 1, child.size());
}
//闭合
private void closeItem(int position) {
DataBean.ParentBean parentBean = (DataBean.ParentBean) data.get(position);
List<DataBean.ChildBean> child = parentBean.getChild();
data.removeAll(child);
//闭合动画
notifyItemRangeRemoved(position + 1, child.size());
notifyItemRangeChanged(position + 1, child.size());
}
四、总结
RecyclerView可以显示大量数据,包含与数据对应的视图,但是在创建 ViewHolder时,它并没有任何关联的数据,在创建之后才会进行数据绑定。
onCreateViewHolder()方法会创建并初始化 ViewHolder 及其关联的 View,但是此时尚未绑定具体数据;其中需要重写RecyclerView.Adapter类的onBindViewHolder()方法,将ViewHolder与数据相关联。
除了基础的配置外,RecyclerView也可实现上拉刷新下拉加载等更多的功能,功能非常强大。
五、源码开源地址(gitee)