android深拷贝,Android LayoutParams的深拷贝

// 通用的复制属性方法

private fun cloneParams(params: ViewGroup.LayoutParams): ViewGroup.LayoutParams {

val paramsClass = params.javaClass

val newInstance =

Class.forName(paramsClass.name).getConstructor(ViewGroup.LayoutParams::class.java).newInstance(

params

) as ViewGroup.LayoutParams

for (paramsField in paramsClass.declaredFields) {

if (TextUtils.equals(paramsField.name, "widget")) { // 该属性导致约束布局的后续修改,影响被复制的View属性

continue

}

paramsField.isAccessible = true

paramsField.set(newInstance, paramsField.get(params))

println("当前字段 ${paramsField.name}:${paramsField.get(params)}")

}

return newInstance

}

遇到的问题整理

对称布局提供了API直接在存在的LayoutParams对象上创建新实例,但是修改以后,原来的View也会被改变,和对Java的理解不一样

androidx.constraintlayout.widget.ConstraintLayout.LayoutParams#LayoutParams(androidx.constraintlayout.widget.ConstraintLayout.LayoutParams)

使用该API,理论上应该会深拷贝一个新的实例,修改该实例的值,不应该影响原来的View的属性,代码层面是没有修改,但是实际效果是修改了的。

目前还不清楚原因 …

原因排查:

androidx.constraintlayout.widget.ConstraintLayout.LayoutParams#widget ->

androidx.constraintlayout.solver.widgets.ConstraintWidget

猜测可能是复制了widget属性

虽然没有找到确定的证据,但从android.support.constraint.ConstraintLayout#setChildrenConstraints中可窥一二,猜测是该属性决定了子View,在父布局ConstraintLayout的一个重排机制,用于外部设置ConstraintSet去设置该属性。

f4128fcb512e

image.png

真相大白,从ConstraintLayout的布局方法中来看的话,可知道宽高以及绘制的位置取决与 ConstraintWidget , 所以如果通过反射获取对应的引用,会导致修改到原View的属性~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值