随着公司自用app客户端功能&
需求越来越复杂,某些页面的布局也越来越复杂。在前同事的建议下,使用RecyclerView来实现。
需求
大概需求如下图,需要通过登录用户的权限来展示这个表格布局。
方案
- 请求服务端登录接口,返回用户信息、角色信息、权限等
- APP端根据权限组装数据传到Adapter
- 渲染视图
实现
在主页布局适合的布局添加以下布局代码
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/workbench_recycleview"
android:divider="#00000000"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/shape_bg"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:layout_marginBottom="15dp">
</androidx.recyclerview.widget.RecyclerView>定义item布局,代表每个item的布局样式等
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical"
android:layout_marginTop="25dp"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="标题"
android:id="@+id/wb_menu_txt_title"
android:textSize="16sp"
android:textStyle="bold"
android:textColor="#555555"/>
<ImageView
android:layout_width="36dp"
android:layout_height="36dp"
android:id="@+id/wb_menu_img_title"
android:src="@mipmap/wk_ck"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="20dp"
android:orientation="vertical"
android:layout_marginBottom="25dp"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="这是一段说明"
android:id="@+id/wb_menu_txt_info"
android:textSize="14sp"
android:textColor="#999999"/>
</LinearLayout>
</LinearLayout>预览效果如下
定义Holder类,继承
RecyclerView.ViewHolder
public class WorkBenchItemViewHolder extends RecyclerView.ViewHolder {
private final TextView txtTitle;
private final TextView txtInfo;
private final ImageView imgTitle;
public WorkBenchItemViewHolder(View view){
super(view);
txtTitle = view.findViewById(R.id.wb_menu_txt_title);
txtInfo = view.findViewById(R.id.wb_menu_txt_info);
imgTitle = view.findViewById(R.id.wb_menu_img_title);
}
public TextView getTxtInfo(){
return this.txtInfo;
}
public ImageView getImg(){
return this.imgTitle;
}
public TextView getTxtTitle(){
return txtTitle;
}
}定义
Adapter
类,继承RecyclerView.Adapter<WorkBenchItemViewHolder>
public class WorkBenchItemViewAdapter extends RecyclerView.Adapter<WorkBenchItemViewHolder> {
public List<WorkbenchMenuBean> mDatas;
private final Context mContext;
private OnItemClickListener listener;
public WorkBenchItemViewAdapter(Context context, List<WorkbenchMenuBean> datas) {
this.mContext = context;
this.mDatas = datas;
}
public WorkBenchItemViewHolder onCreateViewHolder(int viewType) { ViewGroup parent,
return new WorkBenchItemViewHolder(LayoutInflater.from(mContext).inflate(R.layout.home_workbench_item_view, parent,
false));
}
public void onBindViewHolder(WorkBenchItemViewHolder holder, final int position) {
holder.getTxtTitle().setText(mDatas.get(position).getTxtTitle());
holder.getTxtInfo().setText(mDatas.get(position).getTxtInfo());
holder.getImg().setImageResource(mDatas.get(position).getImgTitle());
if (listener != null) {
holder.itemView.setOnClickListener(view -> listener.onItemClick(view, position));
}
}
public int getItemCount() {
return mDatas.size();
}
//第二步, 写一个公共的方法
public void setOnItemClickListener(OnItemClickListener listener) {
this.listener = listener;
}
public interface OnItemClickListener {
void onItemClick(View view, int position);
}
}在对应的页面初始化页面逻辑处添加处理逻辑
定义相关属性
private RecyclerView recyclerView;
private WorkBenchItemViewAdapter adapter;
private List<WorkbenchMenuBean> listData = new ArrayList<>();定义获取列表的方法
// 通过登录后获取的角色判断
// 这里展示如果是超级账号的情况
boolean superAccount = loginInfo.isSuperAccount();
if (superAccount) {
listData.add(new WorkbenchMenuBean("pb", "功能1", "功能1描述", R.mipmap.wk_pb));
listData.add(new WorkbenchMenuBean("zj", "功能2", "。。。", R.mipmap.wk_zj));
listData.add(new WorkbenchMenuBean("sc", "功能3", "。。。", R.mipmap.wk_sc));
listData.add(new WorkbenchMenuBean("ck", "功能4", "。。。", R.mipmap.wk_ck));
listData.add(new WorkbenchMenuBean("sk", "功能5", "。。。", R.mipmap.wk_sk));
return;
}这里更好的处理方法是这些data也通过服务端返回,客户端只管处理
调用recyclerView的其他api
// 设置LayoutManager
recyclerView.setLayoutManager(new GridLayoutManager(getContext(), 2));
recyclerView.addItemDecoration(new CommonDecoration(Objects.requireNonNull(getContext())));
adapter = new WorkBenchItemViewAdapter(getContext(), listData);
// 设置点击事件
adapter.setOnItemClickListener((view, position) -> {
WorkbenchMenuBean workbenchMenuBean = adapter.mDatas.get(position);
onWorkbenchMenuItemClick(workbenchMenuBean);
});
recyclerView.setAdapter(adapter);
常用方法
1、获取recyclerView内容高度
// 获取recyclerView内容高度 |
我们通过recyclerView.getHeight方法获取到的高度是RecyclerView控件的高度,不是内容高度
2、获取adapter中的item总个数
int size = recyclerView.getAdapter().getItemCount(); |
3、获取recyclerView可见的item数量
int childCount = recyclerView.getChildCount(); |
4、获取某个Item的实际position
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); |
5、根据position获取对应的Item的View,需要注意的是,如果当前position对应的View不可见,获取到的View为null。
// llm为对应的LayoutManager |
6、获取第一个可见的Item的position
int firstPosition = ((LinearLayoutManager)recyclerView.getLayoutManager()).findFirstVisibleItemPosition(); |
7、获取第一个完全可见的Item的position
int firstCompletelyVisibleItemPosition = ((LinearLayoutManager)recyclerView.getLayoutManager()).findFirstCompletelyVisibleItemPosition(); |
8、获取最后一个可见的Item的position
int lastPosition = ((LinearLayoutManager)recyclerView.getLayoutManager()).findLastVisibleItemPosition(); |
9、获取最后一个完全可见的Item的position
int lastCompletelyVisibleItemPosition = ((LinearLayoutManager)parent.getLayoutManager() |