【问题标题】:getSupportFragmentManager().findFragmentById(R.id.fragment_id) returns nullgetSupportFragmentManager().findFragmentById(R.id.fragment_id) 返回 null
【发布时间】:2019-11-03 23:56:27
【问题描述】:

我有一个带有片段的基本应用程序。我的 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

【问题讨论】:

  • 为什么你的 Activity 会进入 Fragment 的布局?添加YouTubePlayerSupportFragment 的片段不应该是与之交互的片段吗?
  • 尝试使用下面一个
  • @ianhanniballake 所以你建议我将所有与 YTPF 相关的代码移到 Fragments Java 文件中?
  • 或者直接将&lt;fragment&gt;移动到你的Activity布局中。 Fragment 的全部意义在于封装 UI 的一部分。

标签: android android-fragments


【解决方案1】:

您将静态和动态片段混为一谈。您在 XML 中定义的片段(带有&lt;fragment /&gt; 标签)不会通过FragmentManager 加载,而是在您的布局膨胀时自动创建。

用您的fragment 代码完全替换您的FrameLayout,然后访问:

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

编辑: 我在 YouTube 片段上写了另一个答案,其中包含更详细的示例代码,说明您的 Activity 应该如何查看here

编辑 2:

如果 RadioFragment 的布局包含您的 YouTube 片段,那么您应该保持 Activity 代码不变,而是在 RadioFragment 中初始化您的 YouTube 片段。您可能需要使用 getChildFragmentManager() 而不是 getFragmentManager(),因为 YouTube 片段嵌入在另一个片段中 (RadioFragment)

【讨论】:

  • 但片段还有其他部分,而不仅仅是 YT 播放器
  • 那么您的 YouTube 片段嵌入在 RadioFragment 中了吗?在这种情况下,您需要运行我在RadioFragment 中发布的代码,而不是您的 Activity,因为 YouTube 片段是 RadioFragment 布局的一部分。请记住,您可能还需要使用 getChildFragmentManager() 而不是 getFragmentManager()(请参阅我的更新)
【解决方案2】:

当您在 Fragment 的布局中使用 &lt;fragment&gt; 标签时,它会被添加为子 Fragment。这意味着YouTubePlayerSupportFragment不是添加到 Activity 的 FragmentManager,而是添加到该 Fragment 的 getChildFragmentManager()

这意味着检索您的YouTubePlayerSupportFragment 的正确方法是从创建它的片段中 - 您的RadioFragment。在您的RadioFragment 中,您可以使用:

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

一般来说,您的 Activity 永远不应该进入它添加的片段的布局,也不应该在其中创建子片段。相反,您希望您的 RadioFragment 管理它直接创建的 YouTubePlayerSupportFragment,而不涉及 Activity。

【讨论】:

  • 谢谢你的建议和解释,我会试试的!
  • 你用什么方法调用它?它必须在 之后 onCreateView (因为那是布局膨胀的原因),所以通常这是你在 onViewCreated() 中所做的事情
  • 非常感谢!一旦我把我的代码放在 onViewCreated() 中,它就起作用了!
猜你喜欢
  • 2023-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多