ViewBinding - 如何绑定包含的布局?

Art*_*zak 135 android android-viewbinding

在使用 ViewBinding 时,我遇到了一些没有记录的案例。

第一:如何获取包含的通用视图布局部分的绑定,主绑定只看到主布局中的项目?

第二:如何获得包含的合并类型布局部分的绑定,再次主绑定只看到主布局中的项目?

Art*_*zak 199

的情况下:

  1. 包含通用布局(不是合并节点),我们需要为包含的部分分配 ID,这样在绑定中我们将可以访问包含的子部分
<include
    android:id="@+id/your_id"
    layout="@layout/some_layout" />
Run Code Online (Sandbox Code Playgroud)

这样在您的活动代码中:

private lateinit var exampleBinding: ActivityExampleBinding  //activity_example.xml layout

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    exampleBinding = ActivityExampleBinding.inflate(layoutInflater)
    setContentView(exampleBinding.root)
    //we will be able to access included layouts view like this
    val includedView: View = exampleBinding.yourId.idOfIncludedView
//[...]
}
Run Code Online (Sandbox Code Playgroud)
  1. 在外部布局中包含合并块。我们无法为其添加 ID,因为合并块不是视图。假设我们有这样一个永恒的合并布局(merge_layout.xm):
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    tools:showIn="@layout/activity_example">

    <TextView
        android:id="@+id/some_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World" />
</merge>
Run Code Online (Sandbox Code Playgroud)

要正确绑定这种合并布局,我们需要:

在您的活动代码中:

private lateinit var exampleBinding: ActivityExampleBinding  //activity_example.xml layout
private lateinit var mergeBinding: MergeLayoutBinding  //merge_layout.xml layout

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    exampleBinding = ActivityExampleBinding.inflate(layoutInflater)
    //we need to bind the root layout with our binder for external layout
    mergeBinding = MergeLayoutBinding.bind(exampleBinding.root)
    setContentView(exampleBinding.root)
    //we will be able to access included in merge layout views like this
    val mergedView: View = mergeBinding.someView
//[...]
}
Run Code Online (Sandbox Code Playgroud)

  • 必须在包含合并视图的文件中添加“layout”标签 (6认同)
  • 我试图在片段而不是活动中执行此操作,但它不起作用。我已将 global_header 设置为我的包含项的 id,实际上 android studio 中的自动完成功能运行得很好,并且自动完成 viewBindings.globalHeader,因此它是为绑定生成的,但在运行时它崩溃了:“ java.lang.NullPointerException:缺少必需的查看 ID:com.daon.ps.daonsonboard:id/global_header" (2认同)

Emi*_*Raz 25

您的第一个问题,即使用 ViewBinding 处理包含的布局可以很容易地解决。

这是一个示例main_fragment.xml文件

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

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycler_view_main"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

    <include
        android:id="@+id/toolbar"
        layout="@layout/toolbar" />

</LinearLayout>
Run Code Online (Sandbox Code Playgroud)

MainFragment.java可以是这样的

public class MeaningFragment extends Fragment {

    private MainFragmentBinding binding;
    private ToolbarBinding toolbarBinding;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

        binding = MainFragmentBinding.inflate(inflater, container, false);
        toolbarBinding = binding.toolbar;

        return binding.getRoot();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();

        toolbarBinding = null;
        binding = null;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,您有两个绑定。其中之一是默认设置,下一个来自包含的布局。

  • 非常简单的答案并使用新的语法 - 所有这些都在非片段活动中为我工作,在“onCreate()”中具有类似的语法。谢谢。(只是在使用 `DrawerLayout` 时遇到了一些麻烦) (2认同)

shi*_*ang 19

假设我在activity_main.xml文件中包含了一个布局,如下所示:

<include
    android:id="@+id/ll_layout1"
    layout="@layout/layout1"
    android:visibility="gone" />
Run Code Online (Sandbox Code Playgroud)

假设我想改变它的可见性。我可以这样做:

activityMainBinding.llLayout1.root.visibility = View.VISIBLE
Run Code Online (Sandbox Code Playgroud)


小智 6

如果你想绑定包含的布局,那么

对于活动

YourMainLayoutBinding mainLayoutBinding = MainLayoutBinding.inflate(getLayoutInflater);

View view = mainLayoutBinding.getRoot();

YourIncludedLayoutBinding includedLayoutBinding = YourIncludedLayoutBinding.bind(View);
Run Code Online (Sandbox Code Playgroud)

对于片段

YourMainLayoutBinding mainLayoutBinding = MainLayoutBinding.inflate(inflater,container,false);

View view = mainLayoutBinding.getRoot();

YourIncludedLayoutBinding includedLayoutBinding = YourIncludedLayoutBinding.bind(View);
Run Code Online (Sandbox Code Playgroud)

确保如果您的主布局绑定父根是 LinearLayout 那么,includedLayoutBinding 父布局也是线性布局

  • 无需显式绑定包含的布局,如果您为其指定 id,它会自动完成:`&lt;include android:id="@+id/myToolbar" layout="@layout/toolbar" /&gt;`。之后,字段“mainLayoutBinding.myToolbar”将包含嵌套绑定。 (2认同)