¿Cómo cambiar el texto de un TextView en el encabezado del cajón de navegación?

84

Quiero cambiar el texto de un TextView dentro del encabezado del cajón de navegación. Pero me sale este error:

java.lang.NullPointerException: intento de invocar el método virtual 'void android.widget.TextView.setText (java.lang.CharSequence)' en una referencia de objeto nulo


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

¿Cómo puedo hacer esto?

Salar Rastari
fuente

Respuestas:

267

Utilice getHeaderView` en su 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");
Bereket Gobeze
fuente
3
Para actualizar de manera confiable un TextViewencabezado en un cajón de navegación, use este código en el ActionBarDrawerToggle.onDrawerOpened()método. Consulte: stackoverflow.com/a/35952939/1657502 .
Antonio Vinicius Menezes Medei
Compañero ahorrador. Dios los bendiga: D
Biswajit Das
9

Primero debe inflar el diseño de su encabezado desde NavigationView ...

navHeaderView= navigationView.inflateHeaderView(R.layout.nav_header_main);
tvHeaderName= (TextView) navHeaderView.findViewById(R.id.tvHeaderName);
tvHeaderName.setText("Saly"); 
Ashutosh Verma
fuente
3
Para mí, inflateHeaderView no funcionó. En su lugar, usé getHeaderView (0).
Zeezer
6
Esta solución no funciona correctamente. Esto muestra el encabezado dos veces. El uso de getHeaderView (0) funciona.
AlphaDeveloper
1
@BereketGobeze tiene la respuesta correcta, esto no funciona correctamente
touchofsarcasm
Si elimina la siguiente línea del archivo XML, esta solución también funciona bien app: headerLayout = "@ layout / nav_header_main"
Pablo Insua
7

Aquí está la versión de Kotlin del código, espero que ayude a alguien.

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()
Siyabonga Dube
fuente
6

También puede usar esto a partir de la biblioteca de soporte de diseño 23.1.1

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

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

Neri
fuente
3
  1. Necesita obtener la identificación de NavigationView en su actividad de esta manera

    NavigationView navigationView = (NavigationView) findViewById(R.id.navigationView );
    
  2. Ahora obtenga el diseño de HeaderView usando la identificación de Navigationview como esta

    View headerView = navigationView.getHeaderView(0);
    
  3. Ahora puede obtener cualquier ID de vista y realizar la acción que desee.

    TextView navUsername = (TextView) headerView.findViewById(R.id.navUsername);
    navUsername.setText("Your Text Here");
    
CONOCIMIENTO GURU
fuente
Trabajó para mí hoy
Arsalan Fakhar
0

Use esto para obtener el encabezado de navegación

View hview = navigationView.getHeaderView(0);

luego use hview para obtener las diferentes vistas del encabezado de navegación y haga lo que quiera

de lo contrario, usar navHeaderView= navigationView.inflateHeaderView(R.layout.nav_header_main); esto es crear un nuevo encabezado en el índice 1.

Sachin Gupta
fuente
0

Inicialmente, tenemos que obtener la instancia de la vista de navegación inflando la vista de navegación en una vista variable, luego puede obtener la instancia de textView para editar la vista de texto

Di-s Abhishek
fuente
0

¿Qué funcionó para mí? es esto:-

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

Pero recuerde eliminar esto de su archivo xml, es decir, de NavigationView: -app:headerLayout="@layout/nav_header_main"


Ok, aparte de esta respuesta anterior ... durante meses, ahora pensé que hay una mejor manera de hacerlo si está lo suficientemente avanzado en el desarrollo de Android. Simplemente coloque el diseño del marco allí y cargue el fragmento dentro del cual tenemos Recyclerview y la sección de encabezado. Con Recyclerview, puede configurar el encabezado como desee con vistas de texto, imágenes y muchos más. La aplicación reciente en la que estoy trabajando acaba de hacer eso. Pasó datos dinámicamente a Recyclerview desde la actividad de fragmentación sin iconos y también colocó un diseño relativo (dentro de las vistas de texto y la vista de imágenes) que actúa como encabezado en la parte superior de Recyclerview.

Debasish Ghosh
fuente
0

Esto funcionó para mí:

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);
Faisal Shaikh
fuente
0
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")
Soumen Das
fuente
-1

Tengo el mismo problema, pero las dos soluciones dadas no funcionaron para mí

java.lang.IllegalStateException: No se encontró la vista requerida 'nav_header_username' con ID 2131296646 para el campo 'username'. Si esta vista es opcional, agregue la anotación '@Nullable' (campos) o '@Optional' (métodos).

Tengo casi el mismo código que el publicado arriba:

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());
Aman Bhatia
fuente
Eso no responde a la pregunta del OP
Nikolai Shevchenko