getSupportFragmentManager (). findFragmentById (R.id.fragment_id) возвращает ноль - PullRequest
0 голосов
/ 03 ноября 2019

У меня есть базовое приложение с фрагментами. У моего Activity_main.xml есть

<FrameLayout
        android:id="@+id/fragment_container"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_marginTop="200dp"
        android:background="@android:color/holo_green_light" />

, и в одном из моих фрагментов .xml файлов у меня есть

<fragment
            android:tag="youtube_tag"
            android:id="@+id/youtube_player_fragment"
            android:name="com.google.android.youtube.player.YouTubePlayerSupportFragment"
            android:layout_width="match_parent"
            android:layout_height="300dp"
            android:layout_marginBottom="8dp"/>

, который я хочу инициализировать. Я делаю это из моего MainActivity.java. Моя функция onCreate:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ...some other code...
        getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new RadioFragment()).commit();
        ...some other code...
        initializeYoutubePlayer();
        ....some other code....
    }

, где initializeYoutubePlayer();:

youTubePlayerFragment = (YouTubePlayerSupportFragment)getSupportFragmentManager().findFragmentById(R.id.youtube_player_fragment);
....some other code...

, а RadioFragment - это java-файл нужного фрагмента, а его содержимое:

public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_radio, container, false);
    }

строка в initializeYoutubePlayer(); возвращает нулевой указатель, а затем в коде я получаю NPE .

Ответы [ 2 ]

0 голосов
/ 03 ноября 2019

Когда вы используете тег <fragment> в макете фрагмента, он добавляется как дочерний фрагмент. Это означает, что YouTubePlayerSupportFragment является не добавленным в FragmentManager Деятельности, а к этому getChildFragmentManager().

этого фрагмента. Это означает, что правильный способ получения вашего YouTubePlayerSupportFragment находится изнутриФрагмент, который его создал - ваш RadioFragment. Внутри вашего RadioFragment вы можете использовать:

youTubePlayerFragment = (YouTubePlayerSupportFragment)
   getChildFragmentManager().findFragmentById(R.id.youtube_player_fragment);

Как правило, ваша активность никогда не должна попадать ни в макет добавляемых фрагментов, ни в дочерние фрагменты, созданные внутри. Вместо этого вы бы хотели, чтобы ваш RadioFragment управлял YouTubePlayerSupportFragment, который он создает напрямую, и вообще не включал в себя действие.

0 голосов
/ 03 ноября 2019

Вы объединяете статические и динамические фрагменты. Фрагмент, который вы определили в XML (с тегом <fragment />), не загружается через FragmentManager, но автоматически создается при накачке макета.

Замените ваш FrameLayout полностью на ваш fragment код и доступ с помощью:

final YouTubeSupportFragment frag = (YouTubeSupportFragment) getSupportFragmentManager().findFragmentById(R.id.whatever_id_you_use);
frag.initalize(...);

Редактировать: Я написал еще один ответ на фрагменте YouTube, в котором приведен более подробный пример кода того, как должна выглядеть ваша активность здесь

Изменить 2:

Если RadioFragment имеет макет, который включает в себя ваш фрагмент YouTube, то вы должны оставить свой код активности таким, какой он есть,и вместо этого инициализируйте свой фрагмент YouTube внутри RadioFragment. Возможно, вам придется использовать getChildFragmentManager() вместо getFragmentManager(), поскольку фрагмент YouTube встроен в другой фрагмент (RadioFragment)

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