Android编程实现简易弹幕效果示例【附demo源码下载】

本文实例讲述了Android编程实现简易弹幕效果。分享给大家供大家参考,具体如下:

首先上效果图,类似于360检测到骚扰电话页面:

布局很简单,上面是一个RelativeLayout,下面一个Button.

功能:

(1)弹幕生成后自动从右侧往左侧滚动(TranslateAnimation),弹幕消失后立刻被移除。

(2)弹幕位置随机出现,并且不重复(防止文字重叠)。

(3)字体大小在一定范围内随机改变,字体颜色也可以设置。

(4)自定义先减速,后加速的Interpolator,弹幕加速进入、减速停留、然后加速出去。

1.Activity代码:

/**

* 简易弹幕效果实现

* Created by admin on 15-6-4.

*/

public class MainActivity extends ActionBarActivity {

private MyHandler handler;

//弹幕内容

private TanmuBean tanmuBean;

//放置弹幕内容的父组件

private RelativeLayout containerVG;

//父组件的高度

private int validHeightSpace;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

containerVG = (RelativeLayout) findViewById(R.id.tanmu_container);

tanmuBean = new TanmuBean();

tanmuBean.setItems(new String[]{"测试一下", "弹幕这东西真不好做啊", "总是出现各种问题~~", "也不知道都是为什么?麻烦!", "哪位大神可以帮帮我啊?", "I need your help.",

"测试一下", "弹幕这东西真不好做啊", "总是出现各种问题~~", "也不知道都是为什么?麻烦!", "哪位大神可以帮帮我啊?", "I need your help.",

"测试一下", "弹幕这东西真不好做啊", "总是出现各种问题~~", "也不知道都是为什么?麻烦!", "哪位大神可以帮帮我啊?", "I need your help."});

handler = new MyHandler(this);

//开始弹幕

View startTanmuView = findViewById(R.id.startTanmu);

startTanmuView.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

if (containerVG.getChildCount() > 0) {

return;

}

existMarginValues.clear();

new Thread(new CreateTanmuThread()).start();

}

});

}

//每2s自动添加一条弹幕

private class CreateTanmuThread implements Runnable {

@Override

public void run() {

int N = tanmuBean.getItems().length;

for (int i = 0; i < N; i++) {

handler.obtainMessage(1, i, 0).sendToTarget();

SystemClock.sleep(2000);

}

}

}

//需要在主线城中添加组件

private static class MyHandler extends Handler {

private WeakReference<MainActivity> ref;

MyHandler(MainActivity ac) {

ref = new WeakReference<>(ac);

}

@Override

public void handleMessage(Message msg) {

super.handleMessage(msg);

if (msg.what == 1) {

MainActivity ac = ref.get();

if (ac != null && ac.tanmuBean != null) {

int index = msg.arg1;

String content = ac.tanmuBean.getItems()[index];

float textSize = (float) (ac.tanmuBean.getMinTextSize() * (1 + Math.random() * ac.tanmuBean.getRange()));

int textColor = ac.tanmuBean.getColor();

ac.showTanmu(content, textSize, textColor);

}

}

}

}

private void showTanmu(String content, float textSize, int textColor) {

final TextView textView = new TextView(this);

textView.setTextSize(textSize);

textView.setText(content);

// textView.setSingleLine();

textView.setTextColor(textColor);

int leftMargin = containerVG.getRight() - containerVG.getLeft() - containerVG.getPaddingLeft();

//计算本条弹幕的topMargin(随机值,但是与屏幕中已有的不重复)

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(this, leftMargin, -ScreenUtils.getScreenW(this));

anim.setAnimationListener(new Animation.AnimationListener() {

@Override

public void onAnimationStart(Animation animation) {

}

@Override

public void onAnimationEnd(Animation animation) {

//移除该组件

containerVG.removeView(textView);

//移除占位

int verticalMargin = (int) textView.getTag();

existMarginValues.remove(verticalMargin);

}

@Override

public void onAnimationRepeat(Animation animation) {

}

});

textView.startAnimation(anim);

containerVG.addView(textView);

}

//记录当前仍在显示状态的弹幕的位置(避免重复)

private Set<Integer> existMarginValues = new HashSet<>();

private int linesCount;

private int getRandomTopMargin() {

//计算用于弹幕显示的空间高度

if (validHeightSpace == 0) {

validHeightSpace = containerVG.getBottom() - containerVG.getTop()

- containerVG.getPaddingTop() - containerVG.getPaddingBottom();

}

//计算可用的行数

if (linesCount == 0) {

linesCount = validHeightSpace / ScreenUtils.dp2px(this, tanmuBean.getMinTextSize() * (1 + tanmuBean.getRange()));

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;

}

}

}

}

2.平移动画生成工具:

public class AnimationHelper {

/**

* 创建平移动画

*/

public static Animation createTranslateAnim(Context context, int fromX, int toX) {

TranslateAnimation tlAnim = new TranslateAnimation(fromX, toX, 0, 0);

//自动计算时间

long duration = (long) (Math.abs(toX - fromX) * 1.0f / ScreenUtils.getScreenW(context) * 4000);

tlAnim.setDuration(duration);

tlAnim.setInterpolator(new DecelerateAccelerateInterpolator());

tlAnim.setFillAfter(true);

return tlAnim;

}

}

ScreenUtils是用来获取屏幕宽高、dp与px之间互转的工具类。

3.自定义的Interpolator,其实只有一行代码

public class DecelerateAccelerateInterpolator implements Interpolator {

//input从0~1,返回值也从0~1.返回值的曲线表征速度加减趋势

@Override

public float getInterpolation(float input) {

return (float) (Math.tan((input * 2 - 1) / 4 * Math.PI)) / 2.0f + 0.5f;

}

}

4.TanmuBean是一个实体类

public class TanmuBean {

private String[] items;

private int color;

private int minTextSize;

private float range;

public TanmuBean() {

//init default value

color = Color.parseColor("#eeeeee");

minTextSize = 16;

range = 0.5f;

}

public String[] getItems() {

return items;

}

public void setItems(String[] items) {

this.items = items;

}

public int getColor() {

return color;

}

public void setColor(int color) {

this.color = color;

}

/**

* min textSize, in dp.

*/

public int getMinTextSize() {

return minTextSize;

}

public void setMinTextSize(int minTextSize) {

this.minTextSize = minTextSize;

}

public float getRange() {

return range;

}

public void setRange(float range) {

this.range = range;

}

}

完整实例代码点击此处本站下载。

更多关于Android相关内容感兴趣的读者可查看本站专题:《Android视图View技巧总结》、《Android开发动画技巧汇总》、《Android编程之activity操作技巧总结》、《Android布局layout技巧总结》、《Android开发入门与进阶教程》、《Android资源操作技巧汇总》及《Android控件用法总结》

希望本文所述对大家Android程序设计有所帮助。

以上是 Android编程实现简易弹幕效果示例【附demo源码下载】 的全部内容, 来源链接: utcz.com/z/351171.html

回到顶部