android仿乐视网弹幕的实现

经常看足球比赛,感觉乐视还是挺不错的,但是就是弹幕很让人烦,但是在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>
效果:



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值