我在操作栏中有一个带侧导航抽屉的主要活动,在default_screen.xml中指定如下(请注意,为简洁起见省略了很多代码):
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="190dp"
android:background="@drawable/honeycomb"
android:orientation="vertical"
>
<android.support.design.widget.NavigationView
android:id="@+id/navigation_view"
android:layout_height="match_parent"
android:layout_width="wrap_content"
android:layout_gravity="start"
app:headerLayout="@layout/header"
app:menu="@menu/drawer"
/>
其中layout / header如下所示(为简洁起见,省略了一堆行):
<data>
<variable name="user" type="oose2017.place2b.ClientUser"/>
</data>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.displayName}"
android:textSize="14sp"
android:textColor="#FFF"
android:textStyle="bold"
android:gravity="left"
android:paddingBottom="4dp"
android:id="@+id/username"
android:layout_above="@+id/email"
android:layout_alignLeft="@+id/profile_image"
android:layout_alignStart="@+id/profile_image" />
</RelativeLayout>
我在主活动中实例化我的default_screen,如下所示:
setContentView(R.layout.default_screen);
我如何将数据绑定到标头?我尝试了一些不成功的事情,主要是:
DefaultScreenBinding binding = DataBindingUtil.setContentView(R.layout.default_screen);
哪个不起作用。我怎么能这样做?
答案 0 :(得分:27)
将使用有效的解决方案,在主要活动OnCreate中添加标题视图:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
NavHeaderMainBinding _bind = DataBindingUtil.inflate(getLayoutInflater(), R.layout.nav_header_main, binding
.navView, false);
binding.navView.addHeaderView(_bind.getRoot());
_bind.setUser(Session.getUserProfile());
}
答案 1 :(得分:9)
如果该视图是您父视图的子视图,则可以使用父绑定绑定任何视图。像这里:导航视图标题是导航视图的子项,因此要导航视图标题与导航视图绑定需要这样。
主屏幕的default_screen绑定:
DefaultScreenBinding binding = DataBindingUtil.setContentView(R.layout.default_screen);
标题布局的包括绑定:
HeaderBinding headerBinding = HeaderBinding.bind(binding.navigationView.getHeaderView(0));
binding.navigationView.getHeaderView(0)
将提供您要绑定的导航视图的标题视图。
现在,您可以将headerBinding用于标题布局引用。希望你能轻松理解并获得帮助。
答案 2 :(得分:2)
不确定这是否是最佳方式,但这对我的方案有效。
我为NavigationView
创建了一个自定义视图(扩展了类),然后使用DataBindingUtil.inflate
作为自定义视图构造函数的一部分,我使用它来设置我的数据绑定变量并添加然后使用NavigationView.addHeaderView
将该视图添加为标题。当然这意味着在xml中我必须用我的自定义视图替换NavigationView
,而不是在自定义视图中指定app:headerLayout属性。请参阅下面的自定义视图示例(请注意,我使用Dagger2来注入我的数据绑定变量)。
public class MyNavigationView extends NavigationView {
@Inject
MyViewModel myViewModel;
public MyNavigationView(Context context) {
super(context);
initialize();
}
public MyNavigationView(Context context, AttributeSet attrs) {
super(context, attrs);
initialize();
}
public MyNavigationView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initialize();
}
private void initialize() {
// NOTE: A private method that "injects" your view model dependency (ex: Using Dagger2)
inject();
NavHeaderHomeBinding binding = DataBindingUtil.inflate(LayoutInflater.from(getContext()),
R.layout.nav_header_home,
null,
false);
binding.setHomeNavDrawerViewModel(myViewModel);
addHeaderView(binding.getRoot());
}
}
答案 3 :(得分:2)
我的解决方案如下:
<android.support.design.widget.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="@layout/navigation"
app:menu="@menu/activity_drawer_drawer">
<include
layout="@layout/nav_header_drawer"
bind:thisDevice="@{thisDevice}" />
为了使用数据绑定,我们无法使用原始headLayout
,因此我们使用了包含的布局&#39;。这样,我们的标题可以通过数据绑定正常显示。但是,没有标题布局的菜单将重叠。因此,我们在实际布局中添加空 headLayout
相同尺寸,以便正常显示菜单。
可以找到详细说明in my blog post。
可以找到工作示例here。
如果我不清楚,请通知我。
答案 4 :(得分:0)
似乎没有直接的方法为NavigationView进行数据绑定,所以我必须以某种黑客的方式实现它: 首先,为了使用bind,我们不能使用直接headerLayout并将其替换为包含的布局
<android.support.design.widget.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="@layout/nav_header_drawer"
app:menu="@menu/drawer">
<android.support.design.widget.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:menu="@menu/drawer">
<include layout="@layout/nav_header_drawer"
bind:thisDevice="@{thisDevice}" />
</android.support.design.widget.NavigationView>
新包含的视图位于菜单顶部,因此会正常显示。但部分菜单项会向上移动,因为它上方没有标题,并且被新包含的视图重叠(尽管这些项目可以接收触摸事件),因此我们可以添加标题。
<android.support.design.widget.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="@layout/navigation"
app:menu="@menu/activity_drawer_drawer">
<include
layout="@layout/nav_header_drawer"
bind:thisDevice="@{thisDevice}" />
</android.support.design.widget.NavigationView>
导航布局是一个空布局,具有与真实nav_header_drawer相同的高度和宽度。所以两个菜单我们的实际布局都正常显示。 当然,java代码是数据绑定所必需的:
ActivityDrawerBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_drawer);
binding.setThisDevice(Device.now);
布局文件在这里。 可以在这里找到工作示例。
答案 5 :(得分:0)
// navView is NavigationView
val viewHeader = binding.navView.getHeaderView(0)
// nav_header.xml is headerLayout
val navViewHeaderBinding : NavHeaderBinding = NavHeaderBinding.bind(viewHeader)
// title is Children of nav_header
navViewHeaderBinding.title.text = "Your Text"