为什么findViewById()返回“null”?

Why does findViewById() returns "null"?

提问人:Kaki In 提问时间:5/7/2021 最后编辑:Kaki In 更新时间:5/10/2021 访问量:420

问:

我在 java 上有一个重要问题,
我有这段代码:

package fr.christian.lbcde;

import android.os.Bundle;

import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar;
import com.google.android.material.tabs.TabLayout;

import androidx.lifecycle.ViewModelProvider;
import androidx.viewpager.widget.ViewPager;
import androidx.appcompat.app.AppCompatActivity;

import android.text.Layout;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.Toast;

import fr.christian.lbcde.ui.main.PageViewModel;
import fr.christian.lbcde.ui.main.SectionsPagerAdapter;

public class MainActivity extends AppCompatActivity {

    PageViewModel pageViewModel;
    View activity_main, tab_create, tab_connect;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        pageViewModel = new ViewModelProvider(this).get(PageViewModel.class);
        SectionsPagerAdapter sectionsPagerAdapter = new SectionsPagerAdapter(this, getSupportFragmentManager());
        ViewPager viewPager = findViewById(R.id.view_pager);
        viewPager.setAdapter(sectionsPagerAdapter);
        TabLayout tabs = findViewById(R.id.tabs);
        tabs.setupWithViewPager(viewPager);
        FloatingActionButton fab = findViewById(R.id.fab);

        tab_connect = findViewById(R.id.tab_connect);
        tab_create = findViewById(R.id.tab_create);
        System.out.print("Result of tab_connect : ");
        System.out.print(findViewById(R.id.tab_connect));
        System.out.print(" ");
        System.out.println(tab_connect==null);
        System.out.print("Result of tab_create : ");
        System.out.print(findViewById(R.id.tab_create));
        System.out.print(" ");
        System.out.println(tab_create==null);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                addNew();
            }
        });
//        hideAll();
//        tab_connect.setVisibility(View.VISIBLE);
        pageViewModel.addTabListener(new PageViewModel.tabChangeListener() {
            @Override
            public void onChangeTab(View view, int tab) {
                switch (tab) {
                    case 1:
                        hideAll();
                        tab_connect.setVisibility(View.VISIBLE);
                        break;
                    case 2:
                        hideAll();
                        tab_create.setVisibility(View.VISIBLE);
                        break;
                    default:
                        new Toast(getApplicationContext())
                                .makeText(getApplicationContext(), "Rien a afficher pour cet onglet", Toast.LENGTH_SHORT)
                                .show();
                }
            }
        });
    }

    public void addNew() {
        new Toast(getApplicationContext())
                .makeText(getApplicationContext(), "Cette option n'est pas encore disponible", Toast.LENGTH_SHORT)
                .show();
    }

    public void hideAll() {
        View[] views = {
                tab_create,
                tab_connect
        };
        for (int i = 0; i < views.length; i++) {
            views[i].setVisibility(View.INVISIBLE);
        }
        ;
    }

}

和我的布局的四个文件:

活动 main.xml :

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <com.google.android.material.appbar.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/Theme.LeBonCoinDeLÉvangile.AppBarOverlay">

        <TextView
            android:id="@+id/title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:minHeight="?actionBarSize"
            android:padding="@dimen/appbar_padding"
            android:text="@string/app_name"
            android:textAppearance="@style/TextAppearance.Widget.AppCompat.Toolbar.Title" />

        <com.google.android.material.tabs.TabLayout
            android:id="@+id/tabs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="?attr/colorPrimary"
            app:tabSelectedTextColor="?attr/colorPrimaryVariant"/>
    </com.google.android.material.appbar.AppBarLayout>

    <androidx.viewpager.widget.ViewPager
        android:id="@+id/view_pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="@dimen/fab_margin"
        android:background="?attr/colorPrimary"
        app:srcCompat="@android:drawable/ic_menu_info_details" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>


