自定义LayoutManager完整教程:用MeiWidgetView快速实现StackLayoutManager卡片堆叠效果
【免费下载链接】MeiWidgetView🔥一款汇总了郭霖,鸿洋,以及自己平时收集的自定义控件集合库(小红书)项目地址: https://gitcode.com/gh_mirrors/me/MeiWidgetView
MeiWidgetView 是一款 Android 自定义控件集合库,其中的StackLayoutManager是一个开箱即用的自定义 LayoutManager:只需一行代码,就能让 RecyclerView 实现「卡片堆叠 + 滑动缩放 + 自动居中聚焦」的炫酷效果,非常适合做图片浏览、轮播卡片、功能入口等场景。本教程面向新手,带你从零理解原理并快速接入。
🎬 效果预览:卡片堆叠滑动效果长什么样
先直观感受下这个控件的三个核心特性:
- 横向滑动:卡片水平排列,中间卡片最大、最突出
- 透视缩放:离屏幕中心越远的卡片越小(最小缩到 60%),形成景深堆叠感
- 自动居中:手指一松,最近的那张卡片会自动平滑滑动到正中间"聚焦"
下面这张横向插画,就是典型适合放入这类卡片的素材内容(3:2 横版,正好适配卡片比例):
⚡ 快速上手:3 步接入卡片堆叠列表
第 1 步:准备一个横向 RecyclerView
在布局文件 mei_stack_activity.xml 中只需声明一个占满宽度的 RecyclerView:
<android.support.v7.widget.RecyclerView android:id="@+id/recycler" android:layout_width="match_parent" android:layout_height="match_parent"/>第 2 步:一行代码启用卡片堆叠布局
参考示例页面 MeiStackLayoutManagerActivity.java:
// 第二个参数是卡片间距(dp),设为负数可让卡片重叠,形成更强堆叠感 mRecyclerView.setLayoutManager(stackLayoutManager = new StackLayoutManager(this, 0));💡 官方示例里还预留了
new StackLayoutManager(this, -56)的"堆叠模式"——负间距让前后卡片相互叠压,效果更像"一摞牌"。
第 3 步:给卡片定尺寸
卡片本身是普通 View,尺寸由 item 布局决定。示例卡片 item_stack_card.xml 就是 150dp × 240dp 的竖版卡片,内部放个 TextView 即可,你可以替换成 ImageView 或更复杂的布局。
✅ 到这里,横向滑动、缩放堆叠、松手自动居中的效果就已经全部生效了,无需额外配置。
🧠 核心原理:卡片为什么能堆叠并自动聚焦
看懂原理,你才能魔改它。核心实现都在 StackLayoutManager.java 中,拆解成 3 个关键点:
1. 堆叠顺序:addView(item, 0)把后面的卡片垫底
布局时在 StackLayoutManager.java#L214-L219 中判断:位置在当前聚焦卡片之前的,正常添加;之后的则addView(item, 0)插到最底层。绘制顺序决定遮挡关系,于是后面的卡片自然"垫"在前面卡片下方,形成一摞堆叠的视觉。
2. 透视缩放:按"与中心的距离"算缩放比例
关键代码在 StackLayoutManager.java#L233-L247:
// 缩放子view:最小缩放到 0.6 final float minScale = 0.6f; final int childCenterX = (r + l) / 2; // 卡片中心 final int parentCenterX = getWidth() / 2; // RecyclerView中心 // 距离中心越远,fractionScale 越大,currentScale 越小 currentScale = 1.0f - (1.0f - minScale) * fractionScale; item.setScaleX(currentScale); item.setScaleY(currentScale);逻辑一句话总结:卡片中心离屏幕中心越远 → 缩放比例越小(最低 0.6)。滑动过程中每帧重算,缩放就跟着手指平滑变化。
3. 松手自动聚焦:离得近的那张卡"赢"
手指抬起后,在 onScrollStateChanged 中检测到 IDLE 状态,就调用 findShouldSelectPosition() 找到离落点最近的卡片索引(偏移超过一半宽度就选下一张),再用 ValueAnimator 平滑滑过去。所以无论你怎么甩,最终总有一张卡片稳稳停在正中间。
🚀 进阶技巧:点击卡片平滑滑动到指定位置
除了手动滑动,还可以编程控制焦点。公开 API 是 smoothScrollToPosition:
// 在点击事件中调用,聚焦动画结束后可执行业务逻辑 stackLayoutManager.smoothScrollToPosition(i, new StackLayoutManager.OnStackListener() { @Override public void onFocusAnimEnd() { // 例如:跳转到对应详情页 } });动画时长按滑动距离自动在 100ms~300ms 之间调节(见 startValueAnimator),短距离快、长距离慢,手感很自然。
📌 实战案例:用它搭建"功能入口"列表
本项目自己的主页入口列表 MainActivity.java 就用上了这个技巧,交互设计很值得借鉴:
- 点击已聚焦的卡片 → 直接跳转
- 点击未聚焦的卡片 → 先平滑滑动聚焦过去,
onFocusAnimEnd回调里再跳转
用户先看到卡片"滑到正中间",再进入下一个页面,转场非常流畅。
❓ 常见问题 FAQ
Q1:自定义 LayoutManager 和自定义 View 有什么区别?LayoutManager 不负责"画"什么,只负责"摆"什么——它决定每个 item 放哪里、怎么滑动、如何回收复用。卡片内容还是交给 Adapter 控制,两者分工解耦,这也是 RecyclerView 架构的核心设计。
Q2:卡片间距(gap)可以随意设置吗?可以。构造函数 StackLayoutManager(context, gap) 接收 dp 值:0表示卡片紧贴;负值让卡片重叠(堆叠模式更强);正值拉开间距。
Q3:如何知道当前聚焦的是第几张卡片?调用 findShouldSelectPosition() 即可,主页入口列表的点击判断就是用它实现的。
📁 相关文件导读
| 文件 | 说明 |
|---|---|
| StackLayoutManager.java | 核心布局管理器,约 410 行,注释清晰 |
| MeiStackLayoutManagerActivity.java | 效果演示页:彩色卡片 + 点击聚焦 |
| mei_stack_activity.xml | 演示页布局 |
| item_stack_card.xml | 卡片 item 布局 |
| MainActivity.java | 用卡片堆叠做功能入口的实战案例 |
整个LayoutManager 核心逻辑不到 500 行且注释充分,强烈建议对照本文原理章节通读一遍 StackLayoutManager.java——读懂它,你就掌握了"布局顺序 → 缩放计算 → 动画聚焦"这套自定义 LayoutManager 的完整套路 🎯
【免费下载链接】MeiWidgetView🔥一款汇总了郭霖,鸿洋,以及自己平时收集的自定义控件集合库(小红书)项目地址: https://gitcode.com/gh_mirrors/me/MeiWidgetView
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考