如何从活动中绑定抽屉页眉布局来查看?

所以这是我的activity_main.xml:

<?xml version="1.0" encoding="utf-8"?> <layout 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:context="MainActivity" > <!-- A DrawerLayout is intended to be used as the top-level content view using match_parent for both width and height to consume the full space available. --> <android.support.v4.widget.DrawerLayout android:id="@+id/drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent" > <!-- As the main content view, the view below consumes the entire space available using match_parent in both dimensions. --> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:id="@+id/ll_container" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <android.support.v7.widget.Toolbar android:id="@+id/my_awesome_toolbar" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@android:color/black" android:fitsSystemWindows="true" > <TextView android:id="@+id/toolbar_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:layout_marginStart="10dp" android:textColor="@android:color/white" android:textSize="@dimen/abc_text_size_title_material_toolbar" tools:text="@string/default_toolbar_title"/> </android.support.v7.widget.Toolbar> <FrameLayout android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent"> </FrameLayout> </LinearLayout> <android.support.design.widget.FloatingActionButton android:id="@+id/fab_fuf" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentEnd="true" android:layout_alignParentRight="true" android:layout_marginBottom="20dp" android:layout_marginEnd="20dp" android:layout_marginRight="20dp" android:src="@drawable/flamme" app:fabSize="normal" /> </RelativeLayout> <android.support.design.widget.NavigationView android:id="@+id/navigation_view" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="start" android:background="@android:color/black" **app:headerLayout="@layout/drawer_header"** app:itemTextColor="@color/drawer_item_color_selector" app:menu="@menu/menu_drawer"/> </android.support.v4.widget.DrawerLayout> </layout> 

我正在使用绑定的活动,所以我不必使用findViewById并投下它等等。像这样:

 ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main); Toolbar toolbar = binding.myAwesomeToolbar; toolbarTitle = binding.toolbarTitle; BalrogFontsHelper.SetKhandBoldToView(toolbarTitle); setSupportActionBar(toolbar); final ActionBar actionBar = getSupportActionBar(); if (actionBar != null) { actionBar.setHomeAsUpIndicator(R.drawable.ic_dehaze_white_24); actionBar.setDisplayHomeAsUpEnabled(true); actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD); actionBar.setDisplayShowTitleEnabled(false); } drawerLayout = binding.drawerLayout; **tvLoggedUserEmail = (TextView) findViewById(R.id.tv_logged_user_email);** BalrogFontsHelper.SetKhandBoldToView(tvLoggedUserEmail); 

正如你所看到的,我可以通过绑定直接在activity_main.xml布局中获取视图,但是当我试图获取的视图不在那里时,我看不到绑定对象中的variables。

drawer_header.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="96dp" xmlns:tools="http://schemas.android.com/tools" android:background="@android:color/black" android:theme="@style/ThemeOverlay.AppCompat.Dark"> <TextView android:id="@+id/tv_logged_user_email" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_marginLeft="16dp" tools:text="@string/login_placeholder_email" android:textAllCaps="true" android:textAppearance="@style/TextAppearance.AppCompat.Body2" android:textSize="20sp"/> </RelativeLayout> 

我怎样才能以绑定的方式得到这个tv_logged_user_email TextView所以我有:

 **tvLoggedUserEmail = binding.tvLoggedUserEmail;** 

Solutions Collecting From Web of "如何从活动中绑定抽屉页眉布局来查看?"

13/11/2015

http://developer.android.com/tools/support-library/index.html

更新devise支持库23.1.0至23.1.1

Changes for Design Support library: Added the getHeaderView method to the NavigationView class. Fixed a transparent background issue for a FloatingActionButton object on devices running Android 4.0 (API level 15) and lower. (Issue 183315)

===================

我不知道为什么没有提供通过编程附加标题视图的方法

1.solution

 NavigationView navigationView = (NavigationView) findViewById(R.id.navigation); View headerView = navigationView.inflateHeaderView(R.layout.header_layout) ImageView iv = (ImageView)headerview.findViewById(...) 

2.解决scheme

 NavigationView navigationView = (NavigationView) findViewById(R.id.navigation); View headerView = LayoutInflater.from(this).inflate(R.layout.header_layout, navigationView, false); navigationView.addHeaderView(view); ImageView iv = (ImageView) headerView.findViewById(...) 

我曾经有过同样的问题。

解决方法是膨胀标题视图并以编程方式添加它。

喜欢这个:

 DrawerHeaderBinding drawerHeaderBinding = DrawerHeaderBinding.inflate(LayoutInflater.from(navigationView.getContext())); navigationView.addHeaderView(drawerHeaderBinding.getRoot()); drawerHeaderBinding.tvLoggedUserEmail = "email"; drawerHeaderBinding.executePendingBindings(); 

