Neglected Sanity Neglected Sanity - 8 months ago 64
Android Question

Can't find TextView from MainActivity

I have a DrawerLayout in my android app that has a NavigationView which is using a nav_header_main2 layout. Inside the nav_header_main2 layout file there is an ImageView and 2 TextViews, in my MainActivity I am trying to grab those TextView items so I can dynamically fill in the content with the username and email address, however I am always getting a null reference whenever I try to access them.
Here is the main layout file...

<?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_main2"
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_main2"
app:menu="@menu/activity_main2_drawer"/>

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


As you can see, the NavigationView is using "nav_header_main2", here is that file...

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
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">

<de.hdodenhof.circleimageview.CircleImageView
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/menu_user_photo"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_gravity="center_horizontal"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:src="@drawable/ic_person_white"
app:border_color="@color/colorTransparent"
android:layout_marginStart="10dp"
android:layout_marginLeft="10dp"
android:layout_marginTop="3dp"
android:layout_marginBottom="0dp"
app:border_width="1dp"/>

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

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

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

</LinearLayout>


Then in my MainActivity, I have tried multiple ways of accessing the "menu_username" item but all of them return a null reference. Here is my main class right now...

public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {

public static final String EXTRA_MESSAGE = "text.notreal.justatest.MESSAGE";
public static final int TAG_KEY = 0;
public static final int TAG_VALUE = 0;
public List<Post> posts = new ArrayList<>();

public FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
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);
//THIS IS WHAT IS FAILING
//I HAVE ALSO TRIED JUST USING findViewById(R.id.menu_username); NULL STILL
TextView menuUserName = (TextView) navigationView.findViewById(R.id.menu_username);
if(menuUserName == null) {
Log.d("MAIN ACTIVITY", "Somehow the menu_username doesn't exist");
}
if(findViewById(R.id.frameLayout) != null) {

if(savedInstanceState != null) {
return;
}
AllPostsFragment fragment = new AllPostsFragment();
fragment.setArguments(getIntent().getExtras());
getSupportFragmentManager().beginTransaction().add(R.id.frameLayout, fragment).commit();
}
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
case android.R.id.home:
this.finish();
return true;
default:
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_camera) {
// 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;
}
}


As you can see I am trying to grab it using the NavigationView object, which doesn't work, but I have also tried just using

TextView menuUsername = (TextView) findViewById(R.id.menu_username);


which also returns a null reference. How can I get the username and email fields in my main activity so I can dynamically fill in the content? Thank you

Answer Source

You won't find it that way. The proper way is first to find your NavigationView, then get its HeaderView using getHeaderView() and then search your widgets in that HeaverView:

NavigationView nv = findViewById(R.id.nav_view);
TextView menuUsername = nv.getHeaderView(0).findViewById(R.id.menu_username);
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download