網站首頁 編程語言 正文
實踐過程
SurfaceView屬性和方法
- surfaceCreated(@NonNull SurfaceHolder holder):surface創建時回調
- surfaceDestroyed(@NonNull SurfaceHolder holder):surface銷毀時回調
- surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height):surface發生變化時回調
- SurfaceHolder.addCallback(context):添加回調,也就是上面三個方法
- lockCanvas():獲取Canvas對象并鎖定畫布,調用Canvas進行繪圖,和unlockCanvasAndPost是依次成對出現。
- unlockCanvasAndPost():結束鎖定畫布,并且提交改變。和lockCanvas是依次成對出現。
TextureView屬性和方法
- getSurfaceTexture():此方法返回此視圖使用的 SurfaceTexture。
- getBitmap(整型寬度,整型高度):此方法返回返回關聯表面紋理內容的位圖表示形式。
- getTransform(Matrix transform):此方法返回與此紋理視圖關聯的轉換。
- isOpaque():此方法指示此視圖是否不透明。
- lockCanvas():此方法開始編輯曲面中的像素。
- setOpaque(boolean opaque):此方法指示此紋理視圖的內容是否不透明。
- setTransform(Matrix transform):此方法將轉換設置為與此紋理視圖關聯。
- unlockCanvasAndPost(Canvas canvas):此方法完成對曲面中像素的編輯。
- onSurfaceTextureAvailable(SurfaceTexture arg0, int arg1, int arg2):創建的監聽,前提開啟硬件加速
- onSurfaceTextureDestroyed(SurfaceTexture arg0):銷毀的監聽
- onSurfaceTextureSizeChanged(SurfaceTexture arg0, int arg1,int arg2):變化的監聽
- onSurfaceTextureUpdated(SurfaceTexture arg0):更新的監聽
TextureView示例
public class MainActivity extends Activity implements SurfaceTextureListener{
??? private Camera mCamera;
??? private TextureView [mTextureView]();
??? protected void onCreate(Bundle savedInstanceState) {
??????? super.onCreate(savedInstanceState);
??????? mTextureView = new TextureView(this);
??????? mTextureView.setSurfaceTextureListener(this);
??????? setContentView(mTextureView);
??? }
??? public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
??????? mCamera = Camera.open();
??????? try {
??????????? mCamera.setPreviewTexture(surface);
??????????? mCamera.startPreview();
????????????//可以修改透明度和旋轉方向
mTextureView.setAlpha(1.0f);
mTextureView.setRotation(90.0f);
??????? } catch (IOException ioe) {
??????????? // 異常處理
??????? }
??? }
??? public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
??? }
??? public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
??????? mCamera.stopPreview();
??????? mCamera.release();
??????? return true;
??? }
?? ?public void onSurfaceTextureUpdated(SurfaceTexture surface) {
??? }
}
SurfaceView示例
Java版本自定義
public class ECGSurfaceViewJava extends SurfaceView implements SurfaceHolder.Callback {
??? //簡單模擬一下數據
??? public List<Integer> ecgDatas = new ArrayList<>();
??? //矩陣? 畫布 畫筆 顏色
??? private Rect rect;
??? private Canvas mCanvas;
??? private Paint mPaint;? //畫波形的畫筆
??? private String line_color = "#01FC00";? //畫筆默認是綠色的
??? private int wave_speed = 30;//定義波速:30mm/s
??? private int sleepTime = 8;//每次鎖屏的時間間距,單位ms 連線的時間長度,,如果大則會卡頓效果
??? private SurfaceHolder surfaceHolder;
??? private boolean isCanRun = true;
??? private int mStartX = 0;
??? private int mStartY = 0;
??? private Runnable drawRunnable = new Runnable() {
??????? @Override
??????? public void run() {
??????????? while (isCanRun) {
?????????????? //在這獲取改view的寬度? 如果mStartX超過則歸位 這樣實現反復從頭畫,我這800只是簡單表示下效果
??????????????? if (mStartX > 800) {
??????????????????? mStartX = 0;
??????????????? }
??????????????? //繪制區域不斷向右變化
??????????????? rect.set(mStartX, 0, mStartX + 16, 300);
????????? ??????mCanvas = surfaceHolder.lockCanvas(rect);? //提交繪制區域
??????????????? if (mCanvas == null) return;
??????????????? //很重要,如果反復從頭繪制,會覆蓋上一次的繪制
??????????????? mCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
??????????????? if (ecgDatas.size() > 0) {
??????????????????? mCanvas.drawLine(mStartX, mStartY, mStartX + 16, ecgDatas.get(0), mPaint);
??????????????????? //這個點的重點是下一個點的起點
??????????????????? mStartX = mStartX + 16;
??????????????????? mStartY = ecgDatas.get(0);
??????????????????? ecgDatas.remove(0);
??????????????? } else {
??????????????????? initData();
??????????????? }
??????????????? surfaceHolder.unlockCanvasAndPost(mCanvas);??? //這種方式把上次繪制的遮蓋了 因此出現了斷點
??????????? }
??????? }
??? };
??? public ECGSurfaceViewJava(Context context, AttributeSet attrs) {
??????? super(context, attrs);
??????? this.surfaceHolder = this.getHolder();//獲取holder
??????? this.surfaceHolder.addCallback(this);
??????? rect = new Rect();? //繪制矩陣內
??????? mPaint = new Paint();
??????? mPaint.setColor(Color.parseColor(line_color));?? //畫筆顏色
??????? mPaint.setAntiAlias(true);?? //抗鋸齒
??????? mPaint.setStrokeWidth(2);
??????? initData();
??? }
??? private void initData() {
??????? ecgDatas.clear();
??????? for (int i = 0; i < 200; i++) {
??????????? ecgDatas.add((int) (Math.random() * 200));
??????? }
??????? mStartY = ecgDatas.get(0);
??? }
??? @Override
??? public void surfaceCreated(SurfaceHolder holder) {
??????? new Thread(drawRunnable).start();
??? }
??? @Override
??? public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
??? }
??? @Override
??? public void surfaceDestroyed(SurfaceHolder holder) {
??????? isCanRun = false;
??? }
}
Kotlin版本自定義
class ECGSurfaceViewKotlin(context: Context?, attrs: AttributeSet?) : SurfaceView(context, attrs), SurfaceHolder.Callback {
??? //簡單模擬一下數據
??? var ecgDatas: MutableList<Int> = ArrayList()
??? //矩陣? 畫布 畫筆 顏色
??? private var rect: Rect? = null
??? private var mCanvas: Canvas? = null
??? //畫波形的畫筆
??? private var mPaint: Paint? = null
??? private val line_color = "#01FC00" //畫筆默認是綠色的
??? private val wave_speed = 30 //定義波速:30mm/s
??? private val sleepTime = 8 //每次鎖屏的時間間距,單位ms 連線的時間長度,,如果大則會卡頓效果
??? var surfaceHolder: SurfaceHolder? = null
??? private var isCanRun = true
??? private var mStartX = 0
??? private var mStartY = 0
?
??? private val drawRunnable = Runnable {
??????? while (isCanRun) {
?????????? //在這獲取改view的寬度? 如果mStartX超過則歸位 這樣實現反復從頭畫,我這800只是簡單表示下效果
??????????? if (mStartX > 800) {
??????????????? mStartX = 0
??????????? }
??????????? //繪制區域不斷向右變化
??????????? rect!![mStartX, 0, mStartX + 16] = 300
??????????? mCanvas = surfaceHolder!!.lockCanvas(rect) //提交繪制區域
??????????? if (mCanvas == null) return@Runnable
??????????? //很重要,如果反復從頭繪制,會覆蓋上一次的繪制
??????????? mCanvas!!.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR)
??????????? if (ecgDatas.size > 0) {
??????????????? mCanvas!!.drawLine(mStartX.toFloat(), mStartY.toFloat(), (mStartX + 16).toFloat(), ecgDatas[0].toFloat(), mPaint)
??????????????? //這個點的重點是下一個點的起點
??????????????? mStartX = mStartX + 16
??????????????? mStartY = ecgDatas[0]
??????????????? ecgDatas.removeAt(0)
??????????? } else {
??????????????? initData()
??????????? }
??????????? surfaceHolder!!.unlockCanvasAndPost(mCanvas!!) //這種方式把上次繪制的遮蓋了 因此出現了斷點
??????? }
??? }
??? init {
??????? surfaceHolder = this.holder //獲取holder
??????? surfaceHolder!!.addCallback(this)
??????? rect = Rect() //繪制矩陣內
??????? mPaint = Paint()
??????? mPaint!!.setColor(Color.parseColor(line_color)) //畫筆顏色
??????? mPaint!!.setAntiAlias(true) //抗鋸齒
?????? ?mPaint!!.setStrokeWidth(2f)
??????? initData()
??? }
??? private fun initData() {
??????? ecgDatas.clear()
??????? for (i in 0..199) {
??????????? ecgDatas.add((Math.random() * 200).toInt())
??????? }
??????? mStartY = ecgDatas[0]
??? }
??? override fun surfaceCreated(holder: SurfaceHolder?) {
??????? Thread(drawRunnable).start()
??? }
??? override fun surfaceChanged(holder: SurfaceHolder?, format: Int, width: Int, height: Int) {
??? }
??? override fun surfaceDestroyed(holder: SurfaceHolder?) {
?????? ?isCanRun = false
??? }
}
布局直接使用即可:
<cn.appstudy.customView.ECGSurfaceViewJava ??????? android:layout_width="match_parent" ??????? android:layout_height="200dp"/> ? <cn.appstudy.customView.ECGSurfaceViewKotlin android:layout_width="match_parent" android:layout_height="200dp" android:layout_marginTop="220dp" />
上面小空只是簡單寫了下示例,如果是畫心電圖其實還有更多的邏輯,比如多個心電圖同步,比如超出屏幕后回到起始位置,比如實時更新心電圖數據,再比如心電圖速度控制等等。
而且上面心電圖示例是從左到右的,還有可能從上到下,從右到左的等等,更多功能就交給大佬們去開發了。
原文鏈接:https://juejin.cn/post/7111615602845810718
相關推薦
- 2023-01-12 python如何批量讀取.mat文件并保存成.npy_python
- 2022-12-08 C#與C++?dll之間傳遞字符串string?wchar_t*?char*?IntPtr問題_C#
- 2022-06-26 深入解析python返回函數和匿名函數_python
- 2022-01-26 使用Guzzle拓展包請求接口失敗重試
- 2022-06-17 android實現可上下回彈的scrollview_Android
- 2022-05-02 Pyinstaller+Pipenv打包Python文件的實現示例_python
- 2023-01-28 Flutter?Widget移動UI框架使用Material和密匙Key實戰_Android
- 2022-11-14 gorm crud 指南
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支