欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

很棒的Android彈幕效果實(shí)例

 更新時(shí)間:2016年11月17日 10:15:23   作者:蔡睿智  
這篇文章主要為大家詳細(xì)介紹了很棒的Android彈幕效果實(shí)例,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

很多項(xiàng)目需要用到彈幕效果,尤其是在播放視頻的時(shí)候需要一起顯示別人發(fā)的彈幕,也包括自己的發(fā)的。

今天就試著寫了一下這個(gè)效果。

思路就是將從右往左的動(dòng)畫效果,字體內(nèi)容,字體大小,彈幕平移速度等屬性一起與TextView封裝成BarrageItem,并將控制效果與BarrageItem綁定在BarrageView進(jìn)行顯示。思路還是比較簡(jiǎn)單的。這里沒有考慮到帶有表情的彈幕,我會(huì)持續(xù)更新的。

 先看效果:

 項(xiàng)目目錄結(jié)構(gòu):

 

 接下來(lái)定義Barrageitem.class : 這個(gè)類就將TextView與從右往左的動(dòng)畫效果,字體內(nèi)容,字體大小,彈幕平移速度等屬性綁定。

public class BarrageItem { 
 
 public TextView textView; 
 
 public int textColor; 
 
 public String text; 
 
 public int textSize; 
 
 // 移動(dòng)速度 
 public int moveSpeed; 
 
 // 垂直方向顯示的位置 
 public int verticalPos; 
 
 // 字體顯示占據(jù)的寬度 
 public int textMeasuredWidth; 
 
} 

然后定義BarrageView,由于彈幕的字體顏色大小和移動(dòng)速度都是隨機(jī)的,需要定義最大最小值來(lái)限定它們的范圍,然后通過(guò)產(chǎn)生隨機(jī)數(shù)來(lái)設(shè)置它們?cè)谶@個(gè)范圍內(nèi)的值。另外還需要定義彈幕的文本內(nèi)容,這里是直接寫死的一些固定值。

BarrageView.class:

public class BarrageView extends RelativeLayout { 
 
 private Context mContext; 
 
 private BarrageHandler mHandler = new BarrageHandler(); 
 
 private Random random = new Random(System.currentTimeMillis()); 
 
 // 兩個(gè)彈幕的最小間隔時(shí)間 
 private static final long BARRAGE_GAP_MIN_DURATION = 1000; 
 
 // 兩個(gè)彈幕的最大間隔時(shí)間 
 private static final long BARRAGE_GAP_MAX_DURATION = 2000; 
 
 // 速度,ms 
 private int maxSpeed = 12000; 
 
 // 速度,ms 
 private int minSpeed = 8000; 
 
 // 文字最大值 
 private int maxSize = 50; 
 
 // 文字最小值 
 private int minSize = 10; 
 
 private int totalHeight = 0; 
 
 private int lineHeight = 0;// 每一行彈幕的高度 
 
 private int totalLine = 0;// 彈幕的行數(shù) 
 
 private String[] itemText = { "他們都說(shuō)蔡睿智很帥,但他總覺得自己很丑", 
   "他們都說(shuō)蔡睿智是男神,但他只覺得自己是男生", "蔡睿智不是男神,蔡睿智是男生", "蔡睿智貌似是gay", "蔡睿智是彎的", 
   "蔡睿智是彎的,還好現(xiàn)在掰回來(lái)了", "他承受了他這個(gè)年紀(jì)不該有的機(jī)智與帥氣,他好累", 
   "我恨自己的顏值,我覺得自己的才華才是吸引別人的地方", "他為什么對(duì)妹子不感興趣呢?為什么?", "他為什么不想談戀愛","他不會(huì)去愛別人,同時(shí)也不希望別人去愛他,他已經(jīng)習(xí)慣一個(gè)人了", 
   "他的心里是否住著一個(gè)蒼老的小孩", "他的世界一直就是他和他的影子,直到遇到她", "她引導(dǎo)他走出了自己的世界,改變他的很多看法", 
   "他漸漸的發(fā)現(xiàn)自己已經(jīng)離不開他,他選擇不再去壓抑自己", "因?yàn)樗呀?jīng)不是那個(gè)無(wú)能為力的年紀(jì)","她經(jīng)常說(shuō)他 高冷,現(xiàn)在越來(lái)越覺得他恨悶騷","開始他一直與她保持朋友距離,但他發(fā)現(xiàn)自己根本作不到"}; 
 private int textCount; 
 
