Android修行手册 - TextureView和SurfaceView的属性方法以及示例
- 点击跳转=>《导航贴》- Unity手册,系统实战学习
- 点击跳转=>《导航贴》- Android手册,重温移动开发
本文约8.6千字,新手阅读需要11分钟,复习需要4分钟 【收藏随时查阅不再迷路】
👉关于作者
众所周知,人生是一个漫长的流程,不断克服困难,不断反思前进的过程。在这个过程中会产生很多对于人生的质疑和思考,于是我决定将自己的思考,经验和故事全部分享出来,以此寻找共鸣 !!!
专注于Android/Unity和各种游戏开发技巧,以及各种资源分享(网站、工具、素材、源码、游戏等)
有什么需要欢迎私我,交流群让学习不再孤单。
👉前提
这是小空坚持写的Android新手向系列,欢迎品尝。
大佬(√)
新手(√√√)
👉实践过程
😜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版本自定义
/*** Created by akitaka on 2022-06-20.** @author akitaka* @filename ECGSurfaceView* @describe 绘制心电图案例,注意里面的数字都是测试临时写的,真实的功能一定是适配的动态变量值* @email 960576866@qq.com*/
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/sprivate int sleepTime = 8;//每次锁屏的时间间距,单位ms 连线的时间长度,,如果大则会卡顿效果private SurfaceHolder surfaceHolder;private boolean isCanRun = true;private int mStartX = 0;private int mStartY = 0;private Runnable drawRunnable = new Runnable() {@Overridepublic 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();//获取holderthis.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);}@Overridepublic void surfaceCreated(SurfaceHolder holder) {new Thread(drawRunnable).start();}@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {}@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {isCanRun = false;}
}
Kotlin版本自定义
/*** Created by akitaka on 2022-06-20.* @author akitaka* @filename ECGSurfaceViewKotlin* @describe* @email 960576866@qq.com*/
class ECGSurfaceViewKotlin(context: Context?, attrs: AttributeSet?) : SurfaceView(context, attrs), SurfaceHolder.Callback {//简单模拟一下数据var ecgDatas: MutableList<Int> = ArrayList()//矩阵 画布 画笔 颜色private var rect: Rect? = nullprivate var mCanvas: Canvas? = null//画波形的画笔private var mPaint: Paint? = nullprivate val line_color = "#01FC00" //画笔默认是绿色的private val wave_speed = 30 //定义波速:30mm/sprivate val sleepTime = 8 //每次锁屏的时间间距,单位ms 连线的时间长度,,如果大则会卡顿效果var surfaceHolder: SurfaceHolder? = nullprivate var isCanRun = trueprivate var mStartX = 0private var mStartY = 0private val drawRunnable = Runnable {while (isCanRun) {//在这获取改view的宽度 如果mStartX超过则归位 这样实现反复从头画,我这800只是简单表示下效果if (mStartX > 800) {mStartX = 0}//绘制区域不断向右变化rect!![mStartX, 0, mStartX + 16] = 300mCanvas = 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 + 16mStartY = ecgDatas[0]ecgDatas.removeAt(0)} else {initData()}surfaceHolder!!.unlockCanvasAndPost(mCanvas!!) //这种方式把上次绘制的遮盖了 因此出现了断点}}init {surfaceHolder = this.holder //获取holdersurfaceHolder!!.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.ECGSurfaceViewJavaandroid:layout_width="match_parent"android:layout_height="200dp"/><cn.appstudy.customView.ECGSurfaceViewKotlinandroid:layout_width="match_parent"android:layout_height="200dp"android:layout_marginTop="220dp" />
上面小空只是简单写了下示例,如果是画心电图其实还有更多的逻辑,比如多个心电图同步,比如超出屏幕后回到起始位置,比如实时更新心电图数据,再比如心电图速度控制等等。
而且上面心电图示例是从左到右的,还有可能从上到下,从右到左的等等,更多功能就交给大佬们去开发了。
👉其他
📢作者:小空和小芝中的小空
📢转载说明-务必注明来源:https://zhima.blog.csdn.net/
📢这位道友请留步☁️,我观你气度不凡,谈吐间隐隐有王者霸气💚,日后定有一番大作为📝!!!旁边有点赞👍收藏🌟今日传你,点了吧,未来你成功☀️,我分文不取,若不成功⚡️,也好回来找我。
温馨提示:点击下方卡片获取更多意想不到的资源。