【问题标题】:In android how to set navigation drawer header image and name programmatically in class file?在android中如何在类文件中以编程方式设置导航抽屉标题图像和名称?
【发布时间】:2015-11-06 05:41:40
【问题描述】:

在 android studio 1.4.1 中,我创建了新的默认导航抽屉项目。我的问题是在这个项目中有 nav_header_main.xml 文件用于导航标题图像和名称。我希望这个图像和名称应该在我的主类活动中以编程方式设置。如何做到这一点,我尝试了很多,但应用程序崩溃了。

nav_header_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout        
android:layout_width="match_parent"
android:id="@+id/headerView"
android:layout_height="@dimen/nav_header_height"
android:background="@drawable/side_nav_bar"
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">

<ImageView
    android:id="@+id/imageView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:paddingTop="@dimen/nav_header_vertical_spacing"
    android:src="@android:drawable/sym_def_app_icon" />

<TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingTop="@dimen/nav_header_vertical_spacing"
    android:text="Android Studio"
    android:textAppearance="@style/TextAppearance.AppCompat.Body1" />

<TextView
    android:id="@+id/textView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="android.studio@android.com" />

</LinearLayout>

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout            

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"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">

<include
    layout="@layout/app_bar_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

<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_main"
    app:menu="@menu/activity_main_drawer" />

    </android.support.v4.widget.DrawerLayout>

MainActivity.Class

