【问题标题】:Accessing widget from other layout with 'findViewById' returns null使用“findViewById”从其他布局访问小部件返回 null
【发布时间】:2019-09-09 17:35:31
【问题描述】:

我正在尝试获取 Switch 小部件的状态。为此,我创建了一个新变量,如下所示: Switch notifSwitch = findViewById(R.id.notif_switch).

但这不起作用,因为现在 notifSwitchnull 并且投射 setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() 让我得到 java.lang.NullPointerException

我怀疑这与以下事实有关我在onCreate 方法的开头传递给setContentView 的布局,因为如果我在Switchdeclaration 之前添加setContentView(R.layout.line_notif);,则代码可以正常工作。该应用程序仅包含line_notif.xmllayout 中的内容,即只有SwitchTextView,但至少我没有任何错误并且我能够获得Switch 的状态小部件。

我不知道如何从我的MainActivity.javafile 访问小部件,也找不到这样做的方法。在制作自己的帖子之前,我尝试查看尽可能多的帖子。如果我错过了一个回答我的问题的人,我很抱歉,但我找不到解决这个问题的方法,非常感谢您的帮助。

谢谢。

MainActivity.java:

...
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
public class MainActivity extends AppCompatActivity
        implements NavigationView.OnNavigationItemSelectedListener {

    private MainActivity activity;
    private boolean notificationsOn=false;

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

        this.activity = this;

        ...

        // HERE IS THE PROBLEM

        Switch notifSwitch = findViewById(R.id.notif_switch); // notifSwitch = null
        // Error on next line
        notifSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked) {
                    notificationsOn = true;
                    Toast.makeText(getApplicationContext(), "Notifications enabled", Toast.LENGTH_SHORT).show();
                } else {
                    notificationsOn = false;
                    Toast.makeText(getApplicationContext(), "Notifications disabled", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }
...

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"
    android:background="@color/colorPrimary"
    tools:openDrawer="start">

    <include
        layout="@layout/app_bar_main"
        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_main"
        app:menu="@menu/activity_main_drawer"
        android:background="@color/colorPrimary"/>

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

activity_main_drawer.xml

<?xml version="1.0" encoding="utf-8"?>
<menu 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"
    tools:showIn="navigation_view"
    ...>

    ...

    <item
        android:id="@+id/nav_notifications"
        app:actionLayout="@layout/line_notif"
        android:enabled="true"
        tools:ignore="MenuTitle" />

    ...

</menu>

line_notif.xml

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:id="@+id/line_notif"
    android:background="@android:color/transparent">

    ...

    <Switch
        android:id="@+id/notif_switch"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:gravity="end"
        android:theme="@style/SwitchTheme"
        android:layout_alignParentStart="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentEnd="true"
        android:layout_alignParentRight="true"
        android:paddingTop="15dp"/>

</RelativeLayout>

完全错误:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.projectname/com.example.projectname.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Switch.setOnCheckedChangeListener(android.widget.CompoundButton$OnCheckedChangeListener)' on a null object reference

【问题讨论】:

  • notif_switch 应该在您的 activity_main.xml 中,或者如果它在其他布局中可用,则该布局必须包含在 activity_main.xml 中。发布您的activity_main.xml 文件
  • 能否分享您的 .xml 文件以获取见解
  • 刚刚添加了 .xml 文件
  • @Zoe 好的,我明白了,我正在删除它,抱歉我不知道。感谢您的欢迎!
  • 如果你会在 onCreateOptionsMenu() 方法中找到你的视图。然后你可以得到那个 Switch 但 checkChange 事件没有触发。我也在努力。请参阅此链接以获取更多帮助:stackoverflow.com/questions/32091709/…

标签: java android android-layout android-widget


【解决方案1】:

我怀疑这与以下事实有关我在onCreate 方法开始时传递给setContentView 的布局

你是对的,这就是问题所在。我建议您阅读this post,了解如何创建小部件。您将了解到小部件中允许的组件是有限的,因此您与它们的交互也是有限的。

【讨论】:

  • 谢谢,我会这样做的!
猜你喜欢
  • 2013-03-20
  • 2010-12-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-16
相关资源
最近更新 更多