android - 更改 customView 的层次结构时数据绑定中的 NPE 崩溃
问题描述
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.widget.FrameLayout
class MyCustomView @JvmOverloads constructor(context: Context, attributeSet: AttributeSet? = null) : FrameLayout(
context,
attributeSet
) {
val binding = MylayoutBinding.inflate(
LayoutInflater.from(context),
this,
true
)
}
// mylayout.xml
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<merge>
<FrameLayout
android:id="@+id/myChildContainer"
android:layout_width="100dp"
android:layout_height="100dp"/>
</merge>
</layout>
我在下面的表格中使用我的自定义视图。
// myactivity.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<FrameLayout android:layout_width="match_parent" android:layout_height="match_parent">
<MyCustomView
android:id="@+id/myView"
android:layout_width="300dp"
android:layout_height="300dp">
<Button
android:id="@+id/myButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</MyCustomView>
</FrameLayout>
</layout>
在上面的示例中,我希望 myButton 作为 myChildContainer 的子项进入 MyCustomView。
我遵循了android 中的示例:如何将 xml 布局中的子项添加到自定义视图中,并修改了 MyCustomView,如下所示。
class MyCustomView @JvmOverloads constructor(context: Context, attributeSet: AttributeSet? = null) : FrameLayout(
context,
attributeSet
) {
val binding = MylayoutBinding.inflate(
LayoutInflater.from(context),
this,
true
)
override fun onFinishInflate() {
super.onFinishInflate()
while (childCount > 1) {
val child = getChildAt(1)
val param = child.layoutParams
removeView(child)
binding.myChildContainer.addView(child, param)
}
}
}
如果我不应用数据绑定,这段代码很好。
问题是当我应用数据绑定时应用程序崩溃了。
internal class MyActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = DataBindingUtil.setContentView<MyactivityBinding>(this, R.layout.myactivity)
binding.myButton.text = "Test Text" <-- crash
}
}
Caused by: java.lang.NullPointerException: binding.myButton must not be null
当我将代码的remove view和addview的执行点从onFinishInflate更改为onAttachedToWindow时,一般不会出现错误,但是我已经确认它会间歇性地重复出现,所以我认为这不是一个解决方案。
有什么方法可以在保留 DataBinding 的同时将子视图添加到 CustomView?
我实际上使用了多个这样的视图,所以我不想在 setContentView 之后调用诸如 myView.sortView() 之类的单个函数。
解决方案
推荐阅读
- scala - 未生成反向路由
- html - 在css中为不同的视频添加视频源
- python - Python:使用不同大小的数据框根据日期时间条件创建新列
- cypress - Cypress - 带有请求有效负载的 API 调用 - 如何在代码中处理有效负载
- coq - 对于 Coq 中的异构列表,是否可以证明与 Forall_inv 等效?
- c# - Oracle c# 大容量复制Datatable
- android - 未处理的异常:SocketException:操作系统错误:连接被拒绝,errno = 111,地址 = 127.0.0.1,端口 = 40712
- c++ - 在每个元音上添加字符
- ios - 当我们尝试使用 Appium 脚本导航到 iPhone safari 浏览器中的框架时,获取异常阻止了一个具有原点的框架
- django - Ajax 请求导致内部服务器错误