android实现简单弹幕
整理参考: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
更多推荐
所有评论(0)