如何在Android片段中实例化YoutubePlayerView [英] How to instantiate YoutubePlayerView in an android fragment

查看:157
本文介绍了如何在Android片段中实例化YoutubePlayerView的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个应用程序,可以从youtube加载视频.我遇到的问题是我无法弄清楚如何在android片段中实例化YoutubePlayerView,因为我的应用程序只有一个活动,并且所有UI内容都是通过片段和导航图进行管理的.

I am creating an app which will load videos from youtube. The problem I am having is that i can not figure out how to instantiate a YoutubePlayerView inside an android fragment since my app only has one activity and all of the UI stuff is managed through fragments and navigation graph.

我唯一能想到的是在YoutubeBaseActivity中实例化YoutubePlayerView,这将损害导航的一致性,因为它将是一项新的活动.我尝试创建一个YoutubePlayerFragment,但无法将其设置为导航图中的目标.因此,如果有人能帮助我找出解决方法,我将不胜感激.:)

The only thing that i could figure out is instantiating YoutubePlayerView inside a YoutubeBaseActivity which will compromise the consistency of navigation since it will be a new activity. I tried creating a YoutubePlayerFragment but it can't be set as a destination in a navigation graph. So I will be thankful if anyone can help me figure out how to do this. :)

谢谢.

推荐答案

对于今天遇到此问题的任何人,这就是我所做的,并且非常适合Activity和Fragment.

For anyone having this issue today, this is what I did and it works perfectly for Activity and Fragment.

1.放置框架

在您的Activity或Fragment XML中,放置一个 FrameLayout .很简单.

In your Activity or Fragment XML, place a FrameLayout. Simple enough.

   <FrameLayout
    android:id="@+id/main_player"
    android:layout_width="match_parent"
    android:layout_height="0dp"/>

2.实例化YoutubePlayerSupportFragment并将其添加到框架布局

键入以下几行,如果在使用android.support.v4.Fragment时遇到错误,则必须创建一个新的自定义类YoutubePlayerSupportFragment.我认为发生此错误是因为YoutubePlayerSupportFragment类是从android.support.v4.Fragment扩展而来的,而我使用的是androidx,我不确定.尽管如此,我还是在点击侦听器中执行此操作,但是您可以在其他任何位置执行此操作,例如在 onViewCreated() onCreateView()

Type in the next lines and if you get an error regarding the use of android.support.v4.Fragment you're going to have to create a new custom class of YoutubePlayerSupportFragment. I think this error happens because the YoutubePlayerSupportFragment class extends from android.support.v4.Fragment and I'm using androidx, I'm not sure. Still, I'm doing this inside a click listener, but you can do it anywhere else like in onViewCreated() or in onCreateView()

   val youtubePlayerSupportFragment = YouTubePlayerSupportFragment.newInstance()
                supportFragmentManager.beginTransaction()
                    .add(R.id.main_player, youtubePlayerSupportFragment).commit()
   // these lines of code populates the FrameLayout with a brand new YoutubePlayerSupportFragment
   // this code is actually for an Activity. If you want to do it for a fragment, replace the `supportFragmentManager` for `childFragmentManager` and it should work as well. It does for me.

因此,如果这些代码行给您带来错误,则您已在此确切的新路径 com.google.android.youtube.player 中并在其中创建了一个新类目录中创建一个新类.您可以随心所欲地调用它.只需复制并粘贴:

So if these lines of code give you error, you have create a new class in this exact new path com.google.android.youtube.player and inside this directory create a new class. You can call it whatever you want. Just copy and paste this:

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()
    }
}
}

第36行将留有红色下划线,但请注意.找不到解决方法,但是效果很好.

Line 36 is going to stay with a red underline but just dont pay atention to it. Couldn't find a way to solve it but it works fine.

就我而言,我使用的是自定义类,因此我在上面键入的代码行非常相似:

