经常看足球比赛,感觉乐视还是挺不错的,但是就是弹幕很让人烦,但是在android中这也是一种效果,这个实现就是使用了平移动画而已,现在把代码贴下:
package com.example.bardmeo; import android.animation.Animator; import android.animation.ObjectAnimator; import android.content.Context; import android.graphics.Color; import android.graphics.Rect; import android.os.Handler; import android.os.Message; import android.text.TextPaint; import android.util.AttributeSet; import android.widget.RelativeLayout; import android.widget.TextView; import java.util.Random; /** * Created by lixueyong on 16/2/19. */ public class MarqueeView extends RelativeLayout { private static final String TAG ="MarqueeView" ; private Context mContext; private BarrageHandler mHandler = new BarrageHandler(); private Random random = new Random(System.currentTimeMillis()); private int maxSpeed = 5000; private int minSpeed = 1000;//移动的速度其实是和动画时间定的 private int textSize ; private int totalHeight = 0; private int lineHeight = 0;//每一行弹幕的高度 private int totalLine = 0;//弹幕的行数 private String[] contents = {"邓紫棋","Angelababy","张柏芝","王祖贤","关之琳","蔡卓妍","赵雅芝","利智","周海媚","梅艳芳","张曼玉","翁美玲","钟丽缇","李嘉欣","陈慧琳"}; private int textCount;//弹幕的个数 public MarqueeView(Context context) { this(context, null); } public MarqueeView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public MarqueeView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); mContext = context; init(); } private void init() { textSize = dip2px(getContext(),15); textCount = contents.length; mHandler.sendEmptyMessageDelayed(0, 1000);//延迟多少秒 } @Override public void onWindowFocusChanged(boolean hasWindowFocus) { super.onWindowFocusChanged(hasWindowFocus); totalHeight = getMeasuredHeight();//view的高度 lineHeight = getLineHeight();//每一行的高度 totalLine = totalHeight / lineHeight; } private void generateItem() { TextViewItem item = new TextViewItem(); String content = contents[(int) (Math.random() * textCount)]; item.textView = new TextView(mContext); item.textView.setText(content); item.textView.setTextSize(textSize); item.textView.setTextColor(Color.rgb(random.nextInt(256), random.nextInt(256), random.nextInt(256))); item.width = (int) getTextWidth(item, content); item.moveSpeed = (int) (minSpeed + (maxSpeed - minSpeed) * Math.random()); item.verticalPos = random.nextInt(totalLine) * lineHeight; showBarrageItem(item); } private void showBarrageItem(final TextViewItem item) { int leftMargin = this.getRight() - this.getLeft() - this.getPaddingLeft(); LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); params.addRule(RelativeLayout.ALIGN_PARENT_TOP); params.topMargin = item.verticalPos; this.addView(item.textView, params);//添加到相对布局中 ObjectAnimator animation = ObjectAnimator.ofFloat(item.textView,"translationX",leftMargin,0-item.width); animation.setDuration(item.moveSpeed); animation.start(); animation.addListener(new Animator.AnimatorListener(){ @Override public void onAnimationStart(Animator animation) { } @Override public void onAnimationEnd(Animator animation) { //在动画完毕后记得移除textview不然时间长了会挂的 item.textView.clearAnimation(); MarqueeView.this.removeView(item.textView); } @Override public void onAnimationCancel(Animator animation) { item.textView.clearAnimation(); MarqueeView.this.removeView(item.textView); } @Override public void onAnimationRepeat(Animator animation) { } }); } /** * 计算TextView中字符串的长度 * @param text 要计算的字符串 * @return TextView中字符串的长度 */ public float getTextWidth(TextViewItem item, String text) { Rect bounds = new Rect(); TextPaint paint; paint = item.textView.getPaint(); paint.getTextBounds(text, 0, text.length(), bounds); return bounds.width(); } /** * 获得每一行弹幕的最大高度 * @return */ private int getLineHeight() { TextViewItem item = new TextViewItem(); String tx = contents[0]; item.textView = new TextView(mContext); item.textView.setText(tx); item.textView.setTextSize(textSize); Rect bounds = new Rect(); TextPaint paint; paint = item.textView.getPaint(); paint.getTextBounds(tx, 0, tx.length(), bounds); return bounds.height(); } class BarrageHandler extends Handler { @Override public void handleMessage(Message msg) { super.handleMessage(msg); generateItem(); int duration = (int) (1000 * Math.random()); this.sendEmptyMessageDelayed(0, duration); } } /** * 当退出Activity的时候记得把不再发送hanlder消息 */ public void removeHandler(){ mHandler.removeCallbacksAndMessages(null); } /** * 根据手机的分辨率从 dp 的单位 转成为 px(像素) */ public static int dip2px(Context context, float dpValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (dpValue * scale + 0.5f); } class TextViewItem{ public TextView textView;// public int textColor;//文字的颜色 public String content;//现在的内容 public int textSize;//文字的大小 public int moveSpeed;//移动速度 public int verticalPos;//垂直方向显示的位置 用于在textview之间的位置上 public int width ;//textview的宽度 } }
package com.example.bardmeo; import android.app.Activity; import android.os.Bundle; /** * Created by lixueyong on 16/2/19. */ public class MainActivity extends Activity { private MarqueeView containerView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_barrage); containerView = (MarqueeView) findViewById(R.id.containerView); } @Override protected void onDestroy() { super.onDestroy(); containerView.removeHandler(); } }布局文件:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <com.example.bardmeo.MarqueeView android:id="@+id/containerView" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/white" /> </RelativeLayout>效果: