Android:简易弹幕效果实现

来源:互联网 发布:win7组策略优化 编辑:程序博客网 时间:2024/05/22 17:20

首先上效果图,类似于360检测到骚扰电话页面:


布局很简单,上面是一个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 






0 0
原创粉丝点击