视频播放 (三) 视频列表

1. 配置信息 

  1.1 AndroidManifest.xml 添加网络权限

<uses-permission android:name="android.permission.INTERNET" />

  1.2 使用 Http 明文设置

 android:usesCleartextTraffic="true"

  1.3 使用竖屏设置

android:screenOrientation="portrait"

  1.4 使用协程引用库

implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.0-alpha03'

  1.5 themes.xml 文件设置无操作栏, 全屏 

 Theme.MaterialComponents.DayNight.NoActionBar
  <item name="android:windowFullscreen">true</item>

  1.6 功能说明

  使用ViewPager2的嵌套实现左右、上下滑动的列表视频播放

2. 实现 Fool 页面

  2.1 布局文件 fragment_foo.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"
    tools:context=".FooFragment">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:text="@string/hello_blank_fragment"
        android:textSize="24sp" />
</FrameLayout>

  2.2 调用布局 FooFragment.kt

class FooFragment : Fragment() {
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.fragment_foo, container, false)
    }
}

3. Player 视频播放View

  3.1 布局文件 fragment_player.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"
    tools:context=".PlayerFragment">

    <SurfaceView
        android:id="@+id/surfaceView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <ProgressBar
        android:id="@+id/progressBar"
        style="?android:attr/progressBarStyle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center" />

    <ProgressBar
        android:id="@+id/progressBarHor"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom" />
</FrameLayout>

  3.2 实现播放器 PlayerFragment.kt

class PlayerFragment(private val url:String) : Fragment() {
    private var mediaPlayer = MediaPlayer()

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.fragment_player, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        val progressBar: ProgressBar = view.findViewById(R.id.progressBar)
        val progressBarHor: ProgressBar = view.findViewById(R.id.progressBarHor)
        val surfaceView: SurfaceView = view.findViewById(R.id.surfaceView)
        mediaPlayer.apply {
            setOnPreparedListener {
                progressBarHor.max = mediaPlayer.duration
                //it.start();
                seekTo(1)
                progressBar.visibility = View.INVISIBLE
            }
            setDataSource(url)
            prepareAsync()
            progressBar.visibility = View.VISIBLE
        }
        //kut
       lifecycleScope.launch {
           while (true){
               progressBarHor.progress = mediaPlayer.currentPosition
               delay(500)
           }
       }
        surfaceView.holder.addCallback(object : SurfaceHolder.Callback{
            override fun surfaceCreated(holder: SurfaceHolder) {}

            override fun surfaceChanged(
                holder: SurfaceHolder,
                format: Int,
                width: Int,
                height: Int
            ) {
                mediaPlayer.setDisplay(holder)
                //屏幕不关闭
                mediaPlayer.setScreenOnWhilePlaying(true)
            }
            override fun surfaceDestroyed(holder: SurfaceHolder) {}
        })
    }

    override fun onResume() {
        super.onResume()
        mediaPlayer.start()
        lifecycleScope.launch {
            while (!mediaPlayer.isPlaying){
                mediaPlayer.start()
                delay(500)
            }
        }
    }

    override fun onPause() {
        super.onPause()
        mediaPlayer.pause()
    }
}

4. 播放列表

  4.1 布局文件 fragment_video.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"
    tools:context=".VideoFragment">

    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/videoViewPager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" />
</FrameLayout>

  4.2 调用布局实现 VideoFragment.kt

private val videoUrls: List<String> = listOf(
    "https://v-cdn.zjol.com.cn/280443.mp4",
    "https://v-cdn.zjol.com.cn/276982.mp4",
    "https://v-cdn.zjol.com.cn/276984.mp4",
    "https://v-cdn.zjol.com.cn/276985.mp4",
    "https://v-cdn.zjol.com.cn/276986.mp4",
    "https://v-cdn.zjol.com.cn/276987.mp4",
    "https://v-cdn.zjol.com.cn/276988.mp4",
    "https://v-cdn.zjol.com.cn/276989.mp4",
    "https://v-cdn.zjol.com.cn/276990.mp4",
    "https://v-cdn.zjol.com.cn/276991.mp4",
    "https://v-cdn.zjol.com.cn/276992.mp4",
    "https://v-cdn.zjol.com.cn/276993.mp4",
    "https://v-cdn.zjol.com.cn/276994.mp4",
    "https://v-cdn.zjol.com.cn/276996.mp4",
    "https://v-cdn.zjol.com.cn/276998.mp4",
    "https://v-cdn.zjol.com.cn/277000.mp4",
    "https://v-cdn.zjol.com.cn/277001.mp4",
    "https://v-cdn.zjol.com.cn/277002.mp4",
    "https://v-cdn.zjol.com.cn/277003.mp4",
    "https://v-cdn.zjol.com.cn/277004.mp4"
)

class VideoFragment : Fragment() {
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.fragment_video, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        val videoViewPager: ViewPager2 = view.findViewById(R.id.videoViewPager)
        videoViewPager.apply {
            adapter = object : FragmentStateAdapter(this@VideoFragment) {
                override fun getItemCount() = videoUrls.size

                override fun createFragment(position: Int) = PlayerFragment(videoUrls[position])
            }
            setCurrentItem(0, false)
           // offscreenPageLimit = 5
        }
    }
}

5. 主页实现

  5.1 布局文件, activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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" >

    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/mainViewPager"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <com.google.android.material.tabs.TabLayout
        android:id="@+id/tabLayout"
        android:layout_width="200dp"
        android:layout_height="50dp"
        android:layout_gravity="center_horizontal"
        android:background="#00FFFFFF"
        app:tabIndicatorFullWidth="false" />
</FrameLayout>

  5.2 实现 VideoFragment 的调用, MainActivity.kt

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val tabLayout: TabLayout = findViewById(R.id.tabLayout)
        val mainViewPackage2: ViewPager2 = findViewById(R.id.mainViewPager)
        mainViewPackage2.apply {
            adapter = object : FragmentStateAdapter(this@MainActivity) {
                override fun getItemCount() = 3
                override fun createFragment(position: Int) = when (position) {
                    1 -> VideoFragment()
                    else -> FooFragment()
                }
            }
            setCurrentItem(1, false)
        }

        TabLayoutMediator(tabLayout, mainViewPackage2) { tab: TabLayout.Tab, i: Int ->
            tab.text = when (i) {
                1 -> "video"
                else -> "foo"
            }
        }.attach()
    }
}

6. 效果图

猜你喜欢

转载自blog.csdn.net/u011193452/article/details/128138513