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

时间:2019-11-06 12:23:38

标签: android android-viewbinding

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

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

第二:如何为包含的合并类型布局部件获取绑定,再次主绑定仅查看主布局中的项目?

9 个答案:

答案 0 :(得分:13)

第一个问题就是使用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>

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;
    }
}

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

答案 1 :(得分:5)

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

对于活动

YourMainLayoutBinding mainLayoutBinding = MainLayoutBinding.inflate(getLayoutInflater);

View view = mainLayoutBinding.getRoot();

YourIncludedLayoutBinding includedLayoutBinding = YourIncludedLayoutBinding.bind(View);

对于片段

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

View view = mainLayoutBinding.getRoot();

YourIncludedLayoutBinding includedLayoutBinding = YourIncludedLayoutBinding.bind(View);
<块引用>

确保您的主布局绑定父根是 LinearLayout ,然后, includeLayoutBinding 父布局也是线性布局

答案 2 :(得分:1)

在以下情况下

  1. 在包含通用布局(不是合并节点)的情况下,我们需要为包含的部分分配ID,通过这种方式,我们将可以访问包含的子部分
equal

通过这种方式输入您的活动代码:

<include
    android:id="@+id/your_id"
    layout="@layout/some_layout" />
  1. 在外部布局中包含合并块。我们无法向其中添加ID,因为合并块不是视图。 假设我们有这样的永久合并布局(merge_layout.xm):
private lateinit var exampleBinding: ActivityExampleBinding  //activity_example.xml layout

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    exampleBinding = ActivityExampleBinding.inflate(layoutInflater)
    setContentView(loginBinding.root)
    //we will be able to access included layouts view like this
    val includedView: View = exampleBinding.yourId.idOfIncludedView
//[...]
}

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

在您的活动代码中:

<?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>

答案 3 :(得分:1)

在包含布局中,您必须创建一个容器布局并将ID放在此处。

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/example"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toTopOf="parent">
    </androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

答案 4 :(得分:0)

另一种简单的方法是使用数据绑定库。然后,使用标记包装XML布局,以便在使用库时自动生成将布局中的视图与数据对象绑定所需的类。 老实说,我认为这是要走的路。 遵循指南here

答案 5 :(得分:0)

当我将依赖从 viewBinding 重构为 dataBinding 时,会发生此问题:

`kotlin-android-extensions`

viewBinding {
    enabled = true
}

收件人:

buildFeatures {
    dataBinding true
}

我注意到我需要用layout中的dataBinding标签包装两个xml布局。但是,在旧的依赖项viewBinding中,您不需要使用layout标记包装子项。为此,无法找到包含布局的子级。

答案 6 :(得分:0)

假设我在 activity_main.xml 中包含了这个布局

<include
                android:id="@+id/ll_layout1"
                layout="@layout/layout1"
                android:visibility="gone" />

假设我想改变它的可见性,我会这样做:

activityMainBinding.llLayout1.root.visibility = View.VISIBLE

答案 7 :(得分:0)

使用数据绑定库。然后用 <layout> 标签

包裹你的 XML 布局

activity_main.xml

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

    ... 

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

</LinearLayout>
</layout>

toolbar.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">

    <ImageView 
        android:id="@+id/ivImage"
        ... />

    <TextView 
        android:id="@+id/tvTitle"
        ... />


</LinearLayout>

MainActivity.kt

private lateinit var binding: ActivityMainBinding  

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    binding = DataBindingUtil.setContentView(this, R.layout.activity_main)

    // Access include layout views
    binding.toolbar.rootView.ivImage.setImageResource(R.drawable.ic_back_arrow)
    binding.toolbar.rootView.tvTitle.text = getString(R.string.home)
   
    ...
}

答案 8 :(得分:-1)

这也可以在不设置 idinclude 的情况下实现。

activity_main.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">

    ... 

    <include layout="@layout/toolbar" />
    
    ...

</LinearLayout>

toolbar.xml

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/llRootLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <ImageView 
        android:id="@+id/ivImage"
        ... />

    <TextView 
        android:id="@+id/tvTitle"
        ... />


</LinearLayout>

MainActivity.kt

private lateinit var binding: ActivityMainBinding  

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    binding = ActivityMainBinding.inflate(layoutInflater)
    setContentView(binding.root)

    // Access include layout views
    binding.root.ivImage.setImageResource(R.drawable.ic_back_arrow)
    binding.root.tvTitle.text = getString(R.string.home)
   
    ...
}