首先,效果图。分类似至360检测到的骚扰电话页面:

布局非常easy,上面是一个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;
}
}

==========

源代码下载:http://download.csdn.net/detail/books1958/9005279

版权声明:本文博主原创文章,博客,未经同意不得转载。

Android:简单的弹幕效果达到的更多相关文章

  1. JavaScript实现简单的弹幕效果实例分析

    不知大家有没有感受到,弹幕又是另一出好戏!! 不过我个人还是比较排斥看电视的时候被出来的弹幕打扰.今天我们来写一个简单的弹幕.简单到什么程度呢?看下效果: 由图可以看出,我们的呆毛html结构确实是非 ...

  2. Android Studio 直播弹幕

    我只是搬运:https://blog.csdn.net/HighForehead/article/details/55520199 写的很好很详细,挺有参考价值的 demo直通车:https://do ...

  3. android 弹幕效果demo

    记得之前有位朋友在我的公众号里问过我,像直播的那种弹幕功能该如何实现?如今直播行业确实是非常火爆啊,大大小小的公司都要涉足一下直播的领域,用斗鱼的话来讲,现在就是千播之战.而弹幕则无疑是直播功能当中最 ...

  4. Android弹幕功能实现,模仿斗鱼直播的弹幕效果

    转载出处:http://blog.csdn.net/sinyu890807/article/details/51933728 本文同步发表于我的微信公众号,扫一扫文章底部的二维码或在微信搜索 郭霖 即 ...

  5. Android 自定义View修炼-自定义弹幕效果View

    一.概述 现在有个很流行的效果就是弹幕效果,满屏幕的文字从右到左飘来飘去.看的眼花缭乱,看起来还蛮cool的 现在就是来实现这一的一个效果,大部分的都是从右向左移动漂移,本文的效果中也支持从左向右的漂 ...

  6. Android 弹幕效果开发案例

    概述 现在有个很流行的效果就是弹幕效果,满屏幕的文字从右到左飘来飘去.看的眼花缭乱,看起来还蛮cool的 现在就是来实现这一的一个效果,大部分的都是从右向左移动漂移,本文的效果中也支持从左向右的漂移移 ...

  7. android 的闪屏效果

    android的闪屏效果,就是我们刚开始启动应用的时候弹出的界面或者动画,过2秒之后自动的跳转到主界面. 其实,实现这个效果很简单,使用Handler对象的postDelayed方法就可以实现.在这个 ...

  8. 【转】(转)【Android】Paint的效果研究

    转自:http://wpf814533631.iteye.com/blog/1847661 (转)[Android]Paint的效果研究 博客分类: android   在Paint中有很多的属性可以 ...

  9. Android实现左右滑动效果

    本示例演示在Android中实现图片左右滑动效果.   关于滑动效果,在Android中用得比较多,本示例实现的滑动效果是使用ViewFlipper来实现的,当然也可以使用其它的View来实现.接下来 ...

随机推荐

  1. POJ 3415 Max Sum of Max-K-sub-sequence (线段树+dp思想)

    Max Sum of Max-K-sub-sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ...

  2. HDU 3571 N-dimensional Sphere(高斯消元 数论题)

    这道题算是比较综合的了,要用到扩展欧几里得,乘法二分,高斯消元. 看了题解才做出来orz 基本思路是这样,建一个n*(n-1)的行列式,然后高斯消元. 关键就是在建行列式时会暴long long,所以 ...

  3. ruby中的模块

    什么是模块 模块(module)是Ruby特有的功能之一.类用来表现具有数据与行为(程序)的"东西", 而模块大致来说,则是只有程序部分的集合体.类与模块最大的不同在于: 1.模块 ...

  4. Android OpenGL ES 应用(二) 纹理

    上一篇讲了基础入门 OpenGL (一) ,这一次主要学习OpenGL 纹理基本学习总结 要是做复杂的OpenGL应用程序,一定会用到纹理技术.纹理说白了就是把图片或者视频图像绘制到OpenGL空间中 ...

  5. Java_并发线程_CompletionService

    1.CompletionService源代码分析 CompletionService内部实现还是维护了一个可堵塞的队列,通过代理设计模式.从而操作队列. /** * Creates an Execut ...

  6. 使用SVN clang: error: linker command failed with exit code 1 (use -v to see invocation)

    然后上传到该项目SVN仓库上,例如,下面的错误再次发生再拉到本地编译 ld: library not found for -lxxxxxxxxxxxx clang: error: linker com ...

  7. android圆角View实现及不同版本号这间的兼容

    在做我们自己的APP的时候.为了让APP看起来更加的好看,我们就须要将我们的自己的View做成圆角的,毕竟主流也是将非常多东西做成圆角.和苹果的外观看起来差点儿相同,看起来也还不错. 要将一个View ...

  8. 【网络协议】TCP交互数据流和数据流成块

    前言 建立在TCP协议上的应用层协议有非常多,如FTP.HTTP.Telnet等,这些协议依据数据传输的多少能够分为两类:交互数据类型和成块数据类型. 交互数据类型,如:Telnet,这类协议一般仅仅 ...

  9. zoj3201(树形dp)

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3201 题意:给一棵树, n结点<=1000, 和K < ...

  10. 怎样使用docker不加sudo

    有时候发现docker有的指令必须加sudo才干运行,通过下面三步设置便可不加sudo直接运行docker指令: 1. 假设还没有docker group就加入一个: sudo groupadd do ...