所以删除应用程序:headerLayout并以编程方式执行。 我认为谷歌应该修复这个核心问题,无论是在devise库还是在数据绑定库中。

我有一个稍微更清洁的解决scheme,我不必“污染”片段/活动与代码负责膨胀和添加标题视图到NavigationView。 我实现了NavigationView的扩展类。 我是这样做的:

我的活动布局:

 <data> <variable name="dashboard" type="ramps.view.model.DashboardScreenViewModel"/> </data> <android.support.v4.widget.DrawerLayout android:id="@+id/drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" tools:openDrawer="start"> <include layout="@layout/activity_dashboard" android:layout_width="match_parent" android:layout_height="match_parent" bind:dashboard="@{dashboard}" /> <android.support.design.widget.NavigationView android:id="@+id/nav_view" android:background="@color/white" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="start" android:fitsSystemWindows="true" app:navigationItemSelectedListener="@{dashboard.onMenuItemSelected}" app:model="@{dashboard.score}" app:menu="@menu/activity_main_drawer"/> </android.support.v4.widget.DrawerLayout> 

正如你所看到的,在NavigationView中没有app:headerLayout,但是我添加了我的自定义应用程序:model,以及要传递给标题布局的数据。 我如何定义这个自定义参数? 通过扩展类:

 public class NavigationViewExtensions { @BindingAdapter({"bind:model"}) public static void loadHeader(NavigationView view, ScoreViewModel model) { ViewNavigationHeaderBinding binding = ViewNavigationHeaderBinding.inflate(LayoutInflater.from(view.getContext())); binding.setScore(model); binding.executePendingBindings(); view.addHeaderView(binding.getRoot()); } } 

只要把这个class放在你的项目的任何地方。 和我的标题的布局:

 <layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:bind="http://schemas.android.com/apk/res-auto" > <data> <import type="android.view.View"/> <variable name="score" type="ramps.view.model.ScoreViewModel"/> </data> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/graphite" android:gravity="bottom" android:orientation="vertical" android:paddingBottom="@dimen/activity_vertical_margin_large" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin_large" android:theme="@style/ThemeOverlay.AppCompat.Dark"> <include android:id="@+id/player_details_header_score" layout="@layout/view_avatar_score_header" bind:score="@{score}"/> </LinearLayout> 

 ImageView imageView = (ImageView) navigationView.getHeaderView(0).findViewById(R.id.imageButton); imageView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (flag) { navigationView.getMenu().clear(); //clear old inflated items. navigationView.inflateMenu(R.menu.drawer_view1); flag = false; } else { navigationView.getMenu().clear(); //clear old inflated items. navigationView.inflateMenu(R.menu.drawer_view); flag = true; } } }); 

如果你设置app:headerLayout="@layout/drawer_header那么你不必再膨胀视图,你可以使用.bind而不是.inflate

你可以得到已经膨胀的头部视图,并像这样绑定它:

 View headerView = binding.navigationView.getHeaderView(0); DrawerHeaderBinding headerBinding = DrawerHeaderBinding.bind(headerView); 

试试这与DataBinding库它为我工作。

navigation_view_header.xml:

 <layout xmlns:android="http://schemas.android.com/apk/res/android"> <RelativeLayout android:layout_width="match_parent" android:layout_height="@dimen/navigation_view_header_height" android:paddingLeft="@dimen/navigation_view_padding" android:paddingTop="@dimen/navigation_view_top_padding" android:background="@color/colorPrimary"> <ImageView android:id="@+id/avatar" android:layout_width="@dimen/avatar_dimen" android:layout_height="@dimen/avatar_dimen" android:contentDescription="@null" android:src="@drawable/default_avatar" /> <TextView android:id="@+id/profile_email" android:layout_width="match_parent" android:layout_height="48dp" android:layout_below="@+id/avatar" android:text="email" android:textColor="@color/white" android:layout_alignParentBottom="true" android:gravity="center_vertical" /> </RelativeLayout> </layout> 

activity_main.xml中:

 <layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <data> <variable name="navigationItemSelectedListener" type="com.example.MainActivity"/> </data> <android.support.v4.widget.DrawerLayout android:id="@+id/drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" android:tag="layout"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <android.support.v7.widget.Toolbar android:id="@+id/my_toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" app:titleTextColor="@color/white" android:background="@color/colorPrimary" app:theme="@style/Toolbar.Theme" app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/> <FrameLayout android:id="@+id/fragment_container" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout> <android.support.design.widget.NavigationView android:id="@+id/navigation_view" android:layout_width="@dimen/navigation_view_width" android:layout_height="match_parent" android:layout_gravity="start" android:fitsSystemWindows="true" app:theme="@style/Theme.AppCompat.Light" app:menu="@menu/drawer_menu" app:navigationItemSelectedListener="@{navigationItemSelectedListener::onNavigationItemSelected}"/> </android.support.v4.widget.DrawerLayout> </layout> 

并在您的活动中:

 ActivityMainBinding activityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main); activityMainBinding.setNavigationItemSelectedListener(this);/* with this line navigation menu item selection events are handled in onNavigationItemSelected() specified in navigation_view_header.xml*/ NavigationViewHeaderBinding navigationViewHeaderBinding = DataBindingUtil.inflate(getLayoutInflater(), R.layout.navigation_view_header,activityMainBinding.navigationView,false); activityMainBinding.navigationView.addHeaderView(navigationViewHeaderBinding.getRoot()); 

