先来张镇文图再看一下弹幕效果图:
实现方式同样有很多,最简单的大多数朋友会想到在relativelayout里面动态的添加TextView,虽然思路简单,但一直在那new TextView()感觉很不好,所以今天我的实现方式并非这个,先看一下我的布局文件,以及实现方法:
"http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.ruedy.barrageviewtest.MainActivity">
<com.example.ruedy.barrageviewtest.BarrageView
android:id="@+id/bv"
android:layout_width="match_parent"
android:layout_height="350dp" />
实现方法
bv = ((BarrageView) findViewById(R.id.bv));
bv.addTextitem(content);
今天我们通过自定义控件来实现弹幕View;下面看一下具体思路:
class Textitem {//set get方法未贴出
private String content;//文本内容
private float fx;//x坐标
private float fy;//y坐标
private float perstep;//移动速度
private int textcolor;//字体颜色
}
之所以这样封装,是因为弹幕内容共同点就是,他们是文本,内容不同,x,y坐标不同,向左移动的速度也不同;
这里继承的是view,而不是其他viewgroup,主要是用到了TextPaint(文本画笔)以及Canvas的drawText方法,意思就是我们无需在一个容器布局里面添加布局,而是可以直接在布局View里面把文字在不同的坐标下画出来;下面看一下初始化画笔以及重写的ondraw方法:
private void initpaint() {
paint = new TextPaint(Paint.ANTI_ALIAS_FLAG);//初始化文本画笔
paint.setColor(Color.RED);//文字颜色值,可以不设定
paint.setTextSize(30);//文字大小
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//遍历集合,把每个弹幕画出来
for (Textitem item : items) {
paint.setColor(item.getTextcolor());
canvas.drawText(item.getContent(), item.getFx(), item.getFy(), paint);
}
}
这里的items是Textitem的对象集合;把弹幕内容放到一个集合里面,然后遍历这个集合,把弹幕全部画出来
根据弹幕的属性我们明白,肯定要实现随机的添加弹幕的x,y坐标,颜色,以及移动速度,自然而然的要用到随机数Random,看下主要代码:
public void addTextitem(String content) {//此方法可根据需求自行改动
float x = random.nextFloat() * getWidth() - 30;//随机x
float y = Math.abs(random.nextFloat() * (getHeight() - 50)) + 40;//为了不贴边
float step = random.nextFloat() * 50;
int r = random.nextInt(255);
int g = random.nextInt(255);
int b = random.nextInt(255);
Textitem textitem = new Textitem(content, x, y, step, Color.rgb(r, g, b));
items.add(textitem);
}
代码中的Color.rgb(r, g, b)为获得一个随机颜色。这样我们就实现了动态的添加一条弹幕到集合items中
这个是关键点,如何让他们动起来?当然这里是改变x的坐标,实现向左动,那么意思就是改变textitem的x坐标;让每个弹幕间隔一定时间动一下,那么就是每隔一定时间,从新遍历集合,改变弹幕的x坐标,很容易想到开启一个死循环多线程,每隔一定时间,就遍历弹幕集合,改变每个弹幕的坐标,主要方法如下:
@Override
public void run() {
while (true) {
try {
Thread.sleep(600);
for (Textitem item : items) {
item.setPerstep();
}
postInvalidate();//每隔500毫秒重绘视图
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void setPerstep() {
fx -= perstep;//调用此方法实现x坐标向左移动
}
setPerstep为Textitem的一个方法,用于根据弹幕速度改变x坐标,遍历完调用postInvalidate()方法,在子线程中实现重绘试图,这样就简单实现了弹幕View ,当然这里可以自定义一些共性的属性;
源码已放在git上面,点击查看