新聞中心
本文實(shí)例講述了Android編程實(shí)現(xiàn)簡(jiǎn)易彈幕效果。分享給大家供大家參考,具體如下:
創(chuàng)新互聯(lián)公司是一家專注于成都做網(wǎng)站、成都網(wǎng)站建設(shè)、成都外貿(mào)網(wǎng)站建設(shè)與策劃設(shè)計(jì),橫縣網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)公司做網(wǎng)站,專注于網(wǎng)站建設(shè)10年,網(wǎng)設(shè)計(jì)領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:橫縣等地區(qū)。橫縣做網(wǎng)站價(jià)格咨詢:18980820575
首先上效果圖,類似于360檢測(cè)到騷擾電話頁(yè)面:
布局很簡(jiǎn)單,上面是一個(gè)RelativeLayout,下面一個(gè)Button.
功能:
(1)彈幕生成后自動(dòng)從右側(cè)往左側(cè)滾動(dòng)(TranslateAnimation),彈幕消失后立刻被移除。
(2)彈幕位置隨機(jī)出現(xiàn),并且不重復(fù)(防止文字重疊)。
(3)字體大小在一定范圍內(nèi)隨機(jī)改變,字體顏色也可以設(shè)置。
(4)自定義先減速,后加速的Interpolator,彈幕加速進(jìn)入、減速停留、然后加速出去。
1.Activity代碼:
/** * 簡(jiǎn)易彈幕效果實(shí)現(xiàn) * Created by admin on 15-6-4. */ public class MainActivity extends ActionBarActivity { private MyHandler handler; //彈幕內(nèi)容 private TanmuBean tanmuBean; //放置彈幕內(nèi)容的父組件 private RelativeLayout containerVG; //父組件的高度 private int validHeightSpace; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); containerVG = (RelativeLayout) findViewById(R.id.tanmu_container); tanmuBean = new TanmuBean(); tanmuBean.setItems(new String[]{"測(cè)試一下", "彈幕這東西真不好做啊", "總是出現(xiàn)各種問題~~", "也不知道都是為什么?麻煩!", "哪位大神可以幫幫我???", "I need your help.", "測(cè)試一下", "彈幕這東西真不好做啊", "總是出現(xiàn)各種問題~~", "也不知道都是為什么?麻煩!", "哪位大神可以幫幫我啊?", "I need your help.", "測(cè)試一下", "彈幕這東西真不好做啊", "總是出現(xiàn)各種問題~~", "也不知道都是為什么?麻煩!", "哪位大神可以幫幫我?。?, "I need your help."}); handler = new MyHandler(this); //開始彈幕 View startTanmuView = findViewById(R.id.startTanmu); startTanmuView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (containerVG.getChildCount() > 0) { return; } existMarginValues.clear(); new Thread(new CreateTanmuThread()).start(); } }); } //每2s自動(dòng)添加一條彈幕 private class CreateTanmuThread implements Runnable { @Override public void run() { int N = tanmuBean.getItems().length; for (int i = 0; i < N; i++) { handler.obtainMessage(1, i, 0).sendToTarget(); SystemClock.sleep(2000); } } } //需要在主線城中添加組件 private static class MyHandler extends Handler { private WeakReferenceref; MyHandler(MainActivity ac) { ref = new WeakReference<>(ac); } @Override public void handleMessage(Message msg) { super.handleMessage(msg); if (msg.what == 1) { MainActivity ac = ref.get(); if (ac != null && ac.tanmuBean != null) { int index = msg.arg1; String content = ac.tanmuBean.getItems()[index]; float textSize = (float) (ac.tanmuBean.getMinTextSize() * (1 + Math.random() * ac.tanmuBean.getRange())); int textColor = ac.tanmuBean.getColor(); ac.showTanmu(content, textSize, textColor); } } } } private void showTanmu(String content, float textSize, int textColor) { final TextView textView = new TextView(this); textView.setTextSize(textSize); textView.setText(content); // textView.setSingleLine(); textView.setTextColor(textColor); int leftMargin = containerVG.getRight() - containerVG.getLeft() - containerVG.getPaddingLeft(); //計(jì)算本條彈幕的topMargin(隨機(jī)值,但是與屏幕中已有的不重復(fù)) int verticalMargin = getRandomTopMargin(); textView.setTag(verticalMargin); LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); params.addRule(RelativeLayout.ALIGN_PARENT_TOP); params.topMargin = verticalMargin; textView.setLayoutParams(params); Animation anim = AnimationHelper.createTranslateAnim(this, leftMargin, -ScreenUtils.getScreenW(this)); anim.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { //移除該組件 containerVG.removeView(textView); //移除占位 int verticalMargin = (int) textView.getTag(); existMarginValues.remove(verticalMargin); } @Override public void onAnimationRepeat(Animation animation) { } }); textView.startAnimation(anim); containerVG.addView(textView); } //記錄當(dāng)前仍在顯示狀態(tài)的彈幕的位置(避免重復(fù)) private Set existMarginValues = new HashSet<>(); private int linesCount; private int getRandomTopMargin() { //計(jì)算用于彈幕顯示的空間高度 if (validHeightSpace == 0) { validHeightSpace = containerVG.getBottom() - containerVG.getTop() - containerVG.getPaddingTop() - containerVG.getPaddingBottom(); } //計(jì)算可用的行數(shù) if (linesCount == 0) { linesCount = validHeightSpace / ScreenUtils.dp2px(this, tanmuBean.getMinTextSize() * (1 + tanmuBean.getRange())); if (linesCount == 0) { throw new RuntimeException("Not enough space to show text."); } } //檢查重疊 while (true) { int randomIndex = (int) (Math.random() * linesCount); int marginValue = randomIndex * (validHeightSpace / linesCount); if (!existMarginValues.contains(marginValue)) { existMarginValues.add(marginValue); return marginValue; } } } }
2.平移動(dòng)畫生成工具:
public class AnimationHelper { /** * 創(chuàng)建平移動(dòng)畫 */ public static Animation createTranslateAnim(Context context, int fromX, int toX) { TranslateAnimation tlAnim = new TranslateAnimation(fromX, toX, 0, 0); //自動(dòng)計(jì)算時(shí)間 long duration = (long) (Math.abs(toX - fromX) * 1.0f / ScreenUtils.getScreenW(context) * 4000); tlAnim.setDuration(duration); tlAnim.setInterpolator(new DecelerateAccelerateInterpolator()); tlAnim.setFillAfter(true); return tlAnim; } }
ScreenUtils是用來(lái)獲取屏幕寬高、dp與px之間互轉(zhuǎn)的工具類。
3.自定義的Interpolator,其實(shí)只有一行代碼
public class DecelerateAccelerateInterpolator implements Interpolator { //input從0~1,返回值也從0~1.返回值的曲線表征速度加減趨勢(shì) @Override public float getInterpolation(float input) { return (float) (Math.tan((input * 2 - 1) / 4 * Math.PI)) / 2.0f + 0.5f; } }
4.TanmuBean是一個(gè)實(shí)體類
public class TanmuBean { private String[] items; private int color; private int minTextSize; private float range; public TanmuBean() { //init default value color = Color.parseColor("#eeeeee"); minTextSize = 16; range = 0.5f; } public String[] getItems() { return items; } public void setItems(String[] items) { this.items = items; } public int getColor() { return color; } public void setColor(int color) { this.color = color; } /** * min textSize, in dp. */ public int getMinTextSize() { return minTextSize; } public void setMinTextSize(int minTextSize) { this.minTextSize = minTextSize; } public float getRange() { return range; } public void setRange(float range) { this.range = range; } }
完整實(shí)例代碼點(diǎn)擊此處本站下載。
更多關(guān)于Android相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Android視圖View技巧總結(jié)》、《Android開發(fā)動(dòng)畫技巧匯總》、《Android編程之a(chǎn)ctivity操作技巧總結(jié)》、《Android布局layout技巧總結(jié)》、《Android開發(fā)入門與進(jìn)階教程》、《Android資源操作技巧匯總》及《Android控件用法總結(jié)》
希望本文所述對(duì)大家Android程序設(shè)計(jì)有所幫助。
本文名稱:Android編程實(shí)現(xiàn)簡(jiǎn)易彈幕效果示例【附demo源碼下載】
當(dāng)前路徑:http://www.dlmjj.cn/article/gdhipo.html