写直播时组长要求要带头像的弹幕,于是写了一个demo,在弹幕的基础上添加了一个布局,直接上效果吧

先看下xml里面的弹幕布局

<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="wrap_content"android:layout_height="50dp"android:orientation="horizontal"android:background="#0ff"><com.see.tmlayout.CircleImageViewandroid:id="@+id/barrage_item_img"android:layout_width="50dp"android:layout_height="match_parent"android:src="@drawable/qq"/><TextViewandroid:id="@+id/barrage_item_tv"android:layout_width="wrap_content"android:layout_height="match_parent"android:layout_marginLeft="10dp"android:layout_marginRight="10dp"android:text="测试弹幕"android:gravity="center"android:textColor="#fff"/>
</LinearLayout>

CircleImageView是圆形图片,网上一搜就有。

这是Tm布局没什么好说的
public class Barrage implements Serializable {private String barrageInfo;private String barrageUrl;public Barrage(String barrageInfo, String barrageUrl) {this.barrageInfo = barrageInfo;this.barrageUrl = barrageUrl;}public String getBarrageInfo() {return barrageInfo;}public void setBarrageInfo(String barrageInfo) {this.barrageInfo = barrageInfo;}public String getBarrageUrl() {return barrageUrl;}public void setBarrageUrl(String barrageUrl) {this.barrageUrl = barrageUrl;}
}

接下来就是Tm的自定义

public class BarrageView extends FrameLayout {private static ArrayList<Barrage> mData = new ArrayList<>(); //数据private int nowIndex = 0; //mData的下标private Bitmap nowBitmap; //当前图片private int width;                //控件宽private int height;               //控件高private float scale;              //像素密度private FrameLayout frameLayout;private FrameLayout.LayoutParams tvParams;static boolean IS_START = false;    //判断是否开始long allTime; //视频总时长long startTime; //开始时间Handler handler = new Handler() {@Overridepublic void handleMessage(Message msg) {Barrage barrage = (Barrage) msg.getData().getSerializable("barrage");final LinearLayout layout = (LinearLayout) LayoutInflater.from(getContext()).inflate(R.layout.barrage_itme, null);layout.setLayoutParams(tvParams);//随机获得Y值layout.setY(getRandomY());layout.setX(width + layout.getWidth());//设置文字TextView textView = (TextView) layout.findViewById(R.id.barrage_item_tv);textView.setText(barrage.getBarrageInfo());//设置图片CircleImageView imageView = (CircleImageView) layout.findViewById(R.id.barrage_item_img);if (nowBitmap != null) {imageView.setImageBitmap(nowBitmap);}frameLayout.addView(layout);final ObjectAnimator anim = ObjectAnimator.ofFloat(layout, "translationX", -width);anim.setDuration(10000);//释放资源anim.addListener(new Animator.AnimatorListener() {@Overridepublic void onAnimationStart(Animator animation) {}@Overridepublic void onAnimationEnd(Animator animation) {anim.cancel();layout.clearAnimation();frameLayout.removeView(layout);}@Overridepublic void onAnimationCancel(Animator animation) {}@Overridepublic void onAnimationRepeat(Animator animation) {}});anim.start();}};/*** 使用httprulconnection通过发送网络请求path获得bitmap** @param path* @return*/public static Bitmap getBitmapFromUrl(String path) {try {//获得urlURL url = new URL(path);//打开 httpRulConnection 获得实例HttpURLConnection conn = (HttpURLConnection) url.openConnection();//设置超时时间conn.setConnectTimeout(5000);//设置Getconn.setRequestMethod("GET");//连接成功if (conn.getResponseCode() == 200) {//获得输入流InputStream inputStream = conn.getInputStream();//得到bitmapBitmap bitmap = BitmapFactory.decodeStream(inputStream);if (bitmap == null) {}//返回return bitmap;}//错误信息处理} catch (Exception e) { //打印错误信息e.printStackTrace();}return null;}int lastY;//上一次出现的Y值/*** 获得随机的Y轴的值** @return*/private float getRandomY() {int tempY;int rY;int result = 0;// height * 2 / 4 - 25//首先随机选择一条道路int nowY = (int) (Math.random() * 3);switch (nowY) {case 0:nowY = avoidTheSameY(nowY, lastY);//第一条tempY = height / 4 - 25;rY = (int) (Math.random() * height / 4);if (rY >= height / 8) {result = tempY + rY;} else {result = tempY - rY + 50;}lastY = nowY;break;case 1:nowY = avoidTheSameY(nowY, lastY);//第二条tempY = height / 2 - 25;rY = (int) (Math.random() * height / 4);if (rY >= height / 8) {result = tempY + rY;} else {result = tempY - rY;}lastY = nowY;break;case 2:nowY = avoidTheSameY(nowY, lastY);//第三条tempY = height * 3 / 4 - 25;rY = (int) (Math.random() * height / 4);if (rY >= height / 8) {result = tempY + rY - 50;} else {result = tempY - rY;}lastY = nowY;break;}return result;}/*** 避免Y重合的方法** @param lastY* @return*/private int avoidTheSameY(int nowY, int lastY) {if (nowY == lastY) {nowY++;}if (nowY == 4) {nowY = 0;}return nowY;}public BarrageView(Context context, AttributeSet attrs) {super(context, attrs);}@Overrideprotected void onLayout(boolean changed, int left, int top, int right, int bottom) {super.onLayout(changed, left, top, right, bottom);width = getWidth(); //宽度height = getHeight();   //高度init();}private void init() {setTime(600000);    //设置初始时长,改完记得删startTime = System.currentTimeMillis();scale = this.getResources().getDisplayMetrics().density;//获得自身实例frameLayout = (FrameLayout) findViewById(R.id.barrageView);tvParams = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, 50);if (IS_START) {//开始动画线程startBarrageView();IS_START = false;}}public void startBarrageView() {//开启线程发送弹幕new Thread() {@Overridepublic void run() {while ((System.currentTimeMillis() - startTime < allTime)&& (nowIndex <= mData.size() - 1)) {try {nowBitmap = getBitmapFromUrl(mData.get(nowIndex).getBarrageUrl());Message message = new Message();Bundle bundle = new Bundle();bundle.putSerializable("barrage", mData.get(nowIndex));nowIndex++;message.setData(bundle);handler.sendMessage(message);Thread.sleep((long) (Math.random() * 3000) + 1000);} catch (InterruptedException e) {e.printStackTrace();}}return;}}.start();}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);}//设置数据public void setSentenceList(ArrayList<Barrage> data) {mData = data;IS_START = true;}//获得视频总时长public void setTime(long time) {allTime = time;}
}

