Welcome

首页 / 移动开发 / Android / 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;@Overrideprotected 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() {@Overridepublic void onClick(View v) {if (containerVG.getChildCount() > 0) {return;}existMarginValues.clear();new Thread(new CreateTanmuThread()).start();}});}//每2s自动添加一条弹幕private class CreateTanmuThread implements Runnable {@Overridepublic 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);}@Overridepublic 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() {@Overridepublic void onAnimationStart(Animation animation) {}@Overridepublic void onAnimationEnd(Animation animation) {//移除该组件containerVG.removeView(textView);//移除占位int verticalMargin = (int) textView.getTag();existMarginValues.remove(verticalMargin);}@Overridepublic 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.返回值的曲线表征速度加减趋势@Overridepublic 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 valuecolor = 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程序设计有所帮助。