findViewById завершается ошибкой в ​​onView, созданном из PreferenceFragment, Android - PullRequest
0 голосов
/ 27 февраля 2019

У меня есть два фрагмента:
- HomeFragment, который расширяет Fragment
- SettingsFragment, который расширяет PreferenceFragment

Каждый содержит TextView, к которому я хочу получить доступ и изменить его содержимое в коде Java,Я делаю эту модификацию внутри onViewCreated, вызывая findViewById, а затем, используя setText на TextView.
. Это прекрасно работает для HomeFragment, но не в SettingsFragment.
Для информации TextView из SettingsFragment определяется в макете, связанном с предпочтением.Странно, но иерархия представлений типа PreferenceFragment не полностью готова в onViewCreated!Чтобы пойти дальше, я попытался поместить код, который изменяет TextView после некоторой задержки (с использованием postDelay), и это сработало!

Ниже я поместил весь код, необходимый для проверки моей проблемытолько что поднят.

MainActivity.java

public class MainActivity extends AppCompatActivity {

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

        final HomeFragment homeFragment = new HomeFragment();
        final SettingsFragment settingsFragment = new SettingsFragment();

        getFragmentManager().beginTransaction()
                .add(R.id.fragmentContainer, homeFragment).commit();

        // Just a simple button to switch between the two fragments
        Button button = findViewById(R.id.activityButton);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(homeFragment.isAdded()) {
                    getFragmentManager().beginTransaction()
                            .replace(R.id.fragmentContainer, settingsFragment).commit();
                } else {
                    getFragmentManager().beginTransaction()
                            .replace(R.id.fragmentContainer, homeFragment).commit();
                }
            }
        });
    }
}

HomeFragment.java

public class HomeFragment extends Fragment {

    public HomeFragment() {
        // Required empty public constructor
    }

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_home, container, false);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        TextView textView = view.findViewById(R.id.homeText);
        if(textView != null) {
            textView.setText("Home fragment text (modified)");
        }
    }
}

SettingsFragment.java

public class SettingsFragment extends PreferenceFragment {


    public SettingsFragment() {
        // Required empty public constructor
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        addPreferencesFromResource(R.xml.fragment_settings);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        return super.onCreateView(inflater, container, savedInstanceState);
    }

    @Override
    public void onViewCreated(final View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        // ---- BLOCK 1 -----
        TextView textView = view.findViewById(R.id.settingsText);
        if (textView != null) {
            textView.setText("Preference 1 (modified)");
        }

        // ---- BLOCK 2 -----
//        view.post(new Runnable() {
//            @Override
//            public void run() {
//                TextView textView = view.findViewById(R.id.settingsText);
//                if (textView != null) {
//                    textView.setText("Preference 1 (modified)");
//                }
//            }
//        });

        // ---- BLOCK 3 -----
//        view.postDelayed(new Runnable() {
//            @Override
//            public void run() {
//                TextView textView = view.findViewById(R.id.settingsText);
//                if (textView != null) {
//                    textView.setText("Preference 1 (modified)");
//                }
//            }
//        }, 100);
    }
}

activity_main.xml

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

    <TextView
        android:id="@+id/activityText"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:gravity="center_horizontal"
        android:text="MainActivity" />

    <Button
        android:id="@+id/activityButton"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@id/activityText"
        android:text="Change fragment"/>

    <FrameLayout
        android:id="@+id/fragmentContainer"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintTop_toBottomOf="@id/activityButton"
        app:layout_constraintBottom_toBottomOf="parent">

    </FrameLayout>

</android.support.constraint.ConstraintLayout>

frag_home.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    tools:context=".HomeFragment">

    <TextView
        android:id="@+id/homeText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        android:text="Home fragment text" />

</android.support.constraint.ConstraintLayout>

frag_settings.xml

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <PreferenceCategory
        android:layout="@layout/preference_layout_category">

        <Preference
            android:enabled="true"
            android:layout="@layout/preference_layout" />

    </PreferenceCategory>
</PreferenceScreen>

preference_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <TextView
        android:id="@+id/settingsText"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:textAllCaps="true"
        android:text="Preference 1"/>

</android.support.constraint.ConstraintLayout>

preference_layout_category.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <TextView
        android:id="@+id/settingsTextContainer"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:textAllCaps="true"
        android:background="@android:color/background_dark"
        android:textColor="@android:color/background_light"
        android:text="Category 1"/>

</android.support.constraint.ConstraintLayout>

Ответы [ 2 ]

0 голосов
/ 27 февраля 2019

Свяжите ваши представления в onCreateView (), вместо этого, как это

View view= inflater.inflate(R.layout.your_fragment, container, false);
TextView textView = view.findViewById(R.id.settingsText);
return view;
0 голосов
/ 27 февраля 2019

У меня было что-то похожее на днях.Используйте метод findViewById () в onCreateView для фрагмента вместо метода onViewCreated.Удачи.

...