如何在包含视图中使用View Binding?

20

View Binding于v3.6发布。

文档: https://developer.android.com/topic/libraries/view-binding

我的问题是,有人知道如何在包含布局中使用view binding吗?

给定包含另一个布局的布局。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <include
        android:id="@+id/my_header"
        layout="@layout/item_header"
        android:layout_width="match_parent"
        android:layout_height="100dp" />

</LinearLayout>

我正在尝试引用item_header布局内的项目。

binder.my_header (<-- this just returns back the view)
binder.root (<-- this just returns back the root view)

即使我给item_header的根添加一个id,比如id="@+id/parent_id"并试图引用它,我仍然会收到空指针异常。

binder.parentId (<-- I have access to views inside of the item_header, however, I receive exceptions. Says that "parentId" cannot be found)

如何引用布局中的item_header


2
在我刚刚运行的实验中,binder.my_header 是一个 ItemHeaderBinding,而不是一个 View。我可以轻松地引用其中的小部件(例如,binder.my_header.foo)。 - CommonsWare
@CommonsWare 你太棒了!我没想到我可以引用那个。现在它完美地工作了。您介意将您的评论发布为答案吗?我会接受的。 - portfoliobuilder
这是一个重复的问题。请查看我的答案,链接在这里:https://dev59.com/C1MH5IYBdhLWcg3wqhLz#60616894 - Emad Razavi
2个回答

19

假设你的问题中使用的布局文件为activity_main.xml,生成的视图绑定类名为ActivityMainBinding。同样地,对于item_header.xml,生成的视图绑定类名为ItemHeaderBinding

如果我们假设item_header.xml中有一个名为@+id/fooTextView,那么你将得到以下 Kotlin 代码:

class MainActivity : AppCompatActivity() {

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    val mainBinding = ActivityMainBinding.inflate(layoutInflater)

    setContentView(mainBinding.root)

    mainBinding.myHeader.foo.text = "this is a test"
  }
}
因此,ActivityMainBinding对象应该有一个具有<include>中给出的android:id属性,即这种情况下的myHeader。那应该是一个ItemHeaderBinding,因为视图绑定似乎已经为<include>设置了嵌套绑定对象。由于myHeader是一个ItemHeaderBinding,所以您可以像直接膨胀ItemHeaderBinding一样引用其上的小部件。 请注意,视图绑定似乎将lower_snake_case转换为lowerCamelCase,因此my_header ID在生成的代码方面变成了myHeader

这几乎从来不起作用。也许在一百万个布局中,Android Studio的神灵不会出错,你可以访问子布局视图并且成功构建,但是当你通过代码更改它们时,子视图不会更新。 - undefined
@behelit:就我个人而言,在一个相当大的应用程序中,我对这种技术并没有特别的问题。当然,Compose UI可以摆脱所有这些。 - undefined

5

我已经在Java中检查过这个问题。

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <include
        android:id="@+id/my_header"
        layout="@layout/item_header"
        android:layout_width="match_parent"
        android:layout_height="100dp" />

</LinearLayout>

item_header.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clickable="false"
    android:background="@android:color/transparent">
    <TextView
        android:id="@+id/foo"
        android:layout_gravity="center"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</FrameLayout>

MainActivity.java

package com.example.myapplication;

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import com.example.myapplication.databinding.ActivityMainBinding;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        ActivityMainBinding binding = ActivityMainBinding.inflate(getLayoutInflater());

        setContentView(binding.getRoot());

        binding.myHeader.foo.setText("this is a test");
    }
}}

我检查了它在我的新项目中是否正常工作。 希望它能有所帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接