弹幕

整理参考:https://github.com/shiweibsw/EasyBarrage

 

主要的控件代码:


/**
 * Created by 漠天
 * 参考源码:https://github.com/shiweibsw/EasyBarrage
 */
public class BarrageView extends RelativeLayout {
    private Set<Integer> existMarginValues = new HashSet<>();
    private int linesCount;

    private int validHeightSpace;
    private int INTERVAL = 1000;//这个间隔时间自己设置;但是小于1000的时候貌似是会丢数据的;其实就是还没来得及展示就过去了

    private Random random = new Random(System.currentTimeMillis());
    private int maxBarrageSize;
    private int minTextSize;
    private int lineHeight;
    private int borderColor;
    private boolean random_color;
    private boolean allow_repeat;
    private final int DEFAULT_BARRAGESIZE = 5;
    private final int DEFAULT_MINTEXTSIZE = 15;
    private final int DEFAULT_LINEHEIGHT = 16;
    private final int DEFAULT_BORDERCOLOR = 0xff000000;
    private final boolean DEFAULT_RANDOMCOLOR = false;
    private final boolean DEFAULT_ALLOWREPEAT = false;

    private int barragesIndex = 0;//当前弹幕的坐标
    private List<Barrage> barrages = new ArrayList<>();//当前存储的弹幕内容列表
    private List<Barrage> cache = new ArrayList<>();//临时存储弹幕内容,也就是展示过的弹幕内容

    public BarrageView(Context context) {
        this(context, null);
    }

    public BarrageView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public BarrageView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray typedArray = context.getTheme().obtainStyledAttributes(attrs, R.styleable.BarrageView, 0, 0);
        try {
            maxBarrageSize = typedArray.getInt(R.styleable.BarrageView_size, DEFAULT_BARRAGESIZE);
            minTextSize = typedArray.getInt(R.styleable.BarrageView_min_text_size, DEFAULT_MINTEXTSIZE);
            lineHeight = typedArray.getDimensionPixelSize(R.styleable.BarrageView_line_height, BarrageTools.dp2px(context, DEFAULT_LINEHEIGHT));
            borderColor = typedArray.getColor(R.styleable.BarrageView_border_color, DEFAULT_BORDERCOLOR);
            random_color = typedArray.getBoolean(R.styleable.BarrageView_random_color, DEFAULT_RANDOMCOLOR);
            allow_repeat = typedArray.getBoolean(R.styleable.BarrageView_allow_repeat, DEFAULT_ALLOWREPEAT);
        } finally {
            typedArray.recycle();
        }
    }

    //Handler来处理UI
    public Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            checkBarrage();
            sendEmptyMessageDelayed(0, INTERVAL);
        }
    };

    /**
     *  添加弹幕内容到当前集合,用来循环展示弹幕内容
     * @param list  List<Barrage> 弹幕内容列表
     */
    public void setBarrages(List<Barrage> list) {
        if (!list.isEmpty()) {
            barrages.clear();
            barrages.addAll(list);
            mHandler.sendEmptyMessageDelayed(0, INTERVAL);
        }
    }

    /**
     * 添加弹幕内容到当前集合,用来循环展示弹幕内容
     * @param tb    弹幕内容
     */
    public void addBarrage(Barrage tb) {
        barrages.add(barragesIndex,tb);
        if (!mHandler.hasMessages(0)) {
            mHandler.sendEmptyMessageDelayed(0, INTERVAL);
        }
    }

    /**
     * 确定当前弹幕的内容是否允许展示
     */
    public void checkBarrage() {
        Barrage barrage = barrages.get(barragesIndex);
        if (barragesIndex + 1 < barrages.size()) {
            barragesIndex++;
        } else {
            barragesIndex = 0;
        }
        if (allow_repeat) {
            if (cache.contains(barrage))
                return;
            cache.add(barrage);
        }
        showBarrage(barrage);
    }

    /**
     * 展示弹幕的内容,textView设置内容 (可以在这里自定义view)
     * @param tb    需要展示的内容Bean
     */
    private void showBarrage(final Barrage tb) {
        if (linesCount != 0 && getChildCount() >= linesCount)
            return;
        if (getChildCount() > maxBarrageSize)
            return;
        final TextView textView = tb.isShowBorder() ? new BorderTextView(getContext(), borderColor) : new TextView(getContext());
        textView.setMaxLines(1);
        textView.setMaxEms(30);
        textView.setEllipsize(TextUtils.TruncateAt.END);
        textView.setTextSize(minTextSize);
        textView.setText(tb.getContent());
        textView.setTextColor(random_color ? Color.rgb(random.nextInt(256), random.nextInt(256), random.nextInt(256)) : getResources().getColor(tb.getColor()));
        int leftMargin = getRight() - getLeft() - getPaddingLeft();
        int verticalMargin = getRandomTopMargin();
        textView.setTag(verticalMargin);
        LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        params.addRule(RelativeLayout.ALIGN_PARENT_TOP);
        params.topMargin = verticalMargin;
        textView.setLayoutParams(params);
        Animation anim = AnimationHelper.createTranslateAnim(getContext(), leftMargin, -getScreenWidth(getContext()));
        anim.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {
            }

            @Override
            public void onAnimationEnd(Animation animation) {
                if (allow_repeat)
                    cache.remove(tb);
                removeView(textView);
                int verticalMargin = (int) textView.getTag();
                existMarginValues.remove(verticalMargin);
            }

            @Override
            public void onAnimationRepeat(Animation animation) {
            }
        });
        textView.startAnimation(anim);
        addView(textView);
    }

    /**
     * 获取弹幕的TextView的margin位置
     * @return  Int
     */
    private int getRandomTopMargin() {
        if (validHeightSpace == 0) {
            validHeightSpace = getBottom() - getTop() - getPaddingTop() - getPaddingBottom();
        }
        if (linesCount == 0) {
            linesCount = validHeightSpace / lineHeight;
            if (linesCount == 0) {
                throw new RuntimeException("Not enough space to show text.");
            }
        }
        while (true) {
            int randomIndex = (int) (Math.random() * linesCount);
            int marginValue = randomIndex * (validHeightSpace / linesCount);
            if (!existMarginValues.contains(marginValue)) {
                existMarginValues.add(marginValue);
                return marginValue;
            }
        }
    }

    /**
     * 销毁释放数据资源
     */
    public void destroy() {
        if (mHandler.hasMessages(0))
            mHandler.removeMessages(0);
        barrages.clear();
        cache.clear();
    }

}
 

具体使用 参考demo:https://download.csdn.net/download/u010326875/11061169

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