In my case, I'm using my custom class so the lines of code I typed above turn out to be very similar:

   val youtubePlayerSupportFragment = YouTubePlayerSupportFragmentX.newInstance() //notice this is my custom class, it ends with an X
                supportFragmentManager.beginTransaction()
                    .add(R.id.main_player, youtubePlayerSupportFragment).commit()

3.初始化YouTube播放器支持片段

现在,您应该准备好使用YoutubePlayerSupportFragment.

Now you should have your YoutubePlayerSupportFragment ready to go.

确定可以使用后,您必须初始化 youtubePlayer.您只需通过调用 youtubePlayerSupportFragment.initialize(apiKey,listener)来执行此操作.在括号内,您必须设置apiKey和一个侦听器.api密钥可以轻松生成,如果您没有api密钥,只需用谷歌搜索即可.对于收听者,您可以执行 ctrl + shift +空格键打开智能建议,它应该首先弹出.就我而言,它看起来像这样:

After being sure this works, you have to initialize the youtubePlayer. You have to do that just by calling youtubePlayerSupportFragment.initialize(apiKey, listener). Inside the parenthesis you have to set your apiKey and a listener. The api key can be generated easily, just google it if you don't have one. And for the listener you can do ctrl + shift + spacebar to open the smart suggestions, and it should pop up first. In my case it looks something like this:

val youtubePlayerSupportFragment = YouTubePlayerSupportFragmentX.newInstance() 
            supportFragmentManager.beginTransaction()
                .add(R.id.main_player, youtubePlayerSupportFragment).commit()

youtubePlayerSupportFragment.initialize(
                    resources.getString(R.string.API_KEY), //IF YOU HAVE NO API KEY IT WONT WORK. But that's actually explained in the docs. So you can google it easily if you don't have one
                    object : YouTubePlayer.OnInitializedListener {
                        override fun onInitializationSuccess(
                            p0: YouTubePlayer.Provider?,
                            p1: YouTubePlayer?,
                            p2: Boolean
                        ) {
                            p1?.loadVideo("9ET6R_MR1Ag") // string has to be https://www.youtube.com/watch?v=----------->9ET6R_MR1Ag<---------
                        }

                        override fun onInitializationFailure(
                            p0: YouTubePlayer.Provider?,
                            p1: YouTubeInitializationResult?
                        ) {
                            layoutUtils.createToast(
                                applicationContext,
                                "ERROR INITIATING YOUTUBE"
                            )
                        }
                    })

就是这样!是的,很多工作,但是值得.即使api文档写得不好并且有一些错误,它仍然可以正常工作.但是对于用户来说,它看起来就像youtube,因此它将为您的应用程序提供非常专业的外观.至少那是我实施它时得到的反馈.

And that's it! Lot of work, yeah, but it's worth it. It works perfectly even though the api documentation is poorly written and it has some bugs. But to the user looks exactly like youtube so it's going to give your app a very professional look. At least that's the feedback I got when I implemented it.

重要说明:

如果您要播放视频,并让用户能够按提示播放其他视频(例如,像youtube一样单击),则必须在初始化youtubePlayer时将其存储在变量中.例如:

If you want to play a video, and let the user be able to play other videos on cue, like on a click just like youtube, you have to store the youtubePlayer in a variable the moment it is initialized. For example:

var youtubePlayer: YoutubePlayer? = null // this is a global variable of your class

成功启动播放器后,请按以下方式存储它:

And when the player is successfully initiated, store it like this:

override fun onInitializationSuccess(
                            p0: YouTubePlayer.Provider?,
                            p1: YouTubePlayer?,
                            p2: Boolean
                        ) {
                            p1?.loadVideo(video)
                            youtubePlayer = p1 // <------- this line here
                        }

然后,您可以在代码的任何部分执行 youtubePlayer.loadVideo(anotherLink),它将自动停止当前视频并开始播放新视频.

Then in any part of your code you can just do youtubePlayer.loadVideo(anotherLink) and it will automatically stop the current video and start playing the new one.

这篇关于如何在Android片段中实例化YoutubePlayerView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