Youtube 播放器支持片段不再适用于 Android studio 3.2 (androidx)

Youtube player support fragment no longer working on Android studio 3.2 (androidx)

我刚刚将我的 Android Studio 更新到版本 3.2 并按照说明使用 androidx。

我一直在 Fragment activity 中使用 Youtube 片段并且一切正常,但是在更新之后,这 3 行简单的代码现在给我错误 "Cannot resolve method 'add(...)'":

YouTubePlayerSupportFragment youTubePlayerFragment = YouTubePlayerSupportFragment.newInstance();
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
transaction.add(R.id.youtube_fragment, youTubePlayerFragment).commit();

...当我尝试使用 "replace" 而不是 "add" 时,它说:"Wrong 2nd argument type. Found: 'com.google.android.youtube.player.YouTubePlayerSupportFragment', required: 'androidx.fragment.app.Fragment'"

...这让我认为问题与新的 AndroidX 功能有关。

问题是添加方法需要类型的第二个参数:

androidx.fragment.app.Fragment

...但是 YouTubePlayerSupportFragment returns a:

android.support.v4.app.Fragment

有谁知道如何解决这个问题? 有没有办法将 "android.support.v4.app.Fragment" 转换为 "androidx.fragment.app.Fragment"?

只需使用transaction.replace。忽略错误,它将起作用。 Google 尚未将 youtube api 库重构为 androidx

只需将原始 java 文件 (com.google.android.youtube.player.YouTubePlayerFragment) 复制到您的项目到同一个包但不同 class 名称等 com.google.android.youtube.player.YouTubePlayerFragmentX,并更新扩展 class 从 android.app.Fragmentandroidx.fragment.app.Fragment.

实现方式相同:

YouTubePlayerFragmentX youTubePlayerFragment = YouTubePlayerFragmentX.newInstance();
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
transaction.add(R.id.youtube_fragment, youTubePlayerFragment).commit();

已测试...有效。

我已经按照@Hosszful 的回答修复了它, 我通过使用这个文件使它变得简单,https://gist.github.com/medyo/f226b967213c3b8ec6f6bebb5338a492

替换.add

transaction.add(R.id.youtube_fragment, youTubePlayerFragment).commit();

用这个.replace

transaction.replace(R.id.youtube_fragment, youTubePlayerFragment).commit();

并复制this class到你的项目文件夹(可能需要创建以下文件夹)

java -> com -> google -> android -> youtube -> player -> (here name of) YouTubePlayerSupportFragmentX.java

然后在代码中替换

YouTubePlayerSupportFragmentYouTubePlayerSupportFragmentX.

我通过遵循代码块让它工作。

Object obj = 
getSupportFragmentManager().findFragmentById(R.id.youtube_player_fragment);
    if (obj instanceof YouTubePlayerSupportFragment)
        youTubePlayerFragment = (YouTubePlayerSupportFragment) obj;

在调试过程中,我发现 fragmentmanager 将成为 YouTubePlayerSupportFragment 的唯一实例。但是当我写

时编译器无法转换它
(YouTubePlayerSupportFragment) 
getSupportFragmentManager().findFragmentById(R.id.youtube_player_fragment);

上面的代码块 (instanceof ) 工作正常。

非常感谢@Hosszuful 和@Mehdi。我听从了你的建议,效果很好。

在我问这个问题几周后,我 "translated" 我的应用程序转向了 Kotlin,因此,我也尝试翻译你的答案。

这就是我最终得到的,它对我有用。

package com.google.android.youtube.player //<--- IMPORTANT!!!!

import android.os.Bundle
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.google.android.youtube.player.internal.ab
import java.util.*

class YouTubePlayerSupportFragmentX : Fragment(), YouTubePlayer.Provider {
    private val a = ViewBundle()
    private var b: Bundle? = null
    private var c: YouTubePlayerView? = null
    private var d: String? = null
    private var e: YouTubePlayer.OnInitializedListener? = null
    override fun initialize(var1: String, var2: YouTubePlayer.OnInitializedListener) {
        d = ab.a(var1, "Developer key cannot be null or empty")
        e = var2
        a()
    }

    private fun a() {
        if (c != null && e != null) {
            c?.a(this.activity, this, d, e, b)
            b = null
            e = null
        }
    }

    override fun onCreate(var1: Bundle?) {
        super.onCreate(var1)
        b = var1?.getBundle("YouTubePlayerSupportFragment.KEY_PLAYER_VIEW_STATE")
    }

    override fun onCreateView(var1: LayoutInflater, var2: ViewGroup?, var3: Bundle?): android.view.View? {
        c = YouTubePlayerView(Objects.requireNonNull(this.activity), null, 0, a)
        a()
        return c
    }

    override fun onStart() {
        super.onStart()
        c?.a()
    }

    override fun onResume() {
        super.onResume()
        c?.b()
    }

    override fun onPause() {
        c?.c()
        super.onPause()
    }

    override fun onSaveInstanceState(var1: Bundle) {
        super.onSaveInstanceState(var1)
        (if (c != null) c?.e() else b)?.let { var2 ->
            var1.putBundle("YouTubePlayerSupportFragment.KEY_PLAYER_VIEW_STATE", var2)
        }
    }

    override fun onStop() {
        c?.d()
        super.onStop()
    }

    override fun onDestroyView() {
        this.activity?.let { c?.c(it.isFinishing)  }
        c = null
        super.onDestroyView()
    }

    override fun onDestroy() {
        if (c != null) {
            val var1 = this.activity
            c?.b(var1 == null || var1.isFinishing)
        }
        super.onDestroy()
    }

    private inner class ViewBundle : YouTubePlayerView.b {
        override fun a(var1: YouTubePlayerView, var2: String, var3: YouTubePlayer.OnInitializedListener) {
            e?.let { initialize(var2, it) }
        }

        override fun a(var1: YouTubePlayerView) {}
    }

    companion object {
        fun newInstance(): YouTubePlayerSupportFragmentX {
            return YouTubePlayerSupportFragmentX()
        }
    }
}

可能有更好的方法来记录它,我们将不胜感激,但如果有人正在寻找此问题解决方案的 Kotlin 版本,那么这段代码应该可以。

PS:我将保留@Mehdi 的答案作为已接受的答案,因为他也与@Hosszuful 分享了荣誉,并且因为我的答案只是他们建议的 Kotlin 版本。

建议的解决方案没有用,直到我尝试了来自 Bek: Pierfrancesco Soffritti's android-youtube-player 的评论,该评论得到维护并且运行顺利。