Android自定义View实现弹幕效果
在很多视频直播中都有弹幕功能,而安卓上没有简单好用的弹幕控件,本文介绍一个自定义弹幕view的demo。
效果图:
思路:
1、自定义Textitem类表示弹幕的信息
2、自定义view继承view,使用ArrayList保存每条Textitem
3、随机生成坐标点绘制每条TextItem,不断变换Text的横坐标实现弹幕的滚动
首先创建弹幕类,弹幕包括坐标,颜色,滚动速度,以及文字内容:
publicclassTextitem{
privateStringcontent;
privatefloatfx;
privatefloatfy;
privatefloatperstep;
privateinttextcolor;
publicTextitem(Stringcontent,floatfx,floatfy,floatperstep,inttextcolor){
this.content=content;
this.fx=fx;
this.fy=fy;
this.perstep=perstep;
this.textcolor=textcolor;
}
publicStringgetContent(){
returncontent;
}
publicvoidsetContent(Stringcontent){
this.content=content;
}
publicintgetTextcolor(){
returntextcolor;
}
publicvoidsetTextcolor(inttextcolor){
this.textcolor=textcolor;
}
publicfloatgetFx(){
returnfx;
}
publicvoidsetFx(floatfx){
this.fx=fx;
}
publicfloatgetFy(){
returnfy;
}
publicvoidsetFy(floatfy){
this.fy=fy;
}
publicfloatgetPerstep(){
returnperstep;
}
publicvoidsetPerstep(){
fx-=perstep;
}
}
接下来自定义View,弹幕横坐标不断变换,需要实现定时刷新界面,重新绘制text。所以实现了Runable接口,在构造方法中开启线程,不断循环,每600毫秒刷新界面:
publicclassbarrageviewextendsViewimplementsRunnable{
privateListitems=newArrayList<>();
Randomrandom=newRandom();
privatePaintpaint;
publicbarrageview(Contextcontext){
super(context);
initpaint();
newThread(this).start();
}
publicbarrageview(Contextcontext,AttributeSetattrs){
super(context,attrs);
initpaint();
newThread(this).start();
}
publicbarrageview(Contextcontext,AttributeSetattrs,intdefStyleAttr){
super(context,attrs,defStyleAttr);
initpaint();
newThread(this).start();
}
publicvoidaddTextitem(Stringcontent){
floatx=random.nextFloat()*getWidth();
floaty=Math.abs(random.nextFloat()*(getHeight()-50))+40;
floatstep=random.nextFloat()*50;
intr=random.nextInt(255);
intg=random.nextInt(255);
intb=random.nextInt(255);
Textitemitem=newTextitem(content,x,y,step,Color.rgb(r,g,b));
items.add(item);
}
publicvoidinitpaint(){
paint=newTextPaint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.RED);
paint.setTextSize(30);
}
@Override
publicvoiddraw(Canvascanvas){
super.draw(canvas);
for(Textitemitem:items){
paint.setColor(item.getTextcolor());
canvas.drawText(item.getContent(),item.getFx(),item.getFy(),paint);
}
}
@Override
publicvoidrun(){
while(true){
try{
Thread.sleep(600);
for(Textitemitem:items){
item.setPerstep();
}
postInvalidate();
}catch(InterruptedExceptione){
e.printStackTrace();
}
}
}
}
弹幕VIew就是不断从ArrayList中获取弹幕进行绘制,由于在其他线程进行刷新,所以使用postInvalidate进行重绘。
由于只是实现demo,很多问题没有考虑,存在问题:
弹幕离开屏幕后没有进行清除,使得ArrayList不断扩大,可以进行一个判断,若Textitem的绘制区域不在屏幕内则删掉此item
弹幕若没有交互需求,可以使用Surfaceview进行绘制,SurfaceView可以在子线程更新UI,多缓存机制也可以避免画面跳动
另外注意下自定义View的构造函数的调用时机:
publicView(Contextcontext)是在java代码创建视图直接通过new方法创建的时候被调用,
publicView(Contextcontext,Attributesetattrs)是在xml创建但是没有指定style的时候被调用
publicView(ContextContext,AttributeSetattrs,intdefStyle)给View提供一个基本的style,没有对View设置属性就使用style中的属性
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。