Android编程实现简易弹幕效果示例【附demo源码下载】

#技术教程 发布时间: 2026-01-18

本文实例讲述了Android编程实现简易弹幕效果。分享给大家供大家参考,具体如下:

首先上效果图,类似于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;
  }
}

完整实例代码点击此处本站下载

更多关于Android相关内容感兴趣的读者可查看本站专题:《Android视图View技巧总结》、《Android开发动画技巧汇总》、《Android编程之activity操作技巧总结》、《Android布局layout技巧总结》、《Android开发入门与进阶教程》、《Android资源操作技巧汇总》及《Android控件用法总结》

希望本文所述对大家Android程序设计有所帮助。




上一篇 : JAVA实现遍历文件夹下的所有文件(递归调用和非递归调用)

下一篇 : Java遍历Map键、值和获取Map大小的方法示例

推荐阅读

电话:400 76543 55
邮箱:915688610@qq.com
品牌营销
客服微信
搜索营销
公众号
©  丽景创新 版权所有 赣ICP备2024032158号 
宜昌市隼壹珍商贸有限公司 宜昌市隼壹珍商贸有限公司 宜昌市隼壹珍商贸有限公司 宜昌市隼壹珍商贸有限公司 宜昌市隼壹珍商贸有限公司 宜昌市隼壹珍商贸有限公司 宜昌市隼壹珍商贸有限公司 宜昌市隼壹珍商贸有限公司 宜昌市隼壹珍商贸有限公司 宜昌市隼壹珍商贸有限公司 内江振祥营销策划有限公司 内江振祥营销策划有限公司 内江振祥营销策划有限公司 内江振祥营销策划有限公司 内江振祥营销策划有限公司 内江振祥营销策划有限公司 内江振祥营销策划有限公司 内江振祥营销策划有限公司 内江振祥营销策划有限公司 内江振祥营销策划有限公司 内江振祥营销策划有限公司 内江振祥营销策划有限公司 内江振祥营销策划有限公司 内江振祥营销策划有限公司 内江振祥营销策划有限公司 内江振祥营销策划有限公司 恩施州毯滚百货有限公司 恩施州毯滚百货有限公司 襄阳市蜂欢商贸有限公司 襄阳市蜂欢商贸有限公司 恩施州换冯百货有限公司 恩施州换冯百货有限公司 恩施州健提百货有限公司 恩施州健提百货有限公司 西安益零商贸有限公司 西安益零商贸有限公司 南奥教育 南奥教育 南奥教育 南奥教育 南昌市南奥教育咨询有限公司 南昌市南奥教育咨询有限公司 南昌市南奥教育咨询有限公司 南昌市南奥教育咨询有限公司 南昌市南奥教育咨询有限公司 南昌市南奥教育咨询有限公司 南昌市南奥教育咨询有限公司 南昌市南奥教育咨询有限公司 南奥教育网 南奥教育网 南奥教育网 南奥教育网 南奥学习网 南奥学习网 南奥学习网 南奥学习网 南奥教育 南奥教育 南奥留学记 南奥留学记 南奥教育 南奥教育 南昌市南奥教育咨询有限公司 南昌市南奥教育咨询有限公司 南昌市南奥教育咨询有限公司 南昌市南奥教育咨询有限公司 南昌壹佳企网络通信有限公司 南昌壹佳企网络通信有限公司 南昌壹佳企网络通信有限公司 南昌壹佳企网络通信有限公司 南昌壹佳企网络通信有限公司 南昌壹佳企网络通信有限公司 南昌壹佳企网络通信有限公司 南昌壹佳企网络通信有限公司 南昌壹佳企网络通信有限公司 南昌壹佳企网络通信有限公司 南昌壹佳企网络通信有限公司 南昌壹佳企网络通信有限公司 南昌壹佳企网络通信有限公司 南昌壹佳企网络通信有限公司 南昌壹佳企网络通信有限公司 南昌壹佳企网络通信有限公司 南昌壹佳企网络通信有限公司 南昌壹佳企网络通信有限公司 南昌壹佳企网络通信有限公司 南昌壹佳企网络通信有限公司 南昌壹佳企网络通信有限公司 南昌壹佳企网络通信有限公司 广照天下广告 广照天下广告 广照天下广告策划 广照天下广告策划 广照天下 广照天下 广照天下 广照天下 广照天下 广照天下 广照天下广告策划 广照天下广告策划 广照天下广告策划 广照天下广告策划 南昌市广照天下广告策划有限公司 南昌市广照天下广告策划有限公司 南昌市广照天下广告策划有限公司 南昌市广照天下广告策划有限公司 宿州市腾雀网络科技有限公司 宿州市腾雀网络科技有限公司 宿州市腾雀网络科技有限公司 宿州市腾雀网络科技有限公司 宿州市腾雀网络科技有限公司 宿州市腾雀网络科技有限公司 宿州市腾雀网络科技有限公司 宿州市腾雀网络科技有限公司 宿州市腾雀网络科技有限公司 宿州市腾雀网络科技有限公司 宿州市腾雀网络科技有限公司 宿州市腾雀网络科技有限公司 宿州市腾雀网络科技有限公司 宿州市腾雀网络科技有限公司 宿州市腾雀网络科技有限公司 宿州市腾雀网络科技有限公司 宿州市腾雀网络科技有限公司 宿州市腾雀网络科技有限公司 九江市云仁商务咨询有限公司 九江市云仁商务咨询有限公司 九江市云仁商务咨询有限公司 九江市云仁商务咨询有限公司 九江市云仁商务咨询有限公司 九江市云仁商务咨询有限公司 九江市云仁商务咨询有限公司 九江市云仁商务咨询有限公司 九江市云仁商务咨询有限公司 九江市云仁商务咨询有限公司
品牌营销
专业SEO优化
添加左侧专家微信
获取产品详细报价方案