简体   繁体   中英

How to change text of a TextView in navigation drawer header?

I want to change the text of a TextView inside the navigation drawer header. But I get this error:

java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference


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

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

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

        <FrameLayout
            android:id="@+id/frame_container"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

    </LinearLayout>

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

nav_header_main

<?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="@dimen/nav_header_height"
    android:background="@drawable/slide_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/tvHeaderIcon"
        android:layout_width="60dp"
        android:layout_height="60dp"
        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="@string/app_name"
        android:textAppearance="@style/TextAppearance.AppCompat.Body1" />

    <TextView
        android:id="@+id/tvHeaderName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

MainActivity.java

TextView tvHeaderName;

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

    tvHeaderName= (TextView) findViewById(R.id.tvHeaderName);
    tvHeaderName.setText("Saly");    
}

How can I do this?

Use function getHeaderView on your navigationView:

NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
View headerView = navigationView.getHeaderView(0);
TextView navUsername = (TextView) headerView.findViewById(R.id.navUsername);
navUsername.setText("Your Text Here");

You should inflate your Header layout from NavigationView first...

navHeaderView= navigationView.inflateHeaderView(R.layout.nav_header_main);
tvHeaderName= (TextView) navHeaderView.findViewById(R.id.tvHeaderName);
tvHeaderName.setText("Saly"); 

Here is the Kotlin version of the code, hope it helps someone out there.

val navigationView : NavigationView  = findViewById(R.id.nav_view)
val headerView : View = navigationView.getHeaderView(0)
val navUsername : TextView = headerView.findViewById(R.id.txtUserName)
val navUserEmail : TextView = headerView.findViewById(R.id.txtEmail)

navUsername.text = username.toString()
navUserEmail.text = email.toString()

You can also use this as of 23.1.1 design support library

View header = navigationView.getHeaderView(0)
TextView text = (TextView) header.findViewById(R.id.textView);

Reference: https://stackoverflow.com/a/33692431/2761923

  1. You need to get NavigationView id in your Activity like this

     NavigationView navigationView = (NavigationView) findViewById(R.id.navigationView );
  2. Now get HeaderView Layout using Navigationview id like this

    View headerView = navigationView.getHeaderView(0);
  3. Now you can get Any view id and perform action what you want example

    TextView navUsername = (TextView) headerView.findViewById(R.id.navUsername); navUsername.setText("Your Text Here");
val navigationView = findViewById<View>(R.id.nav_view_home) as NavigationView
        val headerView = navigationView.getHeaderView(0)
        val tvUserName = headerView.findViewById<View>(R.id.tvUserName) as TextView
        tvUserName.text=(Preference.getInstance("your text")

What worked for me? its this:-

 View linearLayout=navigationView.inflateHeaderView(R.layout.nav_header_main);
      TextView name =  linearLayout.findViewById(R.id.welcomenametext);

But remember to remove this from your xml file ie from NavigationView:- app:headerLayout="@layout/nav_header_main"


Ok apart from this above answer..over months i now figured there's a better way of doing it if you are advanced enough in android development.,Just put frame layout there and load fragment in it inside which we have Recyclerview and header section, With Recyclerview You can setup the header as you like with textviews.image.and many more as you like. The recent application I am working on just did that.Dynamically passed data into Recyclerview from fragmentactivity with out icons and also put a relative layout(inside textviews and imageview) which acts as header on top of Recyclerview.

Use this to get the navigation header

View hview = navigationView.getHeaderView(0);

then use the hview to get the different views of navigation header and do whatever you want

else using navHeaderView= navigationView.inflateHeaderView(R.layout.nav_header_main); this is creating a new header at index 1.

Intially, we have to get the instance of navigation view by inflating the navigation view in a view varible, later you can get the textView instance to edit the textview

This worked for me:

NavigationView navigationView = findViewById(R.id.nav_view);
View headerView = navigationView.getHeaderView(0);
TextView title = headerView.findViewById(R.id.nav_title);
TextView subTitle = headerView.findViewById(R.id.nav_sub_title);

I have same problem, but both given solutions didn't work for me

java.lang.IllegalStateException: Required view 'nav_header_username' with ID 2131296646 for field 'username' was not found. If this view is optional add '@Nullable' (fields) or '@Optional' (methods) annotation.

I have almost same code as posted above:

NavigationView navigationView = (NavigationView)findViewById(R.id.navigation_content);
View headerView = navigationView.inflateHeaderView(R.layout.nav_header);
TextView navUsername = (TextView) headerView.findViewById(R.id.nav_header_username);
navUsername.setText("Hello, "+mUserSession.getLoggedUserData().getmFirstName());

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM