弹慕实现的两种方式
来源:互联网 发布:厦门关键词优化 编辑:程序博客网 时间:2024/05/22 09:40
第一种,属性动画方式:
/** * 弹幕动画 */private int width;private int duration = 5000;List<ObjectAnimator> obj = new ArrayList();class MyHandler extends Handler { @Override public void handleMessage(Message msg) { super.handleMessage(msg); if(msg.what == 2){ handlers.removeMessages(2); final View vv = getTView(); int wr = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); int hr = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); vv.measure(wr, hr); int widthr =vv.getMeasuredWidth(); width = DeviceInfoUtils.getScreenWidth(mContext); final int top = setRandomTopMargin(); if(top==-1){ handlers.sendEmptyMessageDelayed(2, 3000); return; } FrameLayout.LayoutParams txtlp = new FrameLayout.LayoutParams(widthr, ViewGroup.LayoutParams.WRAP_CONTENT); txtlp.leftMargin = DeviceInfoUtils.getScreenWidth(mContext); txtlp.topMargin =top; vv.setTag(top+""); int time = duration*widthr/width; containerVG.addView(vv,txtlp); final ObjectAnimator anim = ObjectAnimator.ofFloat(vv, "translationX", 0,-(width+widthr)); anim.setDuration(duration+time); anim.setInterpolator(new LinearInterpolator()); anim.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { containerVG.removeView(vv); obj.remove(anim); existMarginValues.remove(vv.getTag()); } }); anim.start(); obj.add(anim); handlers.sendEmptyMessageDelayed(2, 3000); } }}
//随机位置弹出
public int setRandomTopMargin() { int posY = -1; if (linesCount == 0) { linesCount = bvHeight / txtheight; } if(linesCount==0)return 0; while (true) { int randomIndex = (int) (Math.random() * linesCount); int marginValue = randomIndex * txtheight; if(existMarginValues.size()==linesCount){ break; } if (!existMarginValues.contains(marginValue+"")) { posY = marginValue; existMarginValues.add(marginValue+""); break; } } return posY;}//动态获取textview
public View getTView() { TextView vv = new TextView(mContext); vv.setText(tanmuBean.getDamulist().get(random.nextInt(N)).getTitle()); vv.setGravity(Gravity.CENTER); vv.setTextColor(white); vv.setSingleLine(); vv.setTextSize(18); vv.setBackgroundResource(R.drawable.xueche_text_black); return vv;}
二,第二种,自定义view(来自网络)
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.LinearInterpolator;
import android.view.animation.TranslateAnimation;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.jxedt.R;
import com.jxedt.bean.TanmuBean;
import com.jxedt.common.Tool;
import com.wuba.android.lib.commons.DeviceInfoUtils;
import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.ExecutorService;
/**
* Created by
* 会导致严重耗电,发热
*/
public class BarrageView {
private Random random = new Random();
Context mContext;
RelativeLayout containerVG;
int dp_textSize;
public BarrageView(RelativeLayout containerVG,Context mContext,int danmuHeight){
this.containerVG = containerVG;
this.mContext = mContext;
this.danmuHeight = danmuHeight;
tanmuBean = new TanmuBean();
tanmuBean.setItems(new String[]{"测试一下", "弹幕这东", "总是出现各种问题~~", "什么?麻烦!", "哪位大?", "I need your help.",
"测试一下", "弹幕这东西真不好做啊", "总是出现各种问题~~", "也不知道都是为什么?麻烦!", "哪位大神可以帮帮我啊?", "I need your help.",
"测试一下", "弹幕这东西真不好做啊", "总是出", "麻烦!", "哪位大神可以帮帮我啊?", "I need your help."});
N = tanmuBean.getItems().length;
handler = new MyHandler(this);
if (containerVG.getChildCount() > 0) {
return;
}
handler.sendEmptyMessageDelayed(1, 500);
}
public void showTanmuView(String content, int dp_textSize) {
this.dp_textSize = dp_textSize;
final TextView textView = new TextView(mContext);
textView.setTextSize(dp_textSize);
textView.setBackgroundResource(R.drawable.xueche_text_black);
textView.setText(content);
textView.setSingleLine();
textView.setTextColor(Color.WHITE);
int leftMargin = containerVG.getRight() - containerVG.getLeft() - containerVG.getPaddingLeft();
int verticalMargin = getRandomTopMargin();
textView.setTag(verticalMargin);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.ALIGN_PARENT_TOP);
params.topMargin = verticalMargin;
textView.setLayoutParams(params);
Animation anim = createTranslateAnim(mContext, leftMargin, -DeviceInfoUtils.getScreenWidth(mContext));
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);
handler.sendEmptyMessageDelayed(1, 2600);//首次进入延迟2秒移动
}
public 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 / DeviceInfoUtils.getScreenWidth(context) * 4000);
tlAnim.setDuration(duration);
tlAnim.setInterpolator(new LinearInterpolator());
tlAnim.setFillAfter(true);
return tlAnim;
}
//记录当前仍在显示状态的弹幕的位置(避免重复)
private Set 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 / danmuHeight;
if (linesCount == 0) {
return 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;
}
}
}
//父组件的高度
private int validHeightSpace;
private MyHandler handler;
//弹幕内容
private TanmuBean tanmuBean;
//需要在主线城中添加组件
class MyHandler extends Handler {
private WeakReference ref;
MyHandler(BarrageView ac) {
ref = new WeakReference<>(ac);
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what == 1 && !isPause) {
BarrageView ac = (BarrageView) ref.get();
if (ac != null && ac.tanmuBean != null) {
int index = random.nextInt(N);
String content = ac.tanmuBean.getItems()[index];
int textSize = ac.tanmuBean.getMinTextSize();
ac.showTanmuView(content, textSize);
}
}
}
}
int danmuHeight=0;
int N =0;
boolean isPause = false;
public void setPause(boolean pause) {
isPause = pause;
if(!isPause){
handler.sendEmptyMessageDelayed(1, 500);
}
}
}
//初始化
private void initBarrageView(){for(int i=0;i<3;i++){TextView vv = new TextView(mContext);vv.setVisibility(View.GONE);vv.setId(i);containerVG.addView(vv);}handlers = new MyHandler();handlers.sendEmptyMessageDelayed(2, 0);//首次进入延迟2秒移动}
- 弹慕实现的两种方式
- CEikRichTextEditor 实现的两种方式
- 局部刷新的两种实现方式
- Java实现多线程的两种方式
- 两种实现二维数组的方式
- session的两种实现方式
- toolBar的两种实现方式
- Spring定时器的两种实现方式
- Spring定时器的两种实现方式
- Spring定时器的两种实现方式
- WDS的两种实现方式
- Session的两种实现方式
- spring定时器的两种实现方式
- 双队列的两种实现方式
- Spring定时器的两种实现方式
- Spring定时器的两种实现方式
- Spring定时器的两种实现方式
- Spring定时器的两种实现方式
- Truck History poj1789 最小生成树
- Java线程(十三)----阻塞队列BlockingQueue
- 关于layer.photos图片点击无法弹出的问题分析
- 解决IE上不了网,其他浏览器却可以的情况
- ARM汇编和C混合编程-笔记
- 弹慕实现的两种方式
- android 把View转成bitmap
- 关于p标签不对齐问题
- ubuntu16.04 vtune2017安装与启动
- LeetCode第二关:Add Two Numbers --> Difficulty: Medium
- request请求
- JSP中include的方法总结
- JS数组的属性以及方法
- android开发context介绍