并确保您的活动实现了NavigationView.OnNavigationItemSelectedListener

这里有一个简单的解决scheme。 假设您将您的NavigationView添加为

 <android.support.design.widget.NavigationView android:id="@+id/navigationView" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="start" android:fitsSystemWindows="true" app:headerLayout="@layout/nav_drawer_header" app:menu="@menu/menu_nav_drawer"/> 

并且您要访问nav_drawer_header.xml中具有nav_drawer_header.xml标识的TextView。 所以你可以在你的活动中使用这个代码:

 View headerContainer = navigationView.getHeaderView(0); // This returns the container layout in nav_drawer_header.xml (eg, your RelativeLayout or LinearLayout) TextView textView2 = (TextView)headerContainer.findViewById(R.id.textView2); textView2.setText("Sorted!"); 

无需膨胀或干扰您现有的代码等

  • 编辑您的gradle文件,将com.android.support库更新到版本23.1.1或更高版本。

  • 使用navigationView.getHeaderView(i) ,其中iheaderview的索引。 如果您只是在布局上定义此视图,则为0

我已经更新从Android SDKpipe理器的构build工具,那么23.1.0也适用于我。

我正在使用buildToolsVersion "23.0.2"在此之前它是23.0.1

而且不需要使用:

 (View) navigationView.findViewById(R.id.idOfViewFromHeaderView); 

在你的活动中,你可以直接使用:

 (View) findViewById(R.id.idOfViewFromHeaderView); 

这个对我有用。

MainActivity.java:

  NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view); NavHeaderMainBinding binding = DataBindingUtil.inflate(getLayoutInflater(), R.layout.nav_header_main, navigationView, false); navigationView.addHeaderView(binding.getRoot()); 

activity_main.xml中:

 <android.support.v4.widget.DrawerLayout android:id="@+id/drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" tools:openDrawer="start"> <RelativeLayout android:id="@+id/content_frame" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.design.widget.AppBarLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <include layout="@layout/toolbar" /> </android.support.design.widget.AppBarLayout> </RelativeLayout> <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/activity_main_drawer" /> </android.support.v4.widget.DrawerLayout> 

nav_header.xml:

 <layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <data> <variable name="account" type="lonja.dreamteam.su.trainingdiary.view_model.AccountViewModel"/> </data> <LinearLayout android:layout_width="match_parent" android:layout_height="@dimen/nav_header_height" android:background="@drawable/header_background" android:gravity="bottom" android:orientation="vertical" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:theme="@style/ThemeOverlay.AppCompat.Dark"> <de.hdodenhof.circleimageview.CircleImageView android:id="@+id/imageView" android:layout_width="72dp" android:layout_height="72dp" android:src="@{account.sex}" app:civ_border_color="@color/colorAccent" app:civ_border_width="0dp" /> <TextView android:id="@+id/userName" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingTop="@dimen/nav_header_vertical_spacing" android:text="@{account.name}" android:textAppearance="@style/TextAppearance.AppCompat.Body1" /> </LinearLayout> 

你可以这样做。 首先初始化导航视图。

  NavigationView navigationView = (NavigationView) findViewById(R.id.navigation_view); 

然后初始化navigationView中的所有视图。

  CircleImageView circleView = (CircleImageView) navigationView.findViewById(R.id.circleView); TextView name = (TextView) navigationView.findViewById(R.id.name); TextView email = (TextView) navigationView.findViewById(R.id.email); LinearLayout header = (LinearLayout) navigationView.findViewById(R.id.header); 

然后你可以根据需要使用这些视图。 例如:

  name.setText(NAME); email.setText(EMAIL);