这是一个有点晚的答案,但可能有助于其他面临类似问题的人。我在开发customview时遇到了同样的问题,customview为手机/平板电脑扩展了自己的布局,并将其添加到视图层次结构中。对我来说,问题是使用生成的绑定对象来扩展这个自定义视图中的布局。这一切都与
ViewDataBinding.java
private static void mapBindings(DataBindingComponent bindingComponent, View view,
Object[] bindings, IncludedLayouts includes, SparseIntArray viewsWithIds,
boolean isRoot) {
final int indexInIncludes;
final ViewDataBinding existingBinding = getBinding(view);
if (existingBinding != null) {
return;
}
...
}
return语句导致映射过早退出递归函数,我的主绑定类的视图为null,因此崩溃。
class CustomContainerView : LinearLayout {
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs,
defStyleAttr)
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int,
defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes)
var binding: CustomContainerViewBinding? = null
val customViewRoot: View
init {
orientation = VERTICAL
customViewRoot= LayoutInflater.from(context)
.inflate(R.layout.custom_container_view, this, false)
addView(customViewRoot)
if (!isInEditMode) {
binding = CustomContainerViewBinding.bind(customViewRoot)
}
}
private fun relocate(child: View) {
removeView(child)
val params = child.layoutParams ?: ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT)
findViewById<ViewGroup>(R.id.contentContainer)
.addView(child, params)
}
override fun onViewAdded(child: View?) {
child?.let {
if (it != customViewRoot) {
relocate(it)
}
}
}
}
所以对我来说,罪魁祸首是这句话:
if (!isInEditMode) {
binding = CustomContainerViewBinding.bind(customViewRoot)
}
为了修复它,我只需从init块中删除上面的代码,并将其移动到延迟负载获取程序。
class CustomContainerView : LinearLayout {
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs,
defStyleAttr)
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int,
defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes)
private var customContainerBinding: CustomContainerViewBinding? = null
val customViewRoot: View
init {
orientation = VERTICAL
customViewRoot= LayoutInflater.from(context)
.inflate(R.layout.custom_container_view, this, false)
addView(customViewRoot)
}
private fun relocate(child: View) {
removeView(child)
val params = child.layoutParams ?: ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT)
findViewById<ViewGroup>(R.id.contentContainer)
.addView(child, params)
}
override fun onViewAdded(child: View?) {
child?.let {
if (it != customViewRoot) {
relocate(it)
}
}
}
fun getCustomContainerBinding(): CustomContainerViewBinding? {
if (customContainerBinding == null) {
customContainerBinding = CustomContainerViewBinding.bind(customViewRoot)
}
return customContainerBinding
}
}
private val binding : LayoutCustomViewBinding = LayoutCustomViewBinding.inflate(LayoutInflater.from(context), this, true)
所以要解决这个问题,只需遵循正常的通货膨胀方法
LayoutInflater.inflate()
class CustomView(context : Context, attrs : AttributeSet, defStyleAttrs : Int, defStylRes : Int) : RelativeLayout(context){
constructor(context : Context, attrs : AttributeSet) : this(context, attrs, 0, 0)
constructor(context : Context, attrs : AttributeSet, defStyleAttrs : Int) : this(context, attrs, defStyleAttrs, 0)
private var myMessage : String? = null
set(value){
value.let{
field = it
binding?.message = field
}
}
private val rootView : View
private val binding : LayoutCustomViewBinding?
get() = LayoutCustomViewBinding.bind(rootView)
init {
rootView = LayoutInflater.from(context)
.inflate(R.layout.layout_custom_view, this, true)
}
fun setMessage(message : String?){
myMessage = message
}
}
@BindingAdapter(value = ["message"])
fun setMessage(view : TextView, message : String?)
{
message?.let{
view.text = it
}
}
@BindingAdapter(value = ["message"])
fun setMessage(view : CustomView, message : String?)
{
message?.let{
view.message = it
}
}