線上直播原始碼,自定義氣泡效果(BubbleView)
線上直播原始碼,自定義氣泡效果(BubbleView)
程式碼如下:
package com.example.myapplication; import android.content.Context; import android.graphics.BlurMaskFilter; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.RectF; import android.util.AttributeSet; import android.util.Log; import android.util.TypedValue; import android.view.View; import androidx.annotation.Nullable; import java.util.ArrayList; import java.util.List; import java.util.Random; public class BubbleView extends View { private int mBubbleMaxRadius = 15; // 氣泡最大半徑 px private int mBubbleMinRadius = 8; // 氣泡最小半徑 px private int mBubbleMaxSize = 50; // 氣泡數量 private int mBubbleRefreshTime = 50; // 重新整理間隔 private int mBubbleMaxSpeedY = 2; // 氣泡速度 private int mBubbleMaxSpeedX = 4; // 氣泡速度 private int mBubbleAlpha = 128; // 氣泡畫筆 private float mContentWidth; // 瓶子寬度 private float mContentHeight; // 瓶子高度 private RectF mContentRectF; // 實際可用內容區域 private Paint mBubblePaint; // 氣泡畫筆 public BubbleView(Context context) { this(context, null); } public BubbleView(Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0); } public BubbleView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); mContentWidth = dp2px(130); mContentHeight = dp2px(260); mBubblePaint = new Paint(); mBubblePaint.setColor(Color.GREEN); mBubblePaint.setAlpha(mBubbleAlpha); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec); int widthSize = MeasureSpec.getSize(widthMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec); int width; int height; if (widthSpecMode == MeasureSpec.EXACTLY || widthSpecMode == MeasureSpec.AT_MOST) { width = widthSize; mContentWidth = width; } else { width = (int) mContentWidth; } if (heightSpecMode == MeasureSpec.EXACTLY || heightSpecMode == MeasureSpec.AT_MOST) { height = heightSize; mContentHeight = height; } else { height = (int) mContentHeight; } setMeasuredDimension(width, height); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); mContentRectF = new RectF(getPaddingLeft(), getPaddingTop(), w - getPaddingRight(), h - getPaddingBottom()); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); drawBubble(canvas); } @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); startBubbleSync(); } @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); stopBubbleSync(); } private static class Bubble { int radius; // 氣泡半徑 float speedY; // 上升速度 float speedX; // 平移速度 float x; // 氣泡x座標 float y; // 氣泡y座標 } private ArrayList<Bubble> mBubbles = new ArrayList<>(); private Random random = new Random(); private Thread mBubbleThread; // 開始氣泡執行緒 private void startBubbleSync() { stopBubbleSync(); mBubbleThread = new Thread() { public void run() { while (true) { try { Thread.sleep(mBubbleRefreshTime); tryCreateBubble(); refreshBubbles(); postInvalidate(); } catch (InterruptedException e) { break; } } } }; mBubbleThread.start(); } // 停止氣泡執行緒 private void stopBubbleSync() { if (null == mBubbleThread) return; mBubbleThread.interrupt(); mBubbleThread = null; } // 繪製氣泡 private void drawBubble(Canvas canvas) { List<Bubble> list = new ArrayList<>(mBubbles); for (Bubble bubble : list) { if (null == bubble) continue; canvas.drawCircle(bubble.x, bubble.y, bubble.radius, mBubblePaint); } } // 建立氣泡 private void tryCreateBubble() { if (null == mContentRectF) return; if (mBubbles.size() >= mBubbleMaxSize) { return; } if (random.nextFloat() < 0.95) { return; } Bubble bubble = new Bubble(); int radius = random.nextInt(mBubbleMaxRadius - mBubbleMinRadius); radius += mBubbleMinRadius; float speedX = 0.5f * mBubbleMaxSpeedX; // while (speedX < 1) { // speedX = random.nextFloat() * mBubbleMaxSpeedX; // } bubble.radius = radius; bubble.speedX = speedX; bubble.x = mContentRectF.left; bubble.y = mContentRectF.centerY(); float speedY = random.nextFloat() - 0.5f; while (speedY == 0) { speedY = random.nextFloat() - 0.5f; } bubble.speedY = speedY * 2; mBubblePaint.setMaskFilter(new BlurMaskFilter(radius, BlurMaskFilter.Blur.SOLID)); mBubbles.add(bubble); } // 重新整理氣泡位置,超出的氣泡進行移除 private void refreshBubbles() { List<Bubble> list = new ArrayList<>(mBubbles); for (Bubble bubble : list) { if (bubble.x + bubble.speedX >= mContentRectF.right + bubble.radius) { mBubbles.remove(bubble); } else { int i = mBubbles.indexOf(bubble); if (bubble.y + bubble.speedY <= mContentRectF.top + bubble.radius) { bubble.y = mContentRectF.top + bubble.radius; } else { bubble.y = Math.min(bubble.y + bubble.speedY, mContentRectF.bottom - bubble.radius); } bubble.x = bubble.x + bubble.speedX; mBubbles.set(i, bubble); } } } private float dp2px(float dpValue) { return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpValue, getResources().getDisplayMetrics()); } }
目前為自定義屬性,佈局檔案中直接引用即可。
<com.example.myapplication.BubbleView android:layout_width="300dp" android:layout_height="100dp"/>
以上就是 線上直播原始碼,自定義氣泡效果(BubbleView),更多內容歡迎關注之後的文章
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69978258/viewspace-2906219/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 直播平臺搭建,自定義氣泡效果(BubbleView)View
- 線上直播系統原始碼,滑鼠懸停後彈出氣泡原始碼
- 線上直播系統原始碼,自定義底部 BottomNavigationBar原始碼Navigation
- Android自定義View 水波氣泡AndroidView
- 直播平臺原始碼,Flutter 自定義 虛線 分割線原始碼Flutter
- 手機直播原始碼,Flutter 自定義 虛線 分割線原始碼Flutter
- 線上直播原始碼,自定義導航欄並固定居中對齊原始碼
- 直播平臺原始碼,Android自定義View實現呼吸燈效果原始碼AndroidView
- 直播系統app原始碼,用遞迴實現氣泡排序APP原始碼遞迴排序
- app直播原始碼,java自定義註解APP原始碼Java
- 影片直播app原始碼,自定義View 線型EditText輸入框APP原始碼View
- 線上直播原始碼,自定義AlertDialog設定寬高並去掉預設的邊框原始碼
- 線上直播原始碼,JS動態效果之,側邊欄滾動固定效果原始碼JS
- 直播系統app原始碼,TabLayout:自定義字型大小APP原始碼TabLayout自定義字型
- 視訊直播系統原始碼,使用自定義UI 完成文字顏色載入效果原始碼UI
- 直播系統程式碼,Android自定義View實現呼吸燈效果AndroidView
- app直播原始碼,uniapp之自定義頂部樣式APP原始碼
- 直播軟體原始碼,自定義RecyclerView支援快速滾動原始碼View
- 直播商城原始碼,vue 自定義指令過濾特殊字元原始碼Vue字元
- app直播原始碼,vue 自定義指令過濾特殊字元APP原始碼Vue字元
- 線上直播原始碼,CSS磨砂玻璃效果和漸變主題色文字原始碼CSS
- 線上直播系統原始碼,預設倒數計時,自定義輸入時間倒數計時原始碼
- css3氣泡動態上升效果CSSS3
- 影片直播系統原始碼,自定義背景和狀態管理原始碼
- 直播軟體原始碼,vue 自定義指令過濾特殊字元原始碼Vue字元
- 直播平臺搭建原始碼,qt自定義滑動按鈕原始碼QT
- app直播原始碼,el-button自定義圖片顯示APP原始碼
- 線上直播系統原始碼,Android開發之自帶陰影效果的shape原始碼Android
- 線上直播系統原始碼,實現搜尋後介面顯示商品列表效果原始碼
- 線上直播系統原始碼,使用ValueAnimator實現view放大縮小動畫效果原始碼View動畫
- 直播帶貨原始碼,二次封裝a-upload元件,自定義上傳預覽原始碼封裝元件
- 成品直播原始碼,如何在開發時自定義快取策略原始碼快取
- 直播平臺原始碼,自定義下拉重新整理控制元件原始碼控制元件
- 直播小程式原始碼,react-native自定義文字輸入框原始碼React
- 直播原始碼開發,el-button自定義圖片顯示原始碼
- 直播平臺原始碼,el-button自定義圖片顯示原始碼
- 直播軟體原始碼,自定義修改原本已有的圖示原始碼
- 線上直播系統原始碼,利用css和html實現首頁圖片輪播效果原始碼CSSHTML