我正在尝试更改NavigationView子级的文本。我正在使用findViewById直接获取TextView。它可以在MainActivity中使用,但在其他所有Activity中,findViewById都返回空引用。
顺便说一句,这是我第一个提交的问题,希望我能遵守指南。
我似乎无法弄清楚这一点,所以我不知道从哪里开始。
这是每个活动布局中的NavigationView
<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:visibility="visible"
app:headerLayout="@layout/nav_header_main"
app:menu="@menu/activity_main_drawer"/>
nav_header_main是具有上述TextView的组件,在上面的代码中被引用。这是nav_header_main:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/nav_header"
android:theme="@style/ThemeOverlay.AppCompat.Dark">
<TextView
android:id="@+id/nav_header_textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:text="Angheluta Filip"
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
android:textColor="@android:color/white" />
</LinearLayout>
此代码来自MainActivity,在其中找到所述文本视图不会返回空引用
NavigationManager navigationManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Downloads the database and than proceeds to setup the Activity
//onDataChange gets called when the download is finished and dataSnapshot is the downloaded
//data
final AppCompatActivity context = this;
FirebaseHandler.getFirebaseHandler().getReference().addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
FirebaseHandler.getFirebaseHandler().setData(dataSnapshot);
DataSnapshot userSnapshot = dataSnapshot.child("Users").child(FirebaseHandler.getFirebaseHandler().getAuth().getUid());
User.initializeCurrentUser(userSnapshot);
//Add side bar to this activity
navigationManager = new NavigationManager(context);
navigationManager.createNavBar();
//Recycler view setup
RecyclerManager recyclerManager = new RecyclerManager();
recyclerManager.createRecyclerWithLargeElements(context, Voluntariat.getDataSet());
//Sort spinner setup
SortSpinnerManager sortSpinnerManager = new SortSpinnerManager();
sortSpinnerManager.createSortSpinnerManager(context, recyclerManager);
//Search bar setup
SearchBarManager searchBarManager = new SearchBarManager();
searchBarManager.createSearchBar(context, recyclerManager, Voluntariat.getDataSet());
TextView textViewHeader = findViewById(R.id.nav_header_textView);
Log.d("textHeader", textViewHeader.getText().toString());
textViewHeader.setText(User.currentUser.lastName + " " + User.currentUser.firstName);
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}
但这来自onCreate方法中的任何其他活动
RecyclerManager recyclerManager;
NavigationManager navigationManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_toate_vol);
//Add side bar to this activity
navigationManager = new NavigationManager(this);
navigationManager.createNavBar();
//RECYCLERVIEW SETUP
recyclerManager = new RecyclerManager();
recyclerManager.createRecyclerWithSmallElements(this, Voluntariat.getDataSet());
//Search bar managing
SearchBarManager searchBarManager = new SearchBarManager();
searchBarManager.createSearchBar(this, recyclerManager, Voluntariat.getDataSet());
TextView textViewHeader = findViewById(R.id.nav_header_textView);
Log.d("textHeader", textViewHeader.getText().toString());
textViewHeader.setText(User.currentUser.lastName + " " + User.currentUser.firstName);
}
当我访问MainActivity以外的任何活动时,在textViewHeader上会收到NullPointerException。
编辑:我添加了更多代码,并对其进行了更改,因此直接从Activity文件而不是从NavigationManager文件中调用findViewById。错误是一样的。
EDIT2:从activity_toate_vol.xml添加了更多代码:
此布局似乎没有带问题ID的任何视图,但该ID位于nav_header_main.xml文件中,该文件是在具有headerLayout属性的activity_toate_vol.xml文件中设置的:
app:headerLayout="@layout/nav_header_main"
此NavigationView是根布局的直接子级,其余代码无关。在MainActivity中也可以找到相同的导航视图。
<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:visibility="visible"
app:headerLayout="@layout/nav_header_main"
app:menu="@menu/activity_main_drawer">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="bottom"
android:gravity="bottom"
android:orientation="vertical"
android:padding="16dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:gravity="bottom"
android:orientation="horizontal">
<ImageView
android:id="@+id/imgdeconctare"
android:layout_width="27dp"
android:layout_height="27dp"
android:alpha=".6"
android:src="@drawable/ic_logout"
app:srcCompat="@drawable/ic_logout"
tools:srcCompat="@drawable/ic_logout" />
<TextView
android:id="@+id/logout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="20dp"
android:gravity="center|start"
android:text="Deconectare"
android:textColor="@android:color/black" />
</LinearLayout>
</LinearLayout>
</android.support.design.widget.NavigationView>
编辑3:我想出了一种解决方法,并且也确定了问题所在。事实证明,在更新文本之前,我必须以某种方式等待NavigationView膨胀。谁能帮助我以适当的方式做到这一点?因为我对此不满意。
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
try {
wait(150);
}
catch(Exception e){
}
TextView textViewHeader = findViewById(R.id.nav_header_textView);
Log.d("textHeader", textViewHeader.getText().toString());
textViewHeader.setText(User.currentUser.lastName + " " + User.currentUser.firstName);
}
}, 100);
答案 0 :(得分:0)
欢迎光临!当findViewById
返回null时,可能意味着两件事。
1)您传递给'setContentView'的布局没有具有该ID的视图...
2)布局确实具有该视图,但是视图本身尚未完全膨胀。要等到视图完全膨胀后,可以使用GlobalLayoutListener
在Java中:
setContentView(R.layout.activity_other);
final NavigationView navigationView = findViewById(R.id.nav_view);
navigationView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
TextView text = navigationView.findViewById(R.id.nav_header_textView);
text.setText("Hello StackOverflow");
navigationView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
});
以及当您切换到Kotlin时:
setContentView(R.layout.activity_main)
val view = findViewById<NavigationView>(R.id.nav_view)
view?.viewTreeObserver?.addOnGlobalLayoutListener(object: ViewTreeObserver.OnGlobalLayoutListener{
override fun onGlobalLayout() {
val header = findViewById<TextView>(R.id.nav_header_textView)
header.text= "Hallo Main"
view.viewTreeObserver.removeOnGlobalLayoutListener(this)
}
})