layoutParams.width=100; 这100到底是dp、pt、px.....? 如果要设置成200px宽,layoutParams.width该等于多少?

博客提到代码里宽高数值100指的是px,且代码里的宽高几乎都采用px单位,这属于前端开发中关于单位使用的内容。
这个100指的是px,代码里的宽高几乎都是px的
你的怀疑是**非常合理且专业的**!你提到的这段代码: ```kotlin val skeletonRV = RecyclerView(view.context).apply { layoutParams = view.layoutParams if (config.recyclerOrientation == Orientation.HORIZONTAL) { layoutParams.height = itemView.measuredHeight layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT } } ``` 我们来重点分析这个问题: > ❓ **`layoutParams = view.layoutParams` 是否会修改原 `view` 的 `layoutParams`?** --- ### ✅ 答案:**是的,会!这正是一个典型的“引用共享”陷阱。** 因为 `ViewGroup.LayoutParams` 是**引用类型(对象)**,当你写: ```kotlin layoutParams = view.layoutParams ``` 你并没有创建一个新的 `LayoutParams` 对象,而是让 `skeletonRV` 的 `layoutParams` **指向同一个对象实例**。 所以后续操作: ```kotlin layoutParams.height = ... layoutParams.width = ... ``` 实际上是在**直接修改原来 `view` 所使用的 `LayoutParams` 实例**! 这意味着: - 原始 `view` 的高度和度也会被改变! - 可能导致原始布局错乱、尺寸异常等问题。 - 这是一个隐蔽但严重的副作用 bug。 --- ### 🔍 示例说明 假设 `view` 原本的 `layoutParams.height = 200dp`,你在 `skeletonRV` 中执行了: ```kotlin layoutParams.height = itemView.measuredHeight // 比如设为 100 ``` 那么: ➡️ `view.layoutParams.height` 也变成了 `100`! ➡️ 原始 `view` 的显示尺寸可能因此被压缩或拉伸! --- ### ✅ 正确做法:**必须克隆(copy)`layoutParams`** 你应该创建一份 `LayoutParams` 的副本,而不是共享引用。 #### ✔️ 修改方式如下: ```kotlin val skeletonRV = RecyclerView(view.context).apply { layoutParams = view.layoutParams.copy() // 关键:复制一份新的 LayoutParams if (config.recyclerOrientation == Orientation.HORIZONTAL) { // 现在修改的是副本,不会影响原 view layoutParams.height = itemView.measuredHeight layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT } } ``` 但注意:`copy()` 方法不是所有 `LayoutParams` 都自带,你需要手动创建同类型的新实例并复制值。 #### ✅ 推荐写法(安全克隆): ```kotlin val originalParams = view.layoutParams val newParams = when (originalParams) { is LinearLayout.LayoutParams -> LinearLayout.LayoutParams(originalParams) is RelativeLayout.LayoutParams -> RelativeLayout.LayoutParams(originalParams) is ConstraintLayout.LayoutParams -> ConstraintLayout.LayoutParams(originalParams) is FrameLayout.LayoutParams -> FrameLayout.LayoutParams(originalParams) else -> ViewGroup.LayoutParams(originalParams.width, originalParams.height) } val skeletonRV = RecyclerView(view.context).apply { layoutParams = newParams if (config.recyclerOrientation == Orientation.HORIZONTAL) { layoutParams.height = itemView.measuredHeight layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT } } ``` > 💡 注意:像 `new LinearLayout.LayoutParams(existingParams)` 这种构造函数是 Android 提供的**拷贝构造函数**,专门用于复制现有参数。 --- ### 🛠️ 补充建议 - 如果你不改尺寸,只是想继承高,可以直接用: ```kotlin layoutParams = ViewGroup.LayoutParams( originalParams.width, originalParams.height ) ``` 但这会丢失具体布局类型的额外属性(如 margin、gravity、约束等)。 - 若涉及 `margin`,你还得单独处理: ```kotlin val margins = originalParams as? ViewGroup.MarginLayoutParams val newParams = FrameLayout.LayoutParams(originalParams) newParams.setMargins(margins?.leftMargin ?: 0, ...) ``` --- ### ✅ 总结 | 问题 | 回答 | |------|------| | `layoutParams = view.layoutParams` 是否共享引用? | ✅ 是,完全共享同一个对象 | | 修改 `skeletonRV.layoutParams` 会影响原 `view` 吗? | ✅ 会!这是严重副作用 | | 如何避免? | ❌ 不要直接赋引用;✅ 使用拷贝构造函数创建新实例 | | 推荐方案? | 根据 `LayoutParams` 类型使用对应的拷贝构造器 | > ⚠️ **结论:你怀疑得完全正确——这是典型的引用污染问题,必须通过深拷贝(克隆)解决。** ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值