使用ViewBinding时,我遇到了一些未记录的案例。
第一:如何获取包含的通用视图布局部件的绑定,主绑定仅查看主布局中的项目?
第二:如何为包含的合并类型布局部件获取绑定,再次主绑定仅查看主布局中的项目?
答案 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)
在以下情况下
:equal
通过这种方式输入您的活动代码:
<include
android:id="@+id/your_id"
layout="@layout/some_layout" />
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>
标签
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)
这也可以在不设置 id
的 include
的情况下实现。
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)
...
}