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(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。