之后在声明View传入数据就可以了

下面是Activity里的XML和代码应用
<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context="com.see.tmlayout.MainActivity"><com.see.tmlayout.BarrageViewandroid:id="@+id/barrageView"android:layout_width="match_parent"android:layout_height="400dp"/></RelativeLayout>
public class MainActivity extends AppCompatActivity {private BarrageView mBarrageView;private ArrayList<Barrage> data;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initView();}private void initView() {data = new ArrayList<>();for (int i = 0; i < 50; i++) {data.add(new Barrage("测试弹幕" + i, "http://pic.818today.com/imgsy/image/2016/0215/6359114592207963687677523.jpg"));}mBarrageView = (BarrageView) findViewById(R.id.barrageView);mBarrageView.setSentenceList(data);}
}

解析的数据添加到data集合里就大功告成了!

Android之弹幕(一)带头像相关推荐

  1. 【博客美化】评论带头像,且支持旋转

    [博客美化]评论带头像,且支持旋转 好久没有更新关于博客园页面美化的文章了,这一次主要是写一下关于评论带头像,且支持旋转的内容,希望各位小伙伴能够喜欢!!! 1.效果图 2.添加CSS代码 设置-页面 ...

  2. Android自定义文件路径箭头,Android自定义ViewGroup实现带箭头的圆角矩形菜单

    本文和大家一起做一个带箭头的圆角矩形菜单,大概长下面这个样子: 要求顶上的箭头要对准菜单锚点,菜单项按压反色,菜单背景色和按压色可配置. 最简单的做法就是让UX给个三角形的图片往上一贴,但是转念一想这 ...

  3. Android利用温度传感器实现带动画效果的电子温度计

    概述 Android利用温度传感器实现带动画效果的电子温度计. 详细 一.准备工作 需要准备一部带有温度传感器的安卓手机,或者使用有温度传感器的模拟器. 二.程序实现 1.需要截图程序结构 2.实现思 ...

  4. 【博客美化】09.评论带头像,且支持旋转

    博客园美化相关文章目录: [博客美化]01.推荐和反对炫酷样式 [博客美化]02.公告栏显示个性化时间 [博客美化]03.分享按钮 [博客美化]04.自定义地址栏logo [博客美化]05.添加Git ...

  5. CSS实现的带头像的彩色垂直菜单源码

    大家好,今天给大家介绍一款,用CSS实现的带头像的彩色垂直菜单源码(图1).送给大家哦,获取方式在本文末尾. 图1 鼠标悬停在相应区域,就会出现头像 图2 带切换动画(图3) 图4 部分代码: * { ...

  6. android 横向头像栏,Android实现个人资料页面头像背景模糊显示包(状态栏)

    最近要实现这样一个效果,然后拿出来与大家分享一下主要的几段代码,希望大家能够用到,与人方便自己方便嘛! 首先: 要实现的是浮动状态栏效果,通过在Activity的onCreate方法中调用这个方法,然 ...

  7. android安装自动打开网页,Android调用系统自带浏览器打开网页的实现方法

    Android调用系统自带浏览器打开网页的实现方法 在Android中可以调用自带的浏览器,或者指定一个浏览器来打开一个链接.只需要传入一个uri,可以是链接地址. 启动android默认浏览器 在A ...

  8. java 打开url连接访问不了,android 应用Java自带的HttpURLConnection 连接网络 读取返回数据...

    android 使用Java自带的HttpURLConnection 连接网络 读取返回数据 @Override protected void onCreate(Bundle savedInstanc ...

  9. Tp5生成带头像二维码海报(带文字描述,居中调整)

    Tp5生成带头像二维码海报(带文字描述,居中调整) 三张海报中随机生成一张展现 /*** 获取随机海报* Author: yanjie <823986855@qq.com>* Date: ...

最新文章

  1. Asp.Net读写XML简单方法
  2. Annotation 注解
  3. android如何适配平板,适用于平板电脑、大屏设备和可折叠设备的自适应布局
  4. 微软官方工具_时隔20年再出发!微软官方推出最强Windows工具集
  5. (C语言)字符串大小写无关查找替换
  6. java exception信息_可能通过Java Exceptions暴露敏感信息?
  7. paper reading:[第一代GCN] Spectral Networks and Deep Locally Connected Networks on Graphs
  8. Hitfilm Express下载
  9. Qt +ffmpeg(vp8) 记录视频每一帧并生成webm文件格式
  10. 机器视觉的9大快速开发库简单介绍
  11. iPhone通讯录导入及备份方法
  12. 混合波束成形|重叠子阵结构下的HBF探讨
  13. selenium切换窗口句柄
  14. ristretto255 point压缩和解压缩算法(2)——extended坐标系下
  15. 卡斯商学院研究表示AR可提升购物体验
  16. movie计算机英语作文,关于电影的英语作文movie
  17. 黑马程序员:Socket编程之(UDP vs TCP)
  18. 高德地图搜索,点击地图获取经纬度
  19. Git统计代码行数;Java实现统计代码行数,忽略空行、注释行
  20. Django计算机毕业设计JAVA高校田径运动会管理(程序+LW)Python

热门文章

  1. 暴力突破 Java 并发 - synchronize 解析
  2. i3处理器_酷睿i3-9350K竟然是隐藏的绝世高手 Intel偷偷加了buff
  3. 文件如何同步备份至U盘或移动硬盘
  4. java 内存管理 —— 《Hotspot内存管理白皮书》
  5. 自动字幕对轴软件Autosub 用户手册(2.1)
  6. 【天光学术】艺术论文:传统凤鸟图形在博物馆文创产品设计中的运用
  7. 聊聊前端测试那点事儿
  8. 社交媒体分析在未来业务中将发挥着至关重要的作用
  9. ​九州一轨通过注册:计划募资6.57亿 京投公司为大股东
  10. 如何更改idea注释中的斜体字