fragment_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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/constraintLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".ui.main.PlaceholderFragment">

    <ScrollView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginStart="@dimen/activity_horizontal_margin"
        android:layout_marginTop="@dimen/activity_vertical_margin"
        android:layout_marginEnd="@dimen/activity_horizontal_margin"
        android:layout_marginBottom="@dimen/activity_vertical_margin">
        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:orientation="horizontal">
            <include layout="@layout/login_main"/>
            <include layout="@layout/create_main"/>
        </LinearLayout>
    </ScrollView>

</androidx.constraintlayout.widget.ConstraintLayout>

create_main.xml :

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:id="@+id/tab_create"
    android:orientation="vertical"
    android:layout_marginStart="@dimen/activity_horizontal_margin"
    android:layout_marginTop="@dimen/activity_vertical_margin"
    android:layout_marginEnd="@dimen/activity_horizontal_margin"
    android:layout_marginBottom="@dimen/activity_vertical_margin"
    android:visibility="invisible">
    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="TAB_CREATE"/>
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="BONJOUR LES ÉLËPHANTS"/>
</LinearLayout>

和login_main.xml:

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:id="@+id/tab_connect"
    android:orientation="vertical"
    android:layout_marginStart="@dimen/activity_horizontal_margin"
    android:layout_marginTop="@dimen/activity_vertical_margin"
    android:layout_marginEnd="@dimen/activity_horizontal_margin"
    android:layout_marginBottom="@dimen/activity_vertical_margin">
    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="TAB_CONNECT"/>
    <TextView
        style="@style/h2textStyle"
        android:text="@string/titleConnect_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <EditText
        android:id="@+id/loginConnect_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10"
        android:inputType="textPersonName"
        android:text="Name" />
</LinearLayout>



问题是在以下行:
System.out.print(findViewById(R.id.tab_connect));


System.out.print(findViewById(R.id.tab_create));

我有这个结果(对于两者):

null

所以我无法删除错误“java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法'void android.view.View.setVisibility(int)'”,等等......因为当我初始化我的布局时,它们是用一个空对象(而不是我的布局)初始化的。
我添加一些行,例如
hideAll()tab_create.setVisibility(View.VISIBLE)

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="TAB_CREATE"/>

在我的文件中查看这些选项卡是否真的是我在屏幕上看到的选项卡,并且看起来我真的看到了它们(当我取消具有布局可见性的行时)。
感谢您的帮助!

java android xml android 布局 nullpointerexception

评论

0赞 Benkerroum Mohamed 5/7/2021
请参见 : developer.android.com/reference/android/widget/TextView
0赞 Kaki In 5/14/2021
好的,问题不在这里(但仍然感谢您),我使用选项卡式活动,因此每个选项卡都包含彼此不同的fragment_main,因此我必须编辑 PlaceholderFragment.java 文件中的内容。我无法回答自己,因为我没有足够的声誉 😑

答:

1赞 laalto 5/7/2021 #1

你的等在布局中是d,而不是在你调用这些id时被夸大的布局中。您发布的代码不会显示您的使用位置,但可以肯定的是,当您尝试查找这些视图时,它不在活动的视图层次结构中。tab_connectincludefragment_mainactivity_mainfindViewById()fragment_main

将调用和您对视图执行的任何操作移动到 Fragment,或者将视图从 Fragment 移动到主 Activity。findViewById()

评论

0赞 Kaki In 5/8/2021
感谢您的回答,我将进行验证,但是如果我能看到线性布局的内容,它们通常位于XML层次结构中
1赞 laalto 5/8/2021
它们最终是视图层次结构的一部分,但在活动 onCreate() 时不是
0赞 Kaki In 5/9/2021
对不起,这不是我的工作,所以我不明白它真的改变了什么,对不起。
0赞 Kaki In 5/10/2021
我推送了 fragment main,但我没有正确关闭活动主代码,所以 fragment main 就在对不起之下。我现在安排
0赞 Kaki In 5/14/2021
好的,我意识到我在一个选项卡中看到的线性布局在第二个选项卡上被克隆了,所以我有两个线性布局,因为在两个不同的选项卡中,但是当我更改每个示例一个选项卡中的 EditText 文本时,它不会更改第二个选项卡中的那些。所以我没有真正的tab_create布局