Android:简易弹幕效果实现,android弹幕

转载自http://www.android100.org/html/201506/16/154227.html

首先上效果图,类似于360检测到骚扰电话页面:


布局很简单,上面是一个RelativeLayout,下面一个Button.

功能:

(1)弹幕生成后自动从右侧往左侧滚动(TranslateAnimation),弹幕消失后立刻被移除。

(2)弹幕位置随机出现,并且不重复(防止文字重叠)。

(3)字体大小在一定范围内随机改变,字体颜色也可以设置。

(4)自定义先减速,后加速的Interpolator,弹幕加速进入、减速停留、然后加速出去。

1.Activity代码:

/***简易弹幕效果实现*Createdbyadminon15-6-4.*/publicclassMainActivityextendsActionBarActivity{privateMyHandlerhandler;//弹幕内容privateTanmuBeantanmuBean;//放置弹幕内容的父组件privateRelativeLayoutcontainerVG;//父组件的高度privateintvalidHeightSpace;@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);containerVG=(RelativeLayout)findViewById(R.id.tanmu_container);tanmuBean=newTanmuBean();tanmuBean.setItems(newString[]{"测试一下","弹幕这东西真不好做啊","总是出现各种问题~~","也不知道都是为什么?麻烦!","哪位大神可以帮帮我啊?","Ineedyourhelp.","测试一下","弹幕这东西真不好做啊","总是出现各种问题~~","也不知道都是为什么?麻烦!","哪位大神可以帮帮我啊?","Ineedyourhelp.","测试一下","弹幕这东西真不好做啊","总是出现各种问题~~","也不知道都是为什么?麻烦!","哪位大神可以帮帮我啊?","Ineedyourhelp."});handler=newMyHandler(this);//开始弹幕ViewstartTanmuView=findViewById(R.id.startTanmu);startTanmuView.setOnClickListener(newView.OnClickListener(){@OverridepublicvoidonClick(Viewv){if(containerVG.getChildCount()>0){return;}existMarginValues.clear();newThread(newCreateTanmuThread()).start();}});}//每2s自动添加一条弹幕privateclassCreateTanmuThreadimplementsRunnable{@Overridepublicvoidrun(){intN=tanmuBean.getItems().length;for(inti=0;i<N;i++){handler.obtainMessage(1,i,0).sendToTarget();SystemClock.sleep(2000);}}}//需要在主线城中添加组件privatestaticclassMyHandlerextendsHandler{privateWeakReference<MainActivity>ref;MyHandler(MainActivityac){ref=newWeakReference<>(ac);}@OverridepublicvoidhandleMessage(Messagemsg){super.handleMessage(msg);if(msg.what==1){MainActivityac=ref.get();if(ac!=null&&ac.tanmuBean!=null){intindex=msg.arg1;Stringcontent=ac.tanmuBean.getItems()[index];floattextSize=(float)(ac.tanmuBean.getMinTextSize()*(1+Math.random()*ac.tanmuBean.getRange()));inttextColor=ac.tanmuBean.getColor();ac.showTanmu(content,textSize,textColor);}}}}privatevoidshowTanmu(Stringcontent,floattextSize,inttextColor){finalTextViewtextView=newTextView(this);textView.setTextSize(textSize);textView.setText(content);//textView.setSingleLine();textView.setTextColor(textColor);intleftMargin=containerVG.getRight()-containerVG.getLeft()-containerVG.getPaddingLeft();//计算本条弹幕的topMargin(随机值,但是与屏幕中已有的不重复)intverticalMargin=getRandomTopMargin();textView.setTag(verticalMargin);LayoutParamsparams=newLayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);params.addRule(RelativeLayout.ALIGN_PARENT_TOP);params.topMargin=verticalMargin;textView.setLayoutParams(params);Animationanim=AnimationHelper.createTranslateAnim(this,leftMargin,-ScreenUtils.getScreenW(this));anim.setAnimationListener(newAnimation.AnimationListener(){@OverridepublicvoidonAnimationStart(Animationanimation){}@OverridepublicvoidonAnimationEnd(Animationanimation){//移除该组件containerVG.removeView(textView);//移除占位intverticalMargin=(int)textView.getTag();existMarginValues.remove(verticalMargin);}@OverridepublicvoidonAnimationRepeat(Animationanimation){}});textView.startAnimation(anim);containerVG.addView(textView);}//记录当前仍在显示状态的弹幕的位置(避免重复)privateSet<Integer>existMarginValues=newHashSet<>();privateintlinesCount;privateintgetRandomTopMargin(){//计算用于弹幕显示的空间高度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){thrownewRuntimeException("Notenoughspacetoshowtext.");}}//检查重叠while(true){intrandomIndex=(int)(Math.random()*linesCount);intmarginValue=randomIndex*(validHeightSpace/linesCount);if(!existMarginValues.contains(marginValue)){existMarginValues.add(marginValue);returnmarginValue;}}}}2.平移动画生成工具:publicclassAnimationHelper{/***创建平移动画*/publicstaticAnimationcreateTranslateAnim(Contextcontext,intfromX,inttoX){TranslateAnimationtlAnim=newTranslateAnimation(fromX,toX,0,0);//自动计算时间longduration=(long)(Math.abs(toX-fromX)*1.0f/ScreenUtils.getScreenW(context)*4000);tlAnim.setDuration(duration);tlAnim.setInterpolator(newDecelerateAccelerateInterpolator());tlAnim.setFillAfter(true);returntlAnim;}}


ScreenUtils是用来获取屏幕宽高、dp与px之间互转的工具类。

3.自定义的Interpolator,其实只有一行代码

publicclassDecelerateAccelerateInterpolatorimplementsInterpolator{//input从0~1,返回值也从0~1.返回值的曲线表征速度加减趋势@OverridepublicfloatgetInterpolation(floatinput){return(float)(Math.tan((input*2-1)/4*Math.PI))/2.0f+0.5f;}}


4.TanmuBean是一个实体类

publicclassTanmuBean{privateString[]items;privateintcolor;privateintminTextSize;privatefloatrange;publicTanmuBean(){//initdefaultvaluecolor=Color.parseColor("#eeeeee");minTextSize=16;range=0.5f;}publicString[]getItems(){returnitems;}publicvoidsetItems(String[]items){this.items=items;}publicintgetColor(){returncolor;}publicvoidsetColor(intcolor){this.color=color;}/***mintextSize,indp.*/publicintgetMinTextSize(){returnminTextSize;}publicvoidsetMinTextSize(intminTextSize){this.minTextSize=minTextSize;}publicfloatgetRange(){returnrange;}publicvoidsetRange(floatrange){this.range=range;}}


更多相关文章

  1. 1.3 Android App 组件架构
  2. Android架构组件(二)——LiveData
  3. 【小超_Android】2015最流行的android组件、工具、框架大全(后续)
  4. Android应用程序组件Content Provider在应用程序之间共享数据的
  5. Android中的BatteryService及相关组件
  6. Android 开源组件和第三方库汇总
  7. Android应用程序组件Content Provider的启动过程源代码分析(2)

随机推荐

  1. Android中通过pid获取app包名
  2. Android录屏的三种方案
  3. Android 中设置桌面背景
  4. Android app获取android.permission.BATT
  5. Android canvas.drawArc() 画圆弧
  6. Android 笑话+html 实例开发(详解)
  7. android 创建快捷方式图标到桌面
  8. android:windowIsTranslucent
  9. android监听按钮的点击事件
  10. android studio 中include