 public BarrageView(Context context, AttributeSet attrs, int defStyleAttr) { 
  super(context, attrs, defStyleAttr); 
  mContext = context; 
  _init(); 
 } 
 
 public BarrageView(Context context, AttributeSet attrs) { 
  this(context, null, 0); 
 
 } 
 
 public BarrageView(Context context) { 
  this(context, null); 
 
 } 
 
 private void _init() { 
  textCount = itemText.length; 
  int duration = (int) ((BARRAGE_GAP_MAX_DURATION - BARRAGE_GAP_MIN_DURATION) * Math 
    .random()); 
  mHandler.sendEmptyMessageDelayed(0, duration); 
 } 
 
 @Override 
 public void onWindowFocusChanged(boolean hasWindowFocus) { 
  super.onWindowFocusChanged(hasWindowFocus); 
  totalHeight = getMeasuredHeight(); 
  lineHeight = getLineHeight(); 
  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; 
  } 
  item.verticalPos = random.nextInt(totalLine) * lineHeight; 
  showBarrageItem(item); 
 } 
 
 private void showBarrageItem(final BarrageItem item) { 
  int leftMargin = this.getRight() - this.getLeft() 
    - this.getPaddingLeft(); 
  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 arg0) { 
 
   } 
 
   @Override 
   public void onAnimationRepeat(Animation arg0) { 
     
   } 
 
   @Override 
   public void onAnimationEnd(Animation arg0) { 
    item.textView.clearAnimation(); 
    BarrageView.this.removeView(item.textView); 
   } 
  }); 
  item.textView.startAnimation(anim); 
 } 
 
 private TranslateAnimation generateTranslateAnim(BarrageItem item, 
   int leftMargin) { 
  TranslateAnimation anim = new TranslateAnimation(leftMargin, 
    -item.textMeasuredWidth, 0, 0); 
  anim.setDuration(item.moveSpeed); 
  anim.setInterpolator(new AccelerateDecelerateInterpolator()); 
  anim.setFillAfter(true); 
  return anim; 
 } 
 
 /** 
  * 計(jì)算TextView中字符串的長(zhǎng)度 
  * 
  * @param item 
  * @param text 
  *   要計(jì)算的字符串 
  * @param Size 
  *   字體大小 
  * @return TextView中字符串的長(zhǎng)度 
  */ 
 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(); 
 } 
 
 /** 
  * 獲得每一行彈幕的最大高度 
  */ 
 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(); 
   // 每個(gè)彈幕產(chǎn)生的時(shí)間隨機(jī) 
   int duration = (int) ((BARRAGE_GAP_MAX_DURATION - BARRAGE_GAP_MIN_DURATION) * Math 
     .random()); 
   this.sendEmptyMessageDelayed(0, duration); 
  } 
 } 
 
} 

如果彈幕顯示的垂直位置是隨機(jī)的,就會(huì)出現(xiàn)垂直方向上彈幕重疊的情況,所以需要根據(jù)高度對(duì)垂直方向按照彈幕高度的最大值等分,然后讓彈幕在這些指定的垂直位置隨機(jī)分布。這個(gè)值在onWindowFocusChanged里計(jì)算,因?yàn)樵谶@個(gè)方法中通過(guò)View的getMeasuredHeight()得到的高度不為空。

 MainActivity.class:

<span style="font-size:18px;">public class MainActivity extends Activity { 
 
 @Override 
 protected void onCreate(Bundle savedInstanceState) { 
  super.onCreate(savedInstanceState); 
  setContentView(R.layout.activity_main); 
 } 
}</span> 

以上就是彈幕的源碼,其實(shí)我覺得這里少了自己發(fā)送彈幕的功能,我會(huì)在以后的更新上去的,共勉。

相關(guān)文章

最新評(píng)論