轻松又酷炫地实现弹幕效果——手把手教学

本文详细介绍了如何实现弹幕效果,从大体思路到关键步骤,包括实体类、BaseAdapter的创建和DanmuView的实现。通过适配器模式和Handler实现弹幕滚动,同时涉及内存缓存优化,确保流畅运行。文章提供了完整代码示例,适合希望深入理解弹幕功能的开发者。
摘要由CSDN通过智能技术生成

前言

更多代码,请查看我的github:https://github.com/shuaijia/JsPlayer ,喜欢的话就给个star!^_^
也可以关注我的公众号,搜索 安卓干货营

现在越来越多的视频网站或者客户端支持弹幕功能,弹幕功能似乎也成了很多人的爱好,发弹幕,看弹幕成了大家吐槽、搞笑、发表看法的一种方式。

而国内弹幕的鼻祖应该就算A站和B站了。

弹幕(barrage),中文流行词语,原意指用大量或少量火炮提供密集炮击。而弹幕,顾名思义是指子弹多而形成的幕布,大量吐槽评论从屏幕飘过时效果看上去像是飞行射击游戏里的弹幕。

最近一直在写视频播放器,那弹幕怎么能少得了呢!所以把自己开发弹幕功能的思路写出来与大家分享。

依旧还是先上效果图:

这里写图片描述

大体思路

我们的目标是将各式各样的itemView展示到播放器上方,并且使之滚动起来,itemView支持自定义,这样看起来和ListView的功能很相像,但与之不一样的是,弹幕是多行多列,需要计算每个itemView的位置,且一直在滚动

所以,我采用适配器模式,仿ListView的Adapter来实现弹幕功能。
想到这里,很多人就会觉得这不典型的横向瀑布流嘛,用RecyclerView或者flexbox很轻松就实现了。

但我想自己从设计模式、实现原理来考虑、设计,从而也可以更深刻地理解适配器模式和ListView的原理,如果您想使用RecyclerView来实现,可以自己试试。

关键:

  • 使用适配器模式将各式各样的itemView进行适配、处理、展示
  • 使用hadler定时发送消息使itemView滚动
  • itemView最佳位置的计算
  • 滚动区域的设置

接下来就一起来实现:

1、实体类

实体类当然不能少了:

/**
 * Description: 弹幕实体类
 * Created by jia on 2017/9/25.
 * 人之所以能,是相信能
 */
public class DanmuModel {
   

    private int type;

    public int getType() {
        return type;
    }

    public void setType(int type) {
        this.type = type;
    }
}

其中的type是model实体类的类型,因为弹幕的itemView中会有多种类型,对应不同type的实体类。

使用时可以自己定义实体类,继承自DanmuModel ,也可以不继承,只要能区分不同类型就可以:因为自己稍后的adapter中没有像ListView的Adapter一样定义了获取item类型的方法,所以就在getView方法中依据type选择不同的itemView即可


2、BaseAdapter

这里写图片描述

首先Adapter定义为抽象类,且设置泛型M,M就是对应的实体类。

在Adapter中定义三个抽象方法:

  1. getViewTypeArray :获取itemView的类型type组成的数组
  2. getSingleLineHeight :获取单行itemView的高度
  3. getView :获取itemView,功能类似于ListView的Adapter中getView方法
public abstract class DanmuAdapter<M> {
   
    /**
     * 获取类型数组
     *
     * @return
     */
    public abstract int[] getViewTypeArray();

    /**
     * 获取单行弹幕 高度
     *
     * @return
     */
    public abstract int getSingleLineHeight();

    /**
     * 获取itemView
     *
     * @param entry
     * @param convertView
     * @return
     */
    public abstract View getView(M entry, View convertView);
}

这样适配器抽象类就定义好了嘛?不是的!

在显示弹幕的时候会,会创建大量的View对象,如果不做处理,很容易造成内存溢出,所以我们要进行缓存优化

A、首先创建了map集合

// 使用HashMap,以类型和对应view的栈为key-value存储,实现缓存
private HashMap<Integer, Stack<View>> cacheViews;

以view的类型为key,对应的view存入栈中,以栈为value。

B、构造中

public DanmuAdapter() {
    cacheViews = new HashMap<>();
    typeArray = getViewTypeArray();
    for (int i = 0; i < typeArray.length; i++) {
        Stack<View> stack = new Stack<>();
        cacheViews.put(typeArray[i], stack);
    }
}

获取itemView类型数组,循环创建对应type的栈。

C、itemView加入缓存

/**
  * 将弹幕itemView加入缓存(压栈)
  *
  * @param type
  * @param view
  */
synchronized public void addViewToCache(int type, View view) {
    if (cacheViews.containsKe
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值