弹慕实现的两种方式

来源:互联网 发布:厦门关键词优化 编辑:程序博客网 时间: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秒移动}

0 0