视频feed流框架-原创

背景

目前抖音、快手、其他短剧app遍地都是,但是好用的开源的feed流框架基本没有

于是做了一款可商业化的视频流框架,供大家参考使用,直接上效果

在开源项目:github.com/TimShuai/Vi... 可以查看效果

技术选型

目前市面上视频feed流实现有以下四种方式:

1.ViewPager2和Fragment

优点:方案简单,开发成本低

缺点:fragment创建和销毁有一定的开销,会有明显掉帧情况

2.RecyclerView和PagerSnapHelper

优点:api更灵活,扩展性更强,性能好

缺点:item条目生命周期需要单独控制,需要额外单独处理多指操作和一直滑动情况
3.ViewPager2和RecyclerView.Adapter
优点:性能好,api成熟,多指操作和一直滑动情况兼容好
缺点:item条目生命周期需要单独控制

4.自定义viewpager 成本高,此方案暂不考虑
笔者选择了第三个方案

api使用说明

Feed流:使用ViewPager2实现

Page:TimItemView,条目view,每个itemview上都可以承载n层layer

Layer:layer中加载布局具体的文件

Layout:业务ui控制层,例如播放视频、播放进度等

VideoFeed用不到1000行代码实现了Feed流;有以下优势

  • 架构清晰,每层责任清楚
  • 单一原则,layout负责单一业务,代码简洁、逻辑清晰
  • 耦合度低,各个层级、业务不会产生依赖
  • 性能好,问题少,使用viewpager2性能几乎和RecyclerView差不多
  • 扩展性强,VideoFeed仅仅是帮我们实现Feeds,不关心具体业务
  • 播放器数量,在Video播放layout中,可复用一个播放器或者使用多个播放器,均没有问题

具体使用:
Feed流-viewpager2设置

图层layer

demo中广告层和其他图层是互斥的,demo中根据type进行了判断,例如

广告层 操作面板层 播放层

业务实现层

例如:PlayProgressLayout更新进度的Layout,可以看出它仅仅负责自己单一的进度任务就可以,与其他播放、title等全部是解偶的

kotlin 复制代码
class PlayProgressLayout(val activity: ComponentActivity): IBaseFeedItemLayout(activity) {
    private var progressSeekBar: SeekBar? = null
    private var durationObserver: Observer<Int>? = null
    private var progressObserver: Observer<Int>? = null
    override fun onTimCreateView(type: Int, itemView: View) {
        super.onTimCreateView(type, itemView)
        progressSeekBar = itemView.findViewById<SeekBar?>(R.id.progress_seek)?.apply {
            progress = 0
            max = mainViewModel.videoDuration.value ?: 100
        }
    }
    override fun onTimBindView(position: Int, data: TimData) {
        super.onTimBindView(position, data)
        this.position = position
        this.id = data.id
    }
    override fun onTimSelected() {
        super.onTimSelected()
        if (progressObserver == null) {
            progressObserver = Observer<Int> {
                progressSeekBar?.progress = it
            }
        }
        progressObserver?.let {
            mainViewModel.videoProgress.observe(act, it)
        }
        if (durationObserver == null) {
            durationObserver = Observer<Int> {
                progressSeekBar?.max = it
                Log.d(TAG, "duration = $it")
            }
        }
        durationObserver?.let {
            mainViewModel.videoDuration.observe(act, it)
        }
    }
    override fun onTimDeselected() {
        super.onTimDeselected()
        progressSeekBar?.progress = 0
        removeObserver()
    }
    private fun removeObserver() {
        durationObserver?.let {
            mainViewModel.videoDuration.removeObserver(it)
        }
        progressObserver?.let {
            mainViewModel.videoProgress.removeObserver(it)
        }
    }
    override fun onTimDestroyView() {
        removeObserver()
    }
}
相关推荐
Yang-Never3 天前
Open GL ES->以指定点为中心缩放图片纹理的完整图解
android·java·开发语言·kotlin·android studio
啃火龙果的兔子3 天前
android studio运行下载gradle特别慢怎么处理
android·ide·android studio
longforus3 天前
Flutter iOS 真机部署异常经验(Android Studio 提示无法运行,但 Xcode 可正常运行)
flutter·ios·android studio
dazhong20123 天前
Android Studio 安装之历史版本下载问题解决
android·ide·android studio
啃火龙果的兔子3 天前
android studio first run : unable to sccess android sdk add-on list
android·ide·android studio
yuanhello3 天前
【Android】Android的键值对存储方案对比
android·java·android studio
PWRJOY4 天前
Android Studio中安卓模拟器打不开,报错The emulator process for AVD has terminated
android·ide·android studio
小简GoGo5 天前
新手如何搭建配置Android Studio并成功运行React Native项目(使用自带的虚拟机运行)
react native·react.js·android studio
奶糖 肥晨5 天前
无需Android Studio:Windows安装ADB工具及手机调试全流程
windows·adb·android studio
1024小神5 天前
android studio最新版在toolbar工具栏显示back和forward按钮
javascript·html·android studio