如何将数据绑定到标头?

时间:2015-11-27 17:46:59

标签: android android-activity binding

我在操作栏中有一个带侧导航抽屉的主要活动,在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);

哪个不起作用。我怎么能这样做?

6 个答案:

答案 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);

布局文件在这里。 可以在这里找到工作示例。

参考:http://tonyz93.blogspot.com.br/2016/08/learn-data-binding-of-android.html#navigationview-data-binding

答案 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"