2015-11-27 2 views
3

У меня есть основной вид деятельности с боковой панели навигации в панели действий, определяется следующим образом (обратите внимание, что много кода было опущено для краткости) в 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" 
     /> 

где макет/заголовок следующим образом (опять же, пучок линий для краткости опущены):

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

Какой из них не работает. Как я могу это сделать?

ответ

1

Не уверен, что это лучший способ, но это то, что сработало для моего сценария.

Я создал пользовательский вид для 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()); 
    } 
} 
0

Мое решение заключается в следующем:

<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 поэтому мы используем 'включенную раскладку. Таким образом, наш заголовок может нормально отображаться привязкой данных. Но меню без макета заголовка будет перекрыто. Таким образом, мы добавляем пустойheadLayout имеет одинакового размера с нашим реальным расположением, чтобы меню выглядело нормально.

Подробное описание может быть найдено in my blog post.

Рабочий пример можно найти here.

Сообщите мне, если я не знаю.

15

Действительно решение будет следовать, добавить вид заголовка в основной деятельности 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()); 
} 
+0

Эй, ребята? это правильный ответ. : D –

+0

большое спасибо !!! – susemi99

+2

Важная строка: binding.navView.addHeaderView (_bind.getRoot()); удалить приложение: headerLayout = "@ layout/nav_header_main" из xml добавить программно, как указано выше – Pushan

0

Это кажется не прямой способ сделать привязку данных для NavigationView, так что я должен реализовать его в несколько хакера образом: Первый для того, чтобы использовать привязку, мы не можем использовать прямой 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

2

Вы можете связать любой вид с вашим родителем обязательным, если эта точка зрения вашего ребенка этого родителя. Как здесь: Навигационный заголовок представления - это дочерний элемент «Вид навигации», поэтому для привязки заголовка навигационного представления с видом навигации нужно это сделать.

default_screen обязательный для главного экрана:

DefaultScreenBinding binding = DataBindingUtil.setContentView(R.layout.default_screen); 

для размещения заголовка, включая связывание будет:

HeaderBinding headerBinding = HeaderBinding.bind(binding.navigationView.getHeaderView(0)); 

binding.navigationView.getHeaderView(0) даст представление заголовка зрения навигации, которые вы хотите связать.

Теперь вы можете использовать headerBinding для ссылок на макет заголовка. Надеюсь, это легко понять и получить полезную информацию.

Смежные вопросы