import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.NavigationView;
import android.support.design.widget.Snackbar;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity
        implements NavigationView.OnNavigationItemSelectedListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        LinearLayout headerImageView= (LinearLayout) findViewById(R.id.headerView);


        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });

        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
                this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        drawer.setDrawerListener(toggle);
        toggle.syncState();

        NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
        navigationView.setNavigationItemSelectedListener(this);

    }

    @Override
    public void onBackPressed() {
        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        if (drawer.isDrawerOpen(GravityCompat.START)) {
            drawer.closeDrawer(GravityCompat.START);
        } else {
            super.onBackPressed();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            Toast.makeText(getApplicationContext(),"working",Toast.LENGTH_LONG).show();
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    @SuppressWarnings("StatementWithEmptyBody")
    @Override
    public boolean onNavigationItemSelected(MenuItem item) {
        // Handle navigation view item clicks here.
        int id = item.getItemId();

        if (id == R.id.nav_camara) {
            // Handle the camera action
        } else if (id == R.id.nav_gallery) {

        } else if (id == R.id.nav_slideshow) {

        } else if (id == R.id.nav_manage) {

        } else if (id == R.id.nav_share) {

        } else if (id == R.id.nav_send) {

        }

        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        drawer.closeDrawer(GravityCompat.START);

        return true;
    }
}

【问题讨论】:

    标签: android android-layout android-fragments androiddesignsupport android-navigationview


    【解决方案1】:
    NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
    View hView = navigationView.getHeaderView(0);
    TextView nav_user = (TextView) hView.findViewById(R.id.nav_name);
    nav_user.setText(user);
    

    【讨论】:

    • navigationView.getHeaderView(0);为什么我们在那里使用 0?
    【解决方案2】:

    正如错误190226 中提到的,从版本 23.1.0 开始获取标题布局视图: navigationView.findViewById(R.id.navigation_header_text) 不再有效。

    一种解决方法是以编程方式扩展 headerview 并从扩展的标题视图中按 ID 查找视图。

    例如:

    View headerView = navigationView.inflateHeaderView(R.layout.navigation_header);
    headerView.findViewById(R.id.navigation_header_text);
    

    理想情况下应该有一个方法getHeaderView()但是已经提出了,让我们看看并等待它在设计支持库的功能发布中发布。

    【讨论】:

    • 你能说一下如何添加文本视图和图像视图
    • 老兄,如答案中所述,您可以使用 inflateHeaderView() 方法扩展标题布局(使用 imageview、textview 或您想要的标题布局中的任何视图),并可以使用相同的扩展布局找到视图findViewById()
    • NavigationView navigationView = null;查看 headerView = navigationView.inflateHeaderView(R.layout.nav_header_main); TextView tv=(TextView)headerView.findViewById(R.id.textView); tv.setText("检查");这是我的代码,即使应用程序崩溃
    • 它与给定的示例一起使用并记住从android.support.design.widget.NavigationView app:headerLayout="@layout/nav_header_main" 中删除行,因为您已经以编程方式膨胀
    • @milapTank 评论提供了帮助,因为标题视图膨胀了两次,直到我从我的 XML 中删除了他建议的行。
    【解决方案3】:

    不要在xml中添加标题通过膨胀布局使用代码添加

    View hView =  navigationView.inflateHeaderView(R.layout.nav_header_main);
    ImageView imgvw = (ImageView)hView.findViewById(R.id.imageView);
    TextView tv = (TextView)hView.findViewById(R.id.textview);
    imgvw .setImageResource();
    tv.settext("new text");
    

    【讨论】:

    • 是的,这很容易得到结果,谢谢bhai。
    • 如何在 kotlin 中实现这个?
    【解决方案4】:

    在科特林中

        val hView = nav_view.getHeaderView(0)
        val textViewName = hView.findViewById(R.id.textViewName) as TextView
        val textViewEmail = hView.findViewById(R.id.textViewEmail) as TextView
        val imgvw = hView.findViewById(R.id.imageView) as ImageView
        imgvw.setImageResource(R.drawable.ic_menu_gallery)
    

    【讨论】:

      【解决方案5】:

      首先,您需要像这样访问 MainActivity(或调用活动)中的导航抽屉:

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

      然后您需要从 activity_main.xml 中删除标题布局,因为布局将在 MainActivity 中以编程方式膨胀。您的 activity_main.xml 应如下所示:

      <?xml version="1.0" encoding="utf-8"?>
      <android.support.v4.widget.DrawerLayout            
      
      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"
      android:id="@+id/drawer_layout"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:fitsSystemWindows="true"
      tools:openDrawer="start">
      
      <include
          layout="@layout/app_bar_main"
          android:layout_width="match_parent"
          android:layout_height="match_parent" />
      
      <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>
      

      然后在您的 MainActivity 中,我们膨胀 nav_header_main 布局并访问其视图,在本例中为 ImageView 和 TextView

      //inflate header layout
      View navView =  navigationView.inflateHeaderView(R.layout.nav_header_main);
      //reference to views
      ImageView imgvw = (ImageView)navView.findViewById(R.id.imageView);
      TextView tv = (TextView)navView.findViewById(R.id.textview);
      //set views
      imgvw.setImageResource(R.drawable.your_image);
      tv.setText("new text");
      
      navigationView.setNavigationItemSelectedListener(this);
      

      您可以阅读更多here

      【讨论】:

        【解决方案6】:
        val navigationView: NavigationView =  findViewById(R.id.nv)
        val header: View = navigationView.getHeaderView(0)
        val tv: TextView = header.findViewById(R.id.profilename)
        tv.text = "Your_Text"
        

        这将解决您的问题

        【讨论】:

          【解决方案7】:

          这是我的代码 下面完美工作 不要在 NavigationView 中添加标题 activity_main.xml 中的标记

          <include
              layout="@layout/app_bar_main"
              android:layout_width="match_parent"
              android:layout_height="match_parent" />
          
          <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"
              app:itemBackground="@drawable/active_drawer_color" />
          

          使用以下代码以编程方式添加标题

          View navHeaderView = navigationView.inflateHeaderView(R.layout.nav_header_main);
              headerUserName = (TextView) navHeaderView.findViewById(R.id.nav_header_username);
              headerMobileNo = (TextView) navHeaderView.findViewById(R.id.nav_header_mobile);
              headerMobileNo.setText("+918861899697");
              headerUserName.setText("Anirudh R Huilgol");
          

          【讨论】:

          • 对我不起作用,它显示空的 nav_header。 (不含文字和图片)
          • @maximus 我会把代码上传到 GitHub 上,你可以看看你犯了什么错误。
          【解决方案8】:
            nav = ( NavigationView ) findViewById( R.id.navigation );
          
              if( nav != null ){
                  LinearLayout mParent = ( LinearLayout ) nav.getHeaderView( 0 );
          
                  if( mParent != null ){
                      // Set your values to the image and text view by declaring and setting as you need to here.
          
                      SharedPreferences prefs = getSharedPreferences("user_data", MODE_PRIVATE);
                      String photoUrl = prefs.getString("photo_url", null);
                      String user_name = prefs.getString("name", "User");
          
                      if(photoUrl!=null) {
                          Log.e("Photo Url: ", photoUrl);
          
                          TextView userName = mParent.findViewById(R.id.user_name);
                          userName.setText(user_name);
          
                          ImageView user_imageView = mParent.findViewById(R.id.avatar);
          
                          RequestOptions requestOptions = new RequestOptions();
                          requestOptions.placeholder(R.drawable.ic_user_24dp);
                          requestOptions.error(R.drawable.ic_user_24dp);
          
                          Glide.with(this).load(photoUrl)
                                  .apply(requestOptions).thumbnail(0.5f).into(user_imageView);
          
                      }
          
                  }
              }
          

          希望这会有所帮助。

          【讨论】:

            【解决方案9】:

            编辑:适用于最高 23.0.1 的设计库,但不适用于 23.1.0

            在主布局 xml 中,您将定义 NavigationView,其中使用 app:headerLayout 设置标题视图。

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

            @layout/nav_drawer_header 将是图片和文字的占位符。

            nav_drawer_header.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="170dp"
            android:orientation="vertical">
            
            <RelativeLayout
                android:id="@+id/headerRelativeLayout"
                android:layout_width="match_parent"
                android:layout_height="match_parent">
            
                <ImageView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:scaleType="fitXY"
                    android:src="@drawable/background" />
            
                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="@dimen/action_bar_size"
                    android:layout_alignParentBottom="true"
                    android:layout_alignParentLeft="true"
                    android:layout_alignParentStart="true"
                    android:background="#40000000"
                    android:gravity="center"
                    android:orientation="horizontal"
                    android:paddingBottom="5dp"
                    android:paddingLeft="16dp"
                    android:paddingRight="10dp"
                    android:paddingTop="5dp">
            
                    <LinearLayout
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        android:layout_marginLeft="35dp"
                        android:orientation="vertical"
                        android:weightSum="2">
            
            
                        <TextView
                            android:id="@+id/navHeaderTitle"
                            android:layout_width="wrap_content"
                            android:layout_height="0dp"
                            android:layout_weight="1"
                            android:textAppearance="?android:attr/textAppearanceMedium"
                            android:textColor="@android:color/white" />
            
                        <TextView
                            android:id="@+id/navHeaderSubTitle"
                            android:layout_width="wrap_content"
                            android:layout_height="0dp"
                            android:layout_weight="1"
                            android:textAppearance="?android:attr/textAppearanceSmall"
                            android:textColor="@android:color/white" />
            
                    </LinearLayout>
            
                </LinearLayout>
            </RelativeLayout>
            </LinearLayout>
            

            在你的主类中,你可以像处理普通的其他视图一样处理ImageviewTextView

            TextView navHeaderTitle = (TextView) findViewById(R.id.navHeaderTitle);
            navHeaderTitle.setText("Application Name");
            
            TextView navHeaderSubTitle = (TextView) findViewById(R.id.navHeaderSubTitle);
            navHeaderSubTitle.setText("Application Caption");
            

            希望这会有所帮助。

            【讨论】:

            • 我已经实现了它,它的工作没有任何问题。我用这种方式很久了。
            • 我在设计库 22.2.1 中使用它,它工作正常。从未在 23.1.0 上尝试过
            • 我试过了,但应用程序崩溃了。 navHeaderTitle.setText("Appliclation Name") 附近显示 log cat 错误
            • 您在使用支持库 23.1.0?如果是这样,请查看上述评论中@PareshMayani 提供的链接。
            【解决方案10】:

            我知道这是一篇旧帖子,但我相信这可能会对以后的人有所帮助。

            您可以通过执行以下操作简单地获取导航视图的 headerView 元素:

             NavigationView mView = ( NavigationView ) findViewById( R.id.nav_view );
            
             if( mView != null ){
                 LinearLayout mParent = ( LinearLayout ) mView.getHeaderView( 0 );
            
                 if( mParent != null ){
                    // Set your values to the image and text view by declaring and setting as you need to here. 
                 }
             }
            

            我希望这对某人有所帮助。

            【讨论】:

            • 如何获取TextView?是mParent.findViewById() 还是findViewById()
            • 可以使用 mView.findViewById( R.id.text_view );
            【解决方案11】:

            您还可以使用 Kotlinx 功能

            val hView = nav_view.getHeaderView(0)
            hView.textViewName.text = "lorem ipsum"
            hView.imageView.setImageResource(R.drawable.ic_menu_gallery)
            

            【讨论】:

              【解决方案12】:
                 FirebaseAuth firebaseauth = FirebaseAuth.getInstance(); 
              
                 NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);   //displays text of header of nav drawer.
                  View headerview = navigationView.getHeaderView(0);
              
                  TextView tt1 = (TextView) headerview.findViewById(R.id.textview_username);
                  tt1.setText(firebaseauth.getCurrentUser().getDisplayName());//username of logged in user.  
              
                 TextView tt = (TextView) headerview.findViewById(R.id.textView_emailid);
                  tt.setText(firebaseauth.getCurrentUser().getEmail());    //email id of logged in user.
              
                  final ImageView img1 = (ImageView) headerview.findViewById(R.id.imageView_userimage);
                  Glide.with(getApplicationContext())
                          .load(firebaseauth.getCurrentUser().getPhotoUrl()).asBitmap().atMost().error(R.drawable.ic_selfie_point_icon)   //asbitmap after load always.
                          .into(new SimpleTarget<Bitmap>() {
                              @Override
                              public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
                                  img1.setImageBitmap(resource);
                              }
                          });
              

              我用一些逻辑自己编写了这段代码......它 100% 工作......请支持我的回答。

              textview 和 imageview 来自@layout/nav_header_main.xml

              【讨论】:

                【解决方案13】:

                如果你使用绑定,你可以这样做

                val headerView = binding.navView.getHeaderView(0)
                val headerBinding = NavDrawerHeaderBinding.bind(headerView)
                headerBinding.textView.text = "Your text here"
                

                【讨论】:

                • 你是我的女主角。谢谢:)
                【解决方案14】:

                这是旧帖子,但对我来说是新的。所以,这是直截了当的! 在这部分代码中:

                 public boolean onNavigationItemSelected(MenuItem item) {
                

                } ,我将 ImageView 绑定到 LinearLayout,其中包含示例中的 ImageView,如下所示。注意:这与您启动新项目时获得的代码相同,并选择模板“Navigation Drawer Activity”:

                <ImageView
                android:id="@+id/imageView"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:paddingTop="@dimen/nav_header_vertical_spacing"
                android:src="@android:drawable/sym_def_app_icon" />
                

                我在 nav_header_main.xml 中给出了 LinearLayout 和 ID(在我的例子中,我选择了 'navigation_header_container' ,所以它是这样的:

                LinearLayout lV = (LinearLayout) findViewById(R.id.navigation_header_container);
                
                    ivCloseDrawer = (ImageView) lV.findViewById(R.id.imageView);
                    ivCloseDrawer.setOnClickListener(new View.OnClickListener()
                    {
                        @Override
                        public void onClick(View v)
                        {
                            drawer.closeDrawer(GravityCompat.START);
                        }
                    });
                

                注意:我在顶部声明了一个私有 ImageView ivCloseDrawer,在 onCreate (MainActivity) 之前。

                【讨论】:

                  【解决方案15】:

                  NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view); navigationView.addHeaderView(yourview);

                  【讨论】:

                  • 嗨@Роман Бяков,欢迎来到 Stack Overflow。感谢您的贡献。您是否知道这个问题已经超过 4 个月了 :-) ?不确定是否仍然需要答案...但是,对于不同的答案,请尝试解释更多。您的建议中的yourview 是什么,OP 应该将您的代码放在哪里?她/他应该添加行还是替换与你相同的行?此类解释将有助于尝试您的答案并了解您的贡献的价值。祝你好运。
                  • 对于它的价值,这个问题没有明确的答案并且它仍然活跃:你知道自从这个任意的 4 个月截止日期已经过去,有 3 个新帖子:-)?不确定是否需要您的评论...但是,对于未来的 cmets,请务必坚持帮助提高贡献,而不是完全阻止他们。
                  • 许多超过 4 个月的问题仍然可以得到答案。事实上,一些更老(一些岁)的问题仍在得到答案!这是一件好事。尽管 OP 可能已经得到了他的答案,但有些人有同样的问题,而对于他们来说,现有的答案池仍然没有回答这个问题。由于 StackOverflow 不鼓励重新发布相同的问题,因此新的答案将帮助其他有相同问题的人。此外,API 会随着时间而变化,旧的答案有时包含可能会被弃用的代码。
                  【解决方案16】:

                  这是您可以用来获取标题视图和设置数据的方法

                  val headerView: View? = navigationView.getHeaderView(0) // Index of the added headerView  
                  
                  // Now you can access child views of the header view
                  val titleTextView: TextView? = headerView?.findViewById(R.id.titleTextView)
                  

                  【讨论】:

                    【解决方案17】:

                    对于那些使用 KOTLIN 的人:

                    val headerview = binding.navDrawer.getHeaderView(0)
                    val NavDrawheaderviewRef = NavdrawerHeaderLayoutBinding.bind(headerview)
                    
                    NavDrawheaderviewRef.btnSearch.setOnClickListener
                    {
                    Toast.make(this , "Hii buddy",LENGTH_SHORT).show()    
                        }
                    

                    这里:

                    • navDrawer = 我的导航抽屉的 ID
                    • NavdrawerHeaderLayoutBinding = 一个用于获取标题布局参考的函数。
                    • btnSearch = 标题布局中的按钮

                    【讨论】:

                      猜你喜欢
                      • 2016-04-20
                      • 1970-01-01
                      • 1970-01-01
                      • 2021-09-17
                      • 1970-01-01
                      • 2017-05-11
                      • 1970-01-01
                      • 1970-01-01
                      • 2019-08-27
                      相关资源
                      最近更新 更多