自定義彈幕控制元件
效果圖如下:
MyBarrageView.java
package com.example.example.view;
import java.lang.ref.SoftReference;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Random;
import java.util.concurrent.ArrayBlockingQueue;
import android.animation.Animator;
import android.animation.Animator.AnimatorListener;
import android.animation.ObjectAnimator;
import android.animation.TimeInterpolator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Color;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.LinearInterpolator;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
/**
* 自定義彈幕控制元件
* @author 1
*
*/
public class MyBarrageView extends LinearLayout {
/**
* 每行有多少個彈幕item
*/
private static final int ROW_ITEM_COUNT = 2;
/**
* 是否停止彈幕動畫
*/
private boolean stop = false;
/**
* 存放所有用到的動畫
*/
private HashSet<ObjectAnimator> animators = new HashSet<ObjectAnimator>();
private HashSet<ObjectAnimator> pausedAnimators = new HashSet<ObjectAnimator>();
public MyBarrageView(Context context) {
super(context);
init();
}
public MyBarrageView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public MyBarrageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
setOrientation(LinearLayout.VERTICAL);
}
/**
* 停止彈幕滑動
*/
public void stop(){
stop = true;
if(!animators.isEmpty()){
Iterator<ObjectAnimator> iterator = animators.iterator();
while (iterator.hasNext()) {
ObjectAnimator anim = iterator.next();
if(anim.isRunning()){
anim.cancel();
pausedAnimators.add(anim);
}
}
}
}
/**
* 在主執行緒將彈幕移動起來
*/
Handler handler = new Handler(){
public void handleMessage(android.os.Message msg) {
ObjectAnimator animator = (ObjectAnimator) msg.obj;
animator.start();
};
};
/**
* 開啟彈幕移動
*/
public void start(){
stop = false;
if(!pausedAnimators.isEmpty()){
new Thread(){
public void run() {
Iterator<ObjectAnimator> iterator = pausedAnimators.iterator();
while (iterator.hasNext()) {
Message msg = handler.obtainMessage();
msg.obj = iterator.next();
msg.sendToTarget();
try {
//使動畫啟動時間分散不要太集中
sleep(30);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
pausedAnimators.clear();
};
}.start();
}
}
/**
* 增加彈幕
* @param txt
*/
public void add(String txt){
if(isFull()){
addViewItem(txt);
}else {
addGroupItem(txt);
}
}
/**
* 檢查行Viewgroup是不是已加滿
* @return
*/
private boolean isFull() {
if(getChildCount() < 1){
return false;
}
View lastViewGroup = getChildAt(getChildCount()-1);
int lastBottom = lastViewGroup.getTop()+lastViewGroup.getMeasuredHeight();
boolean b1 = lastBottom >= getMeasuredHeight();
boolean b2 = lastBottom + lastViewGroup.getMeasuredHeight() - getMeasuredHeight() >= lastViewGroup.getHeight()/3;
return b1 || b2;
}
/**
* 根據指定的字元生成Textview
* @param txt
* @return
*/
private TextView initTextview(String txt){
TextView textView = new TextView(getContext());
textView.setBackgroundColor(0xffffff);
textView.setSingleLine(true);
textView.setTextColor(Color.RED);
textView.setGravity(Gravity.CENTER);
//textView.setBackgroundColor(Color.YELLOW);
textView.setText("---------------text "+txt+"------------");
android.view.ViewGroup.LayoutParams layoutParams = new LayoutParams(android.view.ViewGroup.LayoutParams.WRAP_CONTENT, android.view.ViewGroup.LayoutParams.WRAP_CONTENT);
textView.setLayoutParams(layoutParams);
return textView;
}
/**
* 根據指定的字元,增加相應彈幕
* @param txt
*/
private void addViewItem(String txt) {
int rowIndex = new Random().nextInt(getChildCount());
addItemView2Viewgroup(rowIndex,txt);
}
/**
* 根據指定的字元,增加相應彈幕,並新增新的彈幕行
* @param txt
*/
private void addGroupItem(String txt) {
RelativeLayout layout = new RelativeLayout(getContext());
ArrayBlockingQueue<View> subViews = new ArrayBlockingQueue<View>(ROW_ITEM_COUNT);
layout.setTag(subViews);
addView(layout);
int rowIndex = getChildCount() - 1;
addItemView2Viewgroup(rowIndex,txt);
}
/**
* 把指定的view加到指定的行viewGroup上
* @param rowIndex
* @param txt
*/
private void addItemView2Viewgroup(final int rowIndex, final String txt) {
new Thread(){
@Override
public void run() {
TextView textView = null;
Holder holder;
int width = getResources().getDisplayMetrics().widthPixels;
ObjectAnimator animator = null ;
final RelativeLayout group = (RelativeLayout) getChildAt(rowIndex);
ArrayBlockingQueue<View> queue = (ArrayBlockingQueue<View>) group.getTag();
if(group.getChildCount() + queue.size() >= ROW_ITEM_COUNT){
try {
textView = (TextView) queue.take();
group.post(new SetTextRunnable(txt, textView));
Holder holder2 = (Holder) textView.getTag();
animator = holder2.animator.get();
animator.setFloatValues(width,0-width);
} catch (InterruptedException e) {
e.printStackTrace();
}
}else {
holder = new Holder();
holder.rowIndex = rowIndex;
holder.startX = width;
holder.endX = 0 - width;
textView = initTextview(txt);
textView.setTextColor(getColor());
textView.setTag(holder);
textView.setOnClickListener(new MyClickListener());
animator = ObjectAnimator.ofFloat(textView, "translationX", width,0-width);
animator.addListener(new MyAnimatorListener(textView));
animator.setInterpolator(new AccelerateInterpolator());
holder.animator = new SoftReference<ObjectAnimator>(animator);
animators.add(animator);
group.post(new AddViewRunnable(group, textView));
}
int random = new Random().nextInt(2500);
int duration = 5000 + random;
Log.d("duration", " random duration = "+duration);
animator.setDuration(duration);
animator.setInterpolator(getInterpolator());
if(!stop){
group.post(new StartAnimatorRunnable(animator));
}else {
pausedAnimators.add(animator);
}
}
}.start();
}
/**
* 隨機獲取顏色值
* @return
*/
protected int getColor() {
int[] colors = new int[]{Color.BLACK,Color.BLUE, Color.CYAN,Color.RED,Color.GREEN,Color.WHITE,Color.YELLOW};
Random random = new Random();
return colors[random.nextInt(colors.length)];
}
/**
* 隨機獲取彈幕動畫加速器
* @return
*/
private TimeInterpolator getInterpolator() {
Random random = new Random();
int id = random.nextInt(4);
System.out.println("------id = "+id);
switch (id) {
case 0:
return new AccelerateDecelerateInterpolator();
case 1:
return new AccelerateInterpolator();
case 2:
return new DecelerateInterpolator();
case 3:
return new LinearInterpolator();
/*case 4:
return new BounceInterpolator();
case 5:
return new CycleInterpolator(3);
case 6:
return new AnticipateInterpolator();
case 7:
return new AnticipateOvershootInterpolator();
case 8:
return new OvershootInterpolator();*/
default:
break;
}
return new LinearInterpolator();
}
/**
* 用於向指定容器裡新增指定的view
* @author 1
*/
class AddViewRunnable implements Runnable{
private ViewGroup group;
private View view;
public AddViewRunnable(ViewGroup group,View view) {
super();
this.group = group;
this.view = view;
}
@Override
public void run() {
group.addView(view);
}
}
/**
* 啟動相應動畫
* @author 1
*
*/
class StartAnimatorRunnable implements Runnable{
private ObjectAnimator animator;
public StartAnimatorRunnable(ObjectAnimator animator) {
super();
this.animator = animator;
}
@Override
public void run() {
if(!stop){
animator.start();
}
}
}
/**
* 為指定的TextView設定指定的文字
* @author 1
*
*/
class SetTextRunnable implements Runnable{
private String txt;
private TextView textView;
public SetTextRunnable(String txt, TextView textView) {
super();
this.txt = txt;
this.textView = textView;
}
@Override
public void run() {
textView.setText(txt);
textView.setTextColor(getColor());
}
}
/**
* 幫助類
* @author 1
*
*/
class Holder{
/**
* view所處的行號
*/
public int rowIndex;
/**
* view所在的列號
*/
public int columnIndex;
/**
* 動畫持續時間
*/
public int duation;
/**
* 動畫開始座標
*/
public int startX;
/**
* 動畫結束座標
*/
public float endX;
/**
* view所繫結的動畫
*/
public SoftReference<ObjectAnimator> animator;
}
class MyClickListener implements OnClickListener{
@Override
public void onClick(View v) {
TextView textView = (TextView) v;
Toast.makeText(getContext(), textView.getText(), 0).show();
}
}
/**
* 動畫監聽器
* @author 1
*
*/
class MyAnimatorListener implements AnimatorListener{
private SoftReference<View> objectView;
public MyAnimatorListener(View view){
this.objectView = new SoftReference<View>(view);
}
@Override
public void onAnimationStart(Animator animation) {}
@Override
public void onAnimationEnd(Animator animation) {
if(stop) {
return;
}
final View view = objectView.get();
Holder holder = (Holder) view.getTag();
Float f = (Float) ((ValueAnimator)animation).getAnimatedValue();
//((ObjectAnimator)animation).setFloatValues(f,holder.endX);
ViewGroup group = (ViewGroup)getChildAt(holder.rowIndex);
final ArrayBlockingQueue<View> queue = (ArrayBlockingQueue<View>) group.getTag();
new Thread() {
public void run() {
try {
queue.put(view);
} catch (InterruptedException e) {
e.printStackTrace();
}
};
}.start();
System.out.println("--------onAnimationEnd--------");
}
@Override
public void onAnimationCancel(Animator animation) {
Float f = (Float) ((ValueAnimator)animation).getAnimatedValue();
System.out.println("ssss f="+f);
((ObjectAnimator)animation).setFloatValues(f,0-getContext().getResources().getDisplayMetrics().widthPixels);
System.out.println("--------onAnimationCancel---------");
}
@Override
public void onAnimationRepeat(Animator animation) {}
}
}
import android.animation.Animator;
import android.animation.Animator.AnimatorListener;
import android.animation.ObjectAnimator;
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.animation.TranslateAnimation;
import android.widget.LinearLayout;
import android.widget.RelativeLayout.LayoutParams;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class BarrageActivity extends Activity {
private MyBarrageView ll;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_barrage);
ll = (MyBarrageView) findViewById(R.id.ll);
}
int i = 1;
public void addView(View v){
ll.add("彈幕"+ i++);
}
public void stop(View v){
ll.stop();
}
public void start(View v){
ll.start();
}
}
activity_barrage.xml<LinearLayout xmlns: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"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/hello_world" />
<com.example.example.view.MyBarrageView
android:layout_width="match_parent"
android:layout_height="300dp"
android:background="#33333333"
android:id="@+id/ll">
</com.example.example.view.MyBarrageView>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="-=彈幕=-"
android:onClick="addView"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="stop"
android:onClick="stop"/>
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="start"
android:onClick="start"/>
</LinearLayout>
</LinearLayout>
=========================================================================================================
最近對於自定義彈幕控制元件做了一些修訂,作了一個增強版本,主要新增了控制是否可以迴圈滾動、item換成了抽象類降低耦合
程式碼如下:
package com.example.example.view;
import java.lang.ref.SoftReference;
import java.security.acl.LastOwnerException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Random;
import java.util.concurrent.ArrayBlockingQueue;
import android.animation.Animator;
import android.animation.Animator.AnimatorListener;
import android.animation.ObjectAnimator;
import android.animation.TimeInterpolator;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.app.Application;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.util.Log;
import android.util.LruCache;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.LinearInterpolator;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
/**
* 自定義彈幕控制元件
* @author 1
*
*/
public class MyBarrageView1 extends LinearLayout {
/**
* 每行有多少個彈幕item
*/
private static final int ROW_ITEM_COUNT = 7;
/**
* 上面留出的空白區單位,單位為dp
*/
private static final int TOP_PADDING = 3;
/**
* 是否停止彈幕動畫
*/
private boolean stop = false;
/**
* 存放所有用到的動畫
*/
private HashSet<ObjectAnimator> animators = new HashSet<ObjectAnimator>();
private HashSet<ObjectAnimator> pausedAnimators = new HashSet<ObjectAnimator>();
private HashSet<BarrageViewItem> viewItems = new HashSet<MyBarrageView1.BarrageViewItem>();
/**
* 彈幕是否可以迴圈滾動
*/
private boolean canLoop = false;
public MyBarrageView1(Context context) {
super(context);
init();
}
public MyBarrageView1(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public MyBarrageView1(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
/**
* 獲取彈幕是否可以迴圈滾動
*/
public boolean isCanLoop() {
return canLoop;
}
/**
* 設定彈幕是否可以迴圈滾動
*/
public void setCanLoop(boolean canLoop) {
this.canLoop = canLoop;
}
private HashSet<BarrageViewItem> tmpItems = new HashSet<MyBarrageView1.BarrageViewItem>();
boolean canAdd = false;
private void init() {
setOrientation(LinearLayout.VERTICAL);
int topPading = dip2px(getContext(), TOP_PADDING);
System.out.println("------ topPading = "+topPading);
setPadding(0, topPading, 0, 0);
getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
//Log.v("layout", "getMeasuredHeight()="+getMeasuredHeight()+" getHeight()="+getHeight());
int count = getChildCount();
if(count > 0){
View lastGroup = getChildAt(count-1);
if(lastGroup.getHeight() > 0 && !tmpItems.isEmpty()){
Iterator<BarrageViewItem> it = tmpItems.iterator();
BarrageViewItem item = it.next();
add(item);
Log.d("data", "item.getData() ="+item.getData().toString());
tmpItems.remove(item);
}
Log.v("layout1", "tmpItems.size()="+tmpItems.size());
Log.v("layout1", "lastGroup.getMeasuredHeight()="+lastGroup.getMeasuredHeight()+" lastGroup.getHeight()="+lastGroup.getHeight()+" canAdd="+canAdd);
}
}
});
}
/**
* 根據手機的解析度從 dp 的單位 轉成為 px(畫素)
*/
public static int dip2px(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
/**
* 增加彈幕
* @param item
*/
public void add(BarrageViewItem item){
Log.v("layout", "tmpItems.size()="+tmpItems.size());
if(!canAdd()){
tmpItems.add(item);
return;
}
if(isFull()){
addViewItem(item);
}else {
addGroupItem(item);
}
}
/**
* 判斷 是不是可以新加新彈幕組,要在上一次新增的彈幕組完了測量等一系列動作後,才可以再新增
* @return
*/
private boolean canAdd() {
if(getChildCount() < 1){
return true;
}
View lastChild = getChildAt(getChildCount()-1);
Log.d("layout", "lastChild.getHeight() = "+lastChild.getHeight());
return lastChild.getHeight() > 0;
}
/**
* 清屏,把所有彈幕清掉
*/
public void clear(){
removeAllViews();
}
/**
* 停止彈幕滑動
*/
public void stop(){
stop = true;
if(!animators.isEmpty()){
Iterator<ObjectAnimator> iterator = animators.iterator();
while (iterator.hasNext()) {
ObjectAnimator anim = iterator.next();
if(anim.isRunning()){
anim.cancel();
pausedAnimators.add(anim);
}
}
}
}
/**
* 開啟彈幕移動
*/
public void start(){
if(!pausedAnimators.isEmpty()){
Iterator<ObjectAnimator> iterator = pausedAnimators.iterator();
while (iterator.hasNext()) {
iterator.next().start();
}
pausedAnimators.clear();
}
stop = false;
}
/**
* 判斷是否已經停止彈幕滾動
* @return
*/
public boolean isStop() {
return stop;
}
/**
* 檢查行Viewgroup是不是已加滿
* @return
*/
private boolean isFull() {
if(getChildCount() < 1){
return false;
}
View lastViewGroup = getChildAt(getChildCount()-1);
lastViewGroup.measure(0, 0);
//int lastBottom = lastViewGroup.getTop()+lastViewGroup.getMeasuredHeight();
Log.v("test", "last getHeight()="+lastViewGroup.getHeight() +" lastView getMeasuredHeight = "+lastViewGroup.getMeasuredHeight()+" getMeasuredHeight="+getMeasuredHeight());
//boolean b1 = lastViewGroup.getMeasuredHeight() > lastViewGroup.getHeight();
boolean b2 = getHeight() - lastViewGroup.getBottom() < lastViewGroup.getMeasuredHeight();
Log.d("test", "b1="/*+b1*/ +" b2="+b2);
return b2 /*b1 || b2*/;
}
/**
* 根據指定的BarrageViewItem,增加相應彈幕
* @param item
*/
private void addViewItem(BarrageViewItem item) {
int rowIndex = new Random().nextInt(getChildCount());
addItemView2Viewgroup(rowIndex,item);
}
/**
* 根據指定的字元,增加相應彈幕,並新增新的彈幕行
* @param txt
*/
private void addGroupItem(BarrageViewItem item) {
final RelativeLayout layout = new RelativeLayout(getContext());
addView(layout);
int rowIndex = getChildCount() - 1;
addItemView2Viewgroup(rowIndex,item);
}
/**
* 用來動態更新相應條目
*/
Handler itemUpdateHandler = new Handler(){
public void handleMessage(Message msg) {
BarrageViewItem item = (BarrageViewItem) msg.obj;
item.update(item.getRootView(),item.getData());
};
};
/**
* 把指定的item加到指定行號viewGroup上
* @param rowIndex 指定的行號
* @param item 相應的item
*/
private void addItemView2Viewgroup(final int rowIndex, final BarrageViewItem item) {
View v = null;
Holder holder;
int width = getResources().getDisplayMetrics().widthPixels;
ObjectAnimator animator = null ;
final RelativeLayout group = (RelativeLayout) getChildAt(rowIndex);
if(group.getChildCount() >= ROW_ITEM_COUNT){
viewItems.add(item);
System.out.println("-----數量已夠-----");
}else {
//賦值view幫助類
holder = new Holder();
holder.rowIndex = rowIndex;
holder.startX = width;
holder.endX = 0 - width;
item.update(item.getRootView(),item.getData());
v = item.getRootView();
v.setTag(holder);
animator = ObjectAnimator.ofFloat(v, "translationX", width,0-width);
animator.addListener(new MyAnimatorListener(item));
holder.animator = new SoftReference<ObjectAnimator>(animator);
animators.add(animator);
group.addView(v);
System.out.println("-----數量未夠-----");
animator.setDuration(item.getDuration()*2);
animator.setInterpolator(getInterpolator());
if(!stop){
animator.start();
}else {
pausedAnimators.add(animator);
}
}
}
/**
* 隨機獲取顏色值
* @return
*/
public int getColor() {
int[] colors = new int[]{Color.BLACK,Color.BLUE, Color.CYAN,Color.RED,Color.GREEN,Color.WHITE,Color.YELLOW
/*,0xffFFC125,0xffFFC125,0xffFF0000,0xffEEEE00,0xffFF00FF,0xffEEE8CD,0xffB8860B,0xffA52A2A,0xff7A378B,0xff787878,0xff5CACEE,0xff00EE00*/};
Random random = new Random();
return colors[random.nextInt(colors.length)];
}
/**
* 隨機獲取彈幕動畫加速器
* @return
*/
private TimeInterpolator getInterpolator() {
Random random = new Random();
int id = random.nextInt(4);
System.out.println("getInterpolator------id = "+id);
switch (id) {
case 0:
return new AccelerateDecelerateInterpolator();
case 1:
return new AccelerateInterpolator();
case 2:
return new DecelerateInterpolator();
case 3:
return new LinearInterpolator();
/*case 4:
return new BounceInterpolator();
case 5:
return new CycleInterpolator(3);
case 6:
return new AnticipateInterpolator();
case 7:
return new AnticipateOvershootInterpolator();
case 8:
return new OvershootInterpolator();*/
default:
break;
}
return new LinearInterpolator();
}
/**
* 根據指定的字元生成Textview
* @param txt
* @return
*/
private TextView initTextview(String txt){
TextView textView = new TextView(getContext());
textView.setBackgroundColor(0xffffff);
textView.setSingleLine(true);
textView.setTextColor(Color.RED);
textView.setGravity(Gravity.CENTER);
textView.setText("---------------text "+txt+"------------");
android.view.ViewGroup.LayoutParams layoutParams = new LayoutParams(android.view.ViewGroup.LayoutParams.WRAP_CONTENT, android.view.ViewGroup.LayoutParams.WRAP_CONTENT);
textView.setLayoutParams(layoutParams);
return textView;
}
/**
* 幫助類
* @author 1
*/
class Holder{
/**
* view所處的行號
*/
public int rowIndex;
/**
* 動畫持續時間
*/
public int duation;
/**
* 動畫開始座標
*/
public int startX;
/**
* 動畫結束座標
*/
public float endX;
/**
* view所繫結的動畫
*/
public SoftReference<ObjectAnimator> animator;
}
Handler handler = new Handler(){
public void handleMessage(Message msg) {
ObjectAnimator animator = (ObjectAnimator) msg.obj;
animator.start();
//System.out.println("------handleMessage------");
};
};
/**
* 動畫監聽器
* @author 1
*
*/
class MyAnimatorListener implements AnimatorListener{
private BarrageViewItem barrageViewItem;
public MyAnimatorListener(BarrageViewItem item){
barrageViewItem = item;
}
@Override
public void onAnimationStart(Animator animation) {}
@Override
public void onAnimationEnd(Animator animation) {
//判斷是否已停止彈幕滑動或者已清屏
if( stop || getChildCount() < 1) {
return;
}
boolean viewItemsIsEmpty = false;
Holder holder = (Holder) barrageViewItem.getRootView().getTag();
((ObjectAnimator) animation).setFloatValues(holder.startX,holder.endX);
if(!viewItems.isEmpty()){
Log.d("TAG", "------viewItems.size()------"+viewItems.size());
Iterator<BarrageViewItem> it = viewItems.iterator();
BarrageViewItem item = it.next();
barrageViewItem.update(item.getRootView(),item.getData());
viewItems.remove(item);
viewItemsIsEmpty = false;
}else {
viewItemsIsEmpty = true;
}
if(!viewItemsIsEmpty || canLoop){
Message msg = handler.obtainMessage();
msg.obj = animation;
msg.sendToTarget();
}
System.out.println("--------onAnimationEnd--------viewItemsIsEmpty="+viewItemsIsEmpty+" canLoop="+canLoop);
}
@Override
public void onAnimationCancel(Animator animation) {
Float f = (Float) ((ValueAnimator)animation).getAnimatedValue();
System.out.println("ssss f="+f);
((ObjectAnimator)animation).setFloatValues(f,0-getContext().getResources().getDisplayMetrics().widthPixels);
System.out.println("--------onAnimationCancel---------");
}
@Override
public void onAnimationRepeat(Animator animation) {}
}
/**
* 彈幕item
* @author 1
*/
public static abstract class BarrageViewItem{
protected View rootView = null;
protected abstract View getView();
public abstract void setData(Object data);
public abstract Object getData();
/**
* 根據指定的資料更新相應的顯示
* @param data
*/
public abstract void update(View view,Object data);
/**
* item在螢幕上出現的時長,以毫秒為單位
* @return
*/
public abstract int getDuration();
final public View getRootView(){
//Log.d("update", "----getRootView----"+getClass().getName());
if(rootView == null){
rootView = getView();
}
return rootView;
}
}
}
相關文章
- 自定義簡單彈幕實現
- iOS自定義控制元件:精簡的底部彈框iOS控制元件
- avalonia自定義彈窗
- 自定義 alert 彈窗
- Android自定義控制元件之自定義組合控制元件Android控制元件
- Android自定義控制元件——自定義屬性Android控制元件
- 自定義Switch控制元件控制元件
- 自定義控制元件ViewPager控制元件Viewpager
- 控制元件自定義位置控制元件
- 如何自定義控制元件控制元件
- 自定義版本更新彈窗
- 自定義popup彈出框
- 自定義view————廣告彈窗View
- 4. 自定義控制元件(4) --- 自定義屬性控制元件
- Android自定義控制元件之自定義屬性Android控制元件
- Flutter 之 自定義控制元件Flutter控制元件
- iOS自定義控制元件 AlertViewiOS控制元件View
- iOS自定義控制元件 SegmentiOS控制元件
- WPF Blend 自定義控制元件控制元件
- 自定義分頁控制元件控制元件
- winform 自定義容器控制元件ORM控制元件
- uniapp 自定義彈窗元件APP元件
- 自定義控制元件之歌詞RCL控制元件控制元件
- Android自定義組合控制元件之自定義屬性Android控制元件
- C#自定義控制元件:如果定義控制元件的事件C#控制元件事件
- WPF 自定義控制元件的坑(蠢的:自定義控制元件內容不顯示)控制元件
- Flutter 自定義縮放控制元件Flutter控制元件
- iOS自定義控制元件 SlideriOS控制元件IDE
- Qt實現自定義控制元件QT控制元件
- android:建立自定義控制元件Android控制元件
- 自定義UIView UITableViewCell等控制元件UIView控制元件
- 自定義下拉選單控制元件控制元件
- 自定義的ValidationSummary控制元件控制元件
- avalonia實現自定義小彈窗
- iOS 自定義內容的彈窗iOS
- iOS自定義控制元件:簡易下拉控制元件iOS控制元件
- android 自定義控制元件 自定義屬性詳細介紹Android控制元件
- (Android自定義控制元件)Android自定義狀態提示圖表Android控制元件