当前位置:网站首页>RecyclerView多布局写法,“我的”、“个人中心” 页面经典写法演示
RecyclerView多布局写法,“我的”、“个人中心” 页面经典写法演示
2022-06-10 12:54:00 【yechaoa】
效果:
多布局的使用场景还是蛮多的,比如“首页”、“我的”等页面,早期的时候大家一般都是拼起来的,后来开始自定义ListView(支付宝现在的首页还是ListView),再到后来的RecyclerView。 其实多布局都是一个套路,根据类型去引入layout,本文以RecyclerView为例,以BaseRecyclerViewAdapterHelper为辅演示多布局的写法。
1.添加依赖
compile ‘com.github.yechaoa:YUtils:2.0.6’ compile ‘com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.34’
YUtils是一个快速开发工具集合,感兴趣的可以戳 YUtils
2.主页面
主页面采用的是 ViewPager + BottomNavigationView
稍微过一下吧。。不想看的直接跳到第3步
布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent"
tools:context="com.yechaoa.multipleitempage.MainActivity">
<android.support.v4.view.ViewPager
android:id="@+id/viewPager"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="0dp" />
<android.support.design.widget.BottomNavigationView
android:id="@+id/navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:background="?android:attr/windowBackground"
app:menu="@menu/navigation" />
</LinearLayout>添加Listener让二者关联起来
mViewPager.addOnPageChangeListener(mOnPageChangeListener);
mNavigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);private ViewPager.OnPageChangeListener mOnPageChangeListener = new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
mNavigation.getMenu().getItem(position).setChecked(true);
}
@Override
public void onPageScrollStateChanged(int state) {
}
};
private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
= new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.navigation_home:
mViewPager.setCurrentItem(0);
return true;
case R.id.navigation_category:
mViewPager.setCurrentItem(1);
return true;
case R.id.navigation_cart:
mViewPager.setCurrentItem(2);
return true;
case R.id.navigation_my:
mViewPager.setCurrentItem(3);
return true;
}
return false;
}
};ViewPager选中的时候让BottomNavigationView的item也选中,BottomNavigationView的item选中的时候让ViewPager切换page
3.Fragment(“我的”页面)
布局,SwipeRefreshLayout(下拉刷新)嵌套RecyclerView:
<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/swipeRefreshLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.v4.widget.SwipeRefreshLayout>初始化Data
private void initItemData() {
itemDataList = new ArrayList<>();
multipleItem = new MultipleItem(MultipleItem.TYPE_COUNT, 5);
multipleItem.mString1 = "收藏";
multipleItem.mString2 = "关注";
itemDataList.add(multipleItem);
multipleItem = new MultipleItem(MultipleItem.TYPE_ORDER_HEADER, 5);
multipleItem.mString2 = "type2";
itemDataList.add(multipleItem);
for (int i = 0; i < 5; i++) {
multipleItem = new MultipleItem(MultipleItem.TYPE_ORDER, 1);
multipleItem.mString1 = "待付款";
if (i % 2 == 0) {
multipleItem.isShow = true;
multipleItem.count = 6;
} else {
multipleItem.isShow = false;
multipleItem.count = 0;
}
itemDataList.add(multipleItem);
}
multipleItem = new MultipleItem(MultipleItem.TYPE_BALANCE, 5);
multipleItem.mString1 = "¥9999.00";
itemDataList.add(multipleItem);
multipleItem = new MultipleItem(MultipleItem.TYPE_TOOLS_HEADER, 5);
multipleItem.mString1 = "type5";
itemDataList.add(multipleItem);
for (int i = 0; i < 5; i++) {
multipleItem = new MultipleItem(MultipleItem.TYPE_TOOLS, 1);
multipleItem.mString1 = "使用帮助";
if (i % 2 == 0) {
multipleItem.isShow = true;
multipleItem.count = 100;
} else {
multipleItem.isShow = false;
multipleItem.count = 0;
}
itemDataList.add(multipleItem);
}
}获取id
mSwipeRefreshLayout = getActivity().findViewById(R.id.swipeRefreshLayout);
mRecyclerView = getActivity().findViewById(R.id.recyclerView);初始化SwipeRefreshLayout
private void initSwipeRefreshLayout() {
mSwipeRefreshLayout.setColorSchemeResources(
android.R.color.holo_blue_bright,
android.R.color.holo_green_light,
android.R.color.holo_orange_light);
mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
multipleItemQuickAdapter.notifyDataSetChanged();
mSwipeRefreshLayout.setRefreshing(false);
YUtils.showToast("刷新完成");
}
}, 2000);
}
});
}初始化RecyclerView
private void initRecyclerView() {
GridLayoutManager gridLayoutManager = new GridLayoutManager(getActivity(), 5);
mRecyclerView.setLayoutManager(gridLayoutManager);
multipleItemQuickAdapter = new MultipleItemQuickAdapter(itemDataList);
View headerView = getHeaderView(new View.OnClickListener() {
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.my_header_image:
YUtils.showToast("你点击了头像");
break;
case R.id.my_header_settings:
YUtils.showToast("你点击了设置");
break;
}
}
});
multipleItemQuickAdapter.addHeaderView(headerView);
mRecyclerView.setAdapter(multipleItemQuickAdapter);
}添加Header
private View getHeaderView(View.OnClickListener listener) {
View headerView = getLayoutInflater().inflate(R.layout.layout_my_header, (ViewGroup) mRecyclerView.getParent(), false);
CircleImageView myHeaderImage = headerView.findViewById(R.id.my_header_image);
myHeaderImage.setImageResource(R.drawable.header_image);
myHeaderImage.setOnClickListener(listener);
TextView myHeaderName = headerView.findViewById(R.id.my_header_name);
myHeaderName.setText("名字");
TextView myHeaderMobile = headerView.findViewById(R.id.my_header_mobile);
myHeaderMobile.setText("手机号");
ImageView myHeaderSettings = headerView.findViewById(R.id.my_header_settings);
myHeaderSettings.setOnClickListener(listener);
return headerView;
}初始化Listener
private void initListener() {
multipleItemQuickAdapter.setSpanSizeLookup(new BaseQuickAdapter.SpanSizeLookup() {
@Override
public int getSpanSize(GridLayoutManager gridLayoutManager, int position) {
return itemDataList.get(position).getSpanSize();
}
});
multipleItemQuickAdapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() {
@Override
public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
YUtils.showToast("第 " + position);
//可以再加一层 类型 的判断,一般来说订单不是点了就消失的
if (itemDataList.get(position).getItemType() == MultipleItem.TYPE_TOOLS) {
if (itemDataList.get(position).isShow) {
itemDataList.get(position).isShow = false;
LogUtil.i("count = " + itemDataList.get(position).count);
multipleItemQuickAdapter.notifyItemChanged(position + 1);
} else
itemDataList.get(position).isShow = false;
}
}
});
multipleItemQuickAdapter.setOnItemChildClickListener(new BaseQuickAdapter.OnItemChildClickListener() {
@Override
public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {
switch (view.getId()) {
case R.id.my_favorites:
YUtils.showToast("收藏");
break;
case R.id.my_bands:
YUtils.showToast("关注");
break;
case R.id.ll_my_order:
YUtils.showToast("全部订单");
break;
case R.id.my_balance_btn:
YUtils.showToast("立即充值");
break;
}
}
});
}如果考虑到在GridLayoutManager复用item问题可以配置setSpanSizeLookup setOnItemClickListener,item点击事件 setOnItemChildClickListener,item里面的子view点击事件 item点击的时候,角标(徽章)消失,然后局部刷新
4.Bean
实体类必须实现MultiItemEntity,在设置数据的时候,需要给每一个数据设置itemType
public class MultipleItem implements MultiItemEntity {
public static final int TYPE_COUNT = 1;
public static final int TYPE_ORDER_HEADER = 2;
public static final int TYPE_ORDER = 3;
public static final int TYPE_BALANCE = 4;
public static final int TYPE_TOOLS_HEADER = 5;
public static final int TYPE_TOOLS = 6;
private int itemType;
private int spanSize;
public MultipleItem(int itemType, int spanSize) {
this.itemType = itemType;
this.spanSize = spanSize;
}
@Override
public int getItemType() {
return itemType;
}
public int getSpanSize() {
return spanSize;
}
public void setSpanSize(int spanSize) {
this.spanSize = spanSize;
}
public String mString1;
public String mString2;
public boolean isShow;
public int count;
}5.Adapter
多布局关键写法就在Adapter里面,根据类型返回不同的layout,然后填充数据、处理事件等等。 在构造里面addItemType绑定type和layout的关系
public class MultipleItemQuickAdapter extends BaseMultiItemQuickAdapter<MultipleItem, BaseViewHolder> {
public MultipleItemQuickAdapter(List data) {
super(data);
addItemType(MultipleItem.TYPE_COUNT, R.layout.layout_my_count);
addItemType(MultipleItem.TYPE_ORDER_HEADER, R.layout.layout_my_order_header);
addItemType(MultipleItem.TYPE_ORDER, R.layout.layout_my_order);
addItemType(MultipleItem.TYPE_BALANCE, R.layout.layout_my_balance);
addItemType(MultipleItem.TYPE_TOOLS_HEADER, R.layout.layout_my_tools_header);
addItemType(MultipleItem.TYPE_TOOLS, R.layout.layout_my_tools);
}
@Override
protected void convert(BaseViewHolder helper, MultipleItem item) {
switch (helper.getItemViewType()) {
case MultipleItem.TYPE_COUNT:
helper.setText(R.id.my_favorites, item.mString1).addOnClickListener(R.id.my_favorites);
helper.setText(R.id.my_bands, item.mString2).addOnClickListener(R.id.my_bands);
break;
case MultipleItem.TYPE_ORDER_HEADER:
helper.addOnClickListener(R.id.ll_my_order);
break;
case MultipleItem.TYPE_ORDER:
helper.setImageDrawable(R.id.my_order_image, ContextCompat.getDrawable(mContext, R.drawable.ic_launcher));
helper.setText(R.id.my_order_name, item.mString1);
if (item.isShow) {
helper.getView(R.id.my_order_count).setVisibility(View.VISIBLE);
if (item.count > 0) {
if (item.count < 99) {
helper.setText(R.id.my_order_count, String.valueOf(item.count));
} else {
helper.setText(R.id.my_order_count, String.valueOf("99+"));
}
} else {
helper.getView(R.id.my_order_count).setVisibility(View.GONE);
}
} else {
helper.getView(R.id.my_order_count).setVisibility(View.GONE);
}
break;
case MultipleItem.TYPE_BALANCE:
helper.setText(R.id.my_balance_text, item.mString1);
helper.addOnClickListener(R.id.my_balance_btn);
break;
case MultipleItem.TYPE_TOOLS_HEADER:
//helper.setText(R.id.tv_item_name, item.mString1);
break;
case MultipleItem.TYPE_TOOLS:
helper.setImageDrawable(R.id.my_tools_image, ContextCompat.getDrawable(mContext, R.drawable.ic_launcher));
helper.setText(R.id.my_tools_text, item.mString1);
if (item.isShow) {
helper.getView(R.id.my_tools_count).setVisibility(View.VISIBLE);
if (item.count > 0) {
if (item.count < 99) {
helper.setText(R.id.my_tools_count, String.valueOf(item.count));
} else {
helper.setText(R.id.my_tools_count, String.valueOf("99+"));
}
} else {
helper.getView(R.id.my_tools_count).setVisibility(View.GONE);
}
} else {
helper.getView(R.id.my_tools_count).setVisibility(View.GONE);
}
break;
}
}item的layout就不用贴了吧,就一般的布局。。 角标(徽章)的话没用BadgeView,只直接用ImageView写的。 Demo是从项目里抽出来的,好像也没什么要注意的了吧。。忘了。。
Demo:https://github.com/yechaoa/MultipleItemPage
边栏推荐
- 数码管驱动芯片+语音芯片的应用场景介绍,WT588E02B-24SS
- 【Spark】(task8)SparkML中的pipeline通道建立
- 讓資源在雲端和本地自由流動
- Baidu programmers were sentenced to nine months for deleting the database. The one click unbinding function of the mobile phone number was released. Twitter compromised with musk again. Today, more bi
- Qt: 访问其他窗体中的控件
- Don't mistake "it informatization" for "super project"
- No spitting
- CardView使用及属性
- Ekuiper newsletter 2022-05 protobuf codec support, visual drag and drop writing rules
- How to write code that is not easy to overflow memory
猜你喜欢

Some words from ShareIt group

Qt数据库应用22-文件编码格式识别
![buuctf [PHP]inclusion](/img/02/d328ed84e4641c09c5b1eba3ac6ea9.png)
buuctf [PHP]inclusion

Introduction to assembly language - Summary

JS click the button to slide to the left

How can the team be dissolved...

NanoMQ Newsletter 2022-05|v0.8.0 发布,新增 WebHook 拓展接口和连接认证 API

Which EDA design software should Altium Allegro pads choose

Shi Yigong and other teams posted on the cover of Science: AI and freeze electron microscope revealed the structure of "atomic level" NPC, a breakthrough in life science

Leetcode 96. Different binary search trees
随机推荐
How does the API detect security configuration errors?
[spark] (task8) pipeline channel establishment in sparkml
CL210OpenStack操作的故障排除--常见核心问题的故障排除
13、 System call and shell (freesanding shell, terminal and job control)
Nanomq newsletter 2022-05 | release of V0.8.0, new webhook extension interface and connection authentication API
The deep neural network classifies nearly 2billion images per second, and the new brain like optical classifier chip is on nature
[Accessibility] Missing contentDescription attribute on image
The ability to register user names and passwords with the database
If the files and graphics are lost, it means that you don't need the office developed by yourself
Leetcode 96. Different binary search trees
Asynchronous export of Excel
[golang] when creating a structure with configuration parameters, how should the optional parameters be transferred?
Neuron Newsletter 2022 - 05 | ajout de 2 entraînements Sud et 1 Application Nord, mise en œuvre de l'extension personnalisée par Modbus TCP
No spitting
OFFICE技术讲座:标点符号-中文-竖排
3. 网页开发工具 VS Code
Unity3d uses URP rendering pipeline to realize ar shadow (shadow casting and transparent ground)
Error:top-left corner pixel must be either opaque white or transparent.
Performance test plan (plan) template
[flinlk] dynamic Kerberos authentication in Flink pit