合肥网站建设托管,黑色大气金融投资企业网站模板,一个域名可以做中英文两个网站吗,网站建设需要编程吗在bibibi推出弹幕功能#xff0c;我也爱上了边看视频边看吐槽了#xff0c;现在让我们也来实现这一个功能吧。 首先我们要整理一下思绪我们大概需要实现哪个细节板块呢。 我们最直观的看来#xff0c;弹幕就是总右往左出现到消失。我们要实现这个动画#xff0c;弹幕的大小… 在bibibi推出弹幕功能我也爱上了边看视频边看吐槽了现在让我们也来实现这一个功能吧。 首先我们要整理一下思绪我们大概需要实现哪个细节板块呢。 我们最直观的看来弹幕就是总右往左出现到消失。我们要实现这个动画弹幕的大小颜色出现方式加速弹幕的不重叠这个我想了好久还没有实现有实现方法可以联系下我。 我们先来了解一下等会程序里面会用到的相关知识点等会看代码会更轻松一点。 [java] view plain copy /*getHeight跟getMeasureHeight的区别 * 实际上在当屏幕可以包裹内容的时候他们的值相等只有当view超出屏幕后才能看出他们的区别 * getMeasuredHeight()是实际View的大小与屏幕无关而getHeight的大小此时则是屏幕的大小。 * 当超出屏幕后 getMeasuredHeight() 等于 getHeight()加上屏幕之外没有显示的大小 * * */ [java] view plain copy /Activity生命周期中onStart, onResume, onCreate都不是真正visible的时间点真正的visible时间点是onWindowFocusChanged()函数被执行时。 //当你屏幕的焦点发生变化时候想要操作什么也完全可以在这个方法里面执行 // Interpolator 被用来修饰动画效果定义动画的变化率可以使存在的动画效果accelerated(加速)decelerated(减速),repeated(重复),bounced(弹跳)等。 /* * AccelerateDecelerateInterpolator 在动画开始与结束的地方速率改变比较慢在中间的时候加速 AccelerateInterpolator 在动画开始的地方速率改变比较慢然后开始加速 AnticipateInterpolator 开始的时候向后然后向前甩 AnticipateOvershootInterpolator 开始的时候向后然后向前甩一定值后返回最后的值 BounceInterpolator 动画结束的时候弹起 CycleInterpolator 动画循环播放特定的次数速率改变沿着正弦曲线 DecelerateInterpolator 在动画开始的地方快然后慢 LinearInterpolator 以常量速率改变 OvershootInterpolator 向前甩一定值后再回到原来位置 [java] view plain copy * fillBefore是指动画结束时画面停留在此动画的第一帧; fillAfter是指动画结束是画面停留在此动画的最后一帧。 Java代码设置如下 /*****动画结束时停留在最后一帧********* setFillAfter(true); setFillBefore(false); /*****动画结束时停留在第一帧********* setFillAfter(false); setFillBefore(true); * 下面我们就来看一下弹幕实现的效果。 弹幕会出现重叠这个问题还未解决 让我们开始看代码结构吧。 我们字体颜色的xml都写在了colors.xml中了BarrageItem里面存放着我们的一些变量而核心代码都在View中 BraagetItem.Java [java] view plain copy package com.example.bibibibibibibibi; import android.widget.TextView; import android.widget.TextView; /** * Created by lixueyong on 16/2/19. */ public class BarrageItem { public TextView textView;//文本框 public int textColor;//文本颜色 public String text;//文本对象 public int textSize;//文本的大小 public int moveSpeed;//移动速度 public int verticalPos;//垂直方向显示的位置 public int textMeasuredWidth;//字体显示占据的宽度 } 在BarrageItem里面处理了弹幕的速度大小颜色动画等事件 在这个文件中 我注释的内容是我对弹幕重叠的操作代码但是除了问题有兴趣的可以看一下 [java] view plain copy package com.example.bibibibibibibibi; 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.view.animation.AccelerateDecelerateInterpolator; import android.view.animation.Animation; import android.view.animation.TranslateAnimation; import android.widget.RelativeLayout; import android.widget.TextView; import java.util.HashSet; import java.util.Random; import java.util.Set; import com.example.bibibibibibibibi.R.integer; /** * Created by nzx on 16/5/30. */ public class BarrageView extends RelativeLayout { private Context mContext; private BarrageHandler mHandler new BarrageHandler(); private Random random new Random(System.currentTimeMillis());//System.currentTimeMillis()产生一个当前的毫秒 private static final long BARRAGE_GAP_MIN_DURATION 1000;//两个弹幕的最小间隔时间 private static final long BARRAGE_GAP_MAX_DURATION 2000;//两个弹幕的最大间隔时间 private int maxSpeed 10000;//速度ms private int minSpeed 5000;//速度ms private int maxSize 30;//文字大小dp private int minSize 15;//文字大小dp private int totalHeight 0;//整个的高度 private int lineHeight 0;//每一行弹幕的高度 private int totalLine 0;//弹幕的行数 private String[] itemText {大头死变态, 老圩人最屌了, 唉这把中单是火男难玩了, 大头是傻子, 世界上最长的路是套路, 英雄联盟最强的是补丁, 我不会轻易的go die, 嘿嘿, 加班加班}; private int textCount;//文本的组数 //private RelativeLayout Rparams; // private ListBarrageItem itemList new ArrayListBarrageItem(); //实现RelativeLayout的重写的构造方法。 /* * //content 上下文 //AttributeSet 属性集 //defStyleAttr 预设样式属性集 //defStyleRes 预设样式资源属性集 * * */ public BarrageView(Context context) { this(context, null); } public BarrageView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public BarrageView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); mContext context; init(); } private void init() { textCount itemText.length; int duration (int) ((BARRAGE_GAP_MAX_DURATION - BARRAGE_GAP_MIN_DURATION) * Math.random()); mHandler.sendEmptyMessageDelayed(0, duration); } Override //Activity生命周期中onStart, onResume, onCreate都不是真正visible的时间点真正的visible时间点是onWindowFocusChanged()函数被执行时。 //当你屏幕的焦点发生变化时候想要操作什么也完全可以在这个方法里面执行。 public void onWindowFocusChanged(boolean hasWindowFocus) { super.onWindowFocusChanged(hasWindowFocus); totalHeight getMeasuredHeight(); /*getHeight跟getMeasureHeight的区别 * 实际上在当屏幕可以包裹内容的时候他们的值相等只有当view超出屏幕后才能看出他们的区别 * getMeasuredHeight()是实际View的大小与屏幕无关而getHeight的大小此时则是屏幕的大小。 * 当超出屏幕后 getMeasuredHeight() 等于 getHeight()加上屏幕之外没有显示的大小 * * */ //获取每一行弹幕的最大高度 lineHeight getLineHeight(); //我们整个弹幕的高度view/每一行的最大弹幕高度 totalLine totalHeight / lineHeight; } private void generateItem() { BarrageItem item new BarrageItem(); //把我们的每行弹幕的行数顺序跟弹幕进行一个随机 String tx itemText[(int) (Math.random() * textCount)]; //随机弹幕大小 int sz (int) (minSize (maxSize - minSize) * Math.random()); item.textView new TextView(mContext); item.textView.setText(tx); item.textView.setTextSize(sz); item.textView.setTextColor(Color.rgb(random.nextInt(256), random.nextInt(256), random.nextInt(256))); //这里我们需要传入三个参数 文本对象文字行数跟大小 item.textMeasuredWidth(int) getTextWidth(item, tx, sz); //这是设置弹幕移动速度实现有快有慢的感觉 item.moveSpeed (int) (minSpeed (maxSpeed - minSpeed) * Math.random()); //这里为了实现一个弹幕循环播放的项目在我们实际中看情况而定 if (totalLine 0) { totalHeight getMeasuredHeight(); lineHeight getLineHeight(); totalLine totalHeight / lineHeight; } //弹幕在y轴上出现的位置 item.verticalPos random.nextInt(totalLine) * lineHeight; // itemList.add(item); showBarrageItem(item); } private void showBarrageItem(final BarrageItem item) { //paddingLeft是设置布局里面的内容左边的距离这样我们这就可以让这个弹幕的textview完全消失 int leftMargin this.getRight() - this.getLeft() - this.getPaddingLeft(); //这里我们通过动态的方式去设置一些我们布局的属性。 // int verticalMargin getRandomTopMargin(); // item.textView.setTag(verticalMargin); 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); Animation anim generateTranslateAnim(item, leftMargin); anim.setAnimationListener(new Animation.AnimationListener() { Override public void onAnimationStart(Animation animation) { } Override //当我们动画结束的时候清除该条弹幕 public void onAnimationEnd(Animation animation) { item.textView.clearAnimation(); BarrageView.this.removeView(item.textView); } Override //动画被取消的时候出发 public void onAnimationRepeat(Animation animation) { } }); item.textView.startAnimation(anim); } // private TranslateAnimation generateTranslateAnim(BarrageItem item, int leftMargin) { //这里我们有四个参数动画开始的x点结束点开始y轴点结束的y点 TranslateAnimation anim new TranslateAnimation(leftMargin, -item.textMeasuredWidth, 0, 0); //我们设置动画的持续时间弹幕移动多久我们就持续多久动画 anim.setDuration(item.moveSpeed); // Interpolator 被用来修饰动画效果定义动画的变化率可以使存在的动画效果accelerated(加速)decelerated(减速),repeated(重复),bounced(弹跳)等。 /* * AccelerateDecelerateInterpolator 在动画开始与结束的地方速率改变比较慢在中间的时候加速 AccelerateInterpolator 在动画开始的地方速率改变比较慢然后开始加速 AnticipateInterpolator 开始的时候向后然后向前甩 AnticipateOvershootInterpolator 开始的时候向后然后向前甩一定值后返回最后的值 BounceInterpolator 动画结束的时候弹起 CycleInterpolator 动画循环播放特定的次数速率改变沿着正弦曲线 DecelerateInterpolator 在动画开始的地方快然后慢 LinearInterpolator 以常量速率改变 OvershootInterpolator 向前甩一定值后再回到原来位置 * */ anim.setInterpolator(new AccelerateDecelerateInterpolator()); /* * fillBefore是指动画结束时画面停留在此动画的第一帧; fillAfter是指动画结束是画面停留在此动画的最后一帧。 Java代码设置如下 /*****动画结束时停留在最后一帧********* setFillAfter(true); setFillBefore(false); /*****动画结束时停留在第一帧********* setFillAfter(false); setFillBefore(true); * * */ anim.setFillAfter(true); return anim; } /** * 计算TextView中字符串的长度 * * param text 要计算的字符串 * param Size 字体大小 * return TextView中字符串的长度 */ //因为我们的弹幕包裹在一个矩形中 public float getTextWidth(BarrageItem item, String text, float Size) { Rect bounds new Rect(); TextPaint paint; paint item.textView.getPaint(); //这里参数是获取文本对象开始的长度结束的长度我们绘制好的矩形框 paint.getTextBounds(text, 0, text.length(), bounds); return bounds.width(); } /** * 获得每一行弹幕的最大高度 * * return */ private int getLineHeight() { BarrageItem item new BarrageItem(); String tx itemText[0]; item.textView new TextView(mContext); item.textView.setText(tx); item.textView.setTextSize(maxSize); 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) ((BARRAGE_GAP_MAX_DURATION - BARRAGE_GAP_MIN_DURATION) * Math.random()); //多个消息可以使用同一个handler, 通过what不同区分不同的消息来源, 从而获取消息内容 this.sendEmptyMessageDelayed(0, duration); } } //记录一下当前在显示弹幕的高度避免弹幕出现重叠 private Setinteger existMarginValues new HashSet(); private int linesCount; // private int getRandomTopMargin() // { // //计算弹幕的空间高度 // if(totalLine0) // { // totalLineRparams.getBottom()-Rparams.getTop()-Rparams.getPaddingTop() // -Rparams.getPaddingBottom(); // if (totalHeight0) { // totalHeight getMeasuredHeight(); // lineHeight getLineHeight(); // totalLine totalHeight / lineHeight; // } // //检查重叠 // while (true) { // int randomIndex (int) (Math.random() * linesCount); // int marginValue (int) (randomIndex * (totalLine / linesCount)); // // if (!existMarginValues.contains(marginValue)) { // existMarginValues.add(marginValue); // return marginValue; // } // } // // // } } BarrageActivity.java 在这个类里面我们可以去进行一些事件但是我这里没有去处理大家按自己的需求来。 [java] view plain copy package com.example.bibibibibibibibi; import android.app.Activity; import android.os.Bundle; /** * Created by lixueyong on 16/2/19. */ public class BarrageActivity extends Activity { Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_barrage); } } 还有一些关于颜色的xml 大家可以通过demo去看下了这样我们就实现了类似于bibibi弹幕的功能是不是很简单ps哪里简单了手动蔑视。 等我把弹幕重叠的bug解决我在博客上也会更新的。 demo下载地址弹幕demo 今后我会更新更多有趣好玩的博客的。 转自http://blog.csdn.net/ningzhouxu/article/details/51537855