Доступ к виджету из другого макета с помощью 'findViewById' возвращает ноль - PullRequest
0 голосов
/ 19 апреля 2019

Я пытаюсь получить состояние виджета Switch. Для этого я создаю новую переменную так: Switch notifSwitch = findViewById(R.id.notif_switch).

Однако это не работает, потому что теперь notifSwitch равно null, а приведение setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() дает мне java.lang.NullPointerException.

Я подозреваю, что это связано с тем фактом, что виджет с идентификатором 'notif_switch' (Switch, который я пытаюсь получить значение) не (прямо) в activity_main.xml, то есть макет, который я передаю setContentView в начале моего onCreate метода, потому что, если я добавлю setContentView(R.layout.line_notif); до объявления Switch, код будет работать нормально. Приложение состоит только из того, что находится в макете line_notif.xml, то есть только Switch и TextView, но, по крайней мере, у меня нет ошибок, и я могу получить состояние Switch виджет.

Я не знаю, как получить доступ к виджету из моего файла MainActivity.java, и не могу найти способ сделать это. Я пытался просмотреть как можно больше постов, прежде чем создавать свои. Мне жаль, если я пропустил тот, который отвечает на мой вопрос, но я просто не могу найти способ решить эту проблему и буду очень признателен за помощь.

Спасибо.

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

1 Ответ

0 голосов
/ 19 апреля 2019

Я подозреваю, что это связано с тем фактом, что виджет с идентификатором 'notif_switch' (Switch, который я пытаюсь получить значение) не (напрямую) в activity_main.xmlЭто макет, который я передаю setContentView в начале моего onCreate метода

Вы правы, вот в чем проблема.Я предлагаю вам прочитать этот пост о том, как создавать виджеты.Вы узнаете, что компоненты, разрешенные в виджете, ограничены, и поэтому ваше взаимодействие с ними.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...