Android 自定义控件

news2024/12/25 23:38:31

文章目录

    • Canvas 画布类
        •       画布背景
        •       点
        •       线
        •       矩形
        •       椭圆
        •       圆
        •       弧形
        •       路径
        •       字符
        •       对画布裁剪及变形
    • Paint 画笔类
        •       常用方法
        •       图形线条相关
        •       字符相关
        •        Path设置样式

如果是一个自定义控件,则需要派生自 View 或其子类,如果是一个自定义的容器,则需要派生自 ViewGroup 或其子类

Canvas 画布类

凡是要画出成品的东西,比如圆形、矩形、文字等,都调用 Canvas 类里的函数生成

      画布背景

drawColor(int color);			//必须是8位16进制:OxAARRGGBB,否则无作用
drawRGB(int r, int g, int b);	//可10进制 0~255,或16进制 OxOO~OxFF
drawARGB(int a, int r, int g, int b);

      点

// (x,y)绘制点的坐标
drawPoint(float x, float y, Paint);
drawPoints(float[] pts, Paint);		//两个一组组成坐标,pts数组长度必须是二的倍数,例如[x0,y0, x1,y1, x2,y2 …]
//offset 在pts数组中取数值的偏移量,第一个数值为pts[offset]
//count 在pts数组总共取多少个数值,offset+count<=pts.length
drawPoints(float[] pts, int offset, int count, Paint); // 即切割数组,从pts[offset],到pts[offset+count-1],count必须是2的倍数

      线

// (startX,startY)起始点坐标,(endX,endY)终点坐标
drawLine(float startX, float startY, float endX, float endY, Paint);
drawLines(float[] pts, Paint);		//四个一组组成坐标,pts数组长度必须是四的倍数,例如[startX0,startY0,endX0,endY0, startX1,startY1,endX1,endY1 …]
drawLines(float[] pts, int offset, int count, Paint);	// 同上,count必须是四的倍数

      矩形

drawRect(float left, float top, float right, float bottom, Paint);	//可以理解为矩形左上角坐标(left,top) 和右下角坐标(right,bottom)
drawRect(Rect rect, Paint);
drawRect(RectF rectF, Paint);

// 绘制圆角矩形,rx是横向,ry是纵向,单位px,数值越大角越圆
drawRoundRect(float left, float top, float right, float bottom, float rx, float ry, Paint);
drawRoundRect(RectF rectF, float rx, float ry, Paint);
// 构造方法一:
Rect rect = new Rect(10, 10, 100, 100); 
// 构造方法二:
Rect rect = new Rect(); 
rect.set(10, 10, 100, 100) ;
// 构造方法三:
Rect r = new Rect(10, 10, 100, 100);
Rect rect = new Rect(r); 
// RectF 类与上面相同,只是精度不同,精度为float

      椭圆

drawOval(float left, float top, float right, float bottom, Paint); //可以理解为一个矩形,在矩形之中画一个椭圆
drawOval(RectF rect, Paint);

在这里插入图片描述

      圆

// cx和cy是圆的中心,radius是圆的半径
drawCircle(float cx, float cy, float radius, Paint)

      弧形

// startAngle是圆弧开始角度,sweepAngle是圆弧经过的角度,useCenter设置圆弧是否经过中心
// 可以理解为只画出部分椭圆
drawArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle, boolean useCenter, Paint);
drawArc(RectF, float startAngle, float sweepAngle, boolean useCenter, Paint);

在这里插入图片描述

	override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        var paint: Paint = Paint()
        paint.setColor(Color.RED)
        paint.style = Paint.Style.STROKE
        paint.strokeWidth = 10f;

        canvas?.drawArc(10f, 10f, 200f, 100f, 0f, 90f, true, paint)		//经过圆心
        canvas?.drawArc(10f, 150f, 200f, 240f, 45f, 90f, false, paint)	//不经过圆心
        
		paint.style = Paint.Style.FILL
        canvas?.drawArc(200f, 10f, 390f, 100f, 0f, 90f, true, paint)	//经过圆心
        canvas?.drawArc(200f, 150f, 390f, 240f, 45f, 90f, false, paint)	//不经过圆心
    }

      路径

drawPath(Path path, Paint)

Path 类
    1.常用方法

moveTo(float xl , float yl)		//移动画笔到画布对应的坐标
rMoveTo(float dx , float dy)	//相对于上一个画笔的最后一点,移动画笔,等价于上一个画笔位置的偏移量,如果没有上一个画笔位置,则将其视为moveTo()

lineTo(float x, float y)		//从当前画笔位置,绘制一条直线到画布对应坐标(x,y)
rLineTo(float dx, float dy)		//与lineTo相同,相对于当前画笔位置,等价于当前画笔位置为(x0,y0),lineTo(x0+dx, y0+dy)

arcTo(RectF oval, float startAngle, float sweepAngle)	//绘制弧线,参数与画弧线相同
arcTo(RectF oval, float startAngle, float sweepAngle, boolean forceMoveTo)	// forceMoveTo 是否强制地将弧的起始点作为绘制起始
arcTo(float left, float top, float right, float bottom, float startAngle, float sweepAngle, boolean forceMoveTo) //与上面一个方法相同

close(); // 使用 close() 封闭子图形

//Path.Direction.CW 顺时针    Path.Direction.CCW 逆时针
addPath()		//添加另一个路径
addRect()		//添加一个矩形
addRoundRect()	//添加一个圆角矩形
addCircle()		//添加一个圆形
addOval()		//添加一个椭圆
addArc()		//添加一个弧线

quadTo(float x1, float y1, float x2, float y2)							//画二次贝塞尔曲线,两个点的坐标值(x1,y1) (x2,y2)
rQuadTo(float dx1, float dy1, float dx2, float dy2)						//相对坐标
cubicTo(float x1, float y1, float x2, float y2, float x3, float y3) 	//画三次贝塞尔曲线
rCubicTo(float dx1, float dy1, float dx2, float dy2, float dx3, float dy3)	//相对坐标

在这里插入图片描述

	override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        var paint: Paint = Paint()
        paint.setColor(Color.RED)
        paint.style = Paint.Style.STROKE
        paint.strokeWidth = 10f;

        var path: Path = Path()
        path.moveTo(10f, 10f)

		// forceMoveTo = true
        path.addArc(30f, 30f, 200f, 200f, -225f, 225f);
        path.arcTo(400f, 200f, 600f, 400f, -180f, 225f, true);

		// forceMoveTo = false
        path.addArc(30f, 230f, 200f, 400f, -225f, 225f);
        path.arcTo(400f, 400f, 600f, 600f, -180f, 225f, false);
        
        canvas?.drawPath(path,paint)
    }

    2.FillType属性

setFillType(Path.FillType);

有四种类型 Path.FillType.WINDINGPath.FillType.EVEN_ODDPath.FillType.INVERSE_WINDINGPath.FillType.INVERSE_EVEN_ODD
在这里插入图片描述

	override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        paint: Paint = Paint()
        paint.setColor(Color.RED)
        paint.style = Paint.Style.FILL
        paint.strokeWidth = 1f;

		//Path.Direction.CW 顺时针    Path.Direction.CCW 逆时针 
        var path: Path = Path()
        path.addCircle(200f, 200f, 100f, Path.Direction.CW)		//方向相同
        path.addCircle(300f, 200f, 100f, Path.Direction.CW)
        path.fillType = Path.FillType.WINDING
        canvas?.drawPath(path, paint)

        var path2: Path = Path()
        path2.addCircle(200f, 460f, 100f, Path.Direction.CW)	//方向不同
        path2.addCircle(300f, 460f, 100f, Path.Direction.CCW)
        path2.fillType = Path.FillType.WINDING
        canvas?.drawPath(path2, paint)
    }

    2.op方法

op(Path path1, Path path2, Op op)
/** Op 的值有
Path.Op.DIFFERENCE 				path1 减去 path2 的区域
Path.Op.INTERSECT				留下 path2 和 path2 相交的区域
Path.Op.UNION					path1 和 path2 的并集
Path.Op.XOR						包含 path1 和 path2 但不包含相交的部分
Path.Op.REVERSE_DIFFERENCE		path2 减去 path1 的区域
**/

在这里插入图片描述

	override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        paint: Paint = Paint()
        paint.setColor(Color.RED)
        paint.style = Paint.Style.FILL
        paint.strokeWidth = 1f;

        var path: Path = Path()
        path.addCircle(200f, 200f, 100f, Path.Direction.CW)

        var path2: Path = Path()
        path2.addCircle(300f, 200f, 100f, Path.Direction.CW)

        path.op(path2, Path.Op.REVERSE_DIFFERENCE)
        canvas?.drawPath(path, paint)
//        canvas?.drawPath(path2, paint)  //注意不要在绘制path2了,op方法已经将path2的图像合并到path中了
    }

      字符

drawText(String text, float x, float y, Paint);
drawText(String text, int start, int end, float x, float y, Paint);		//只画出字符串text的部分text[start]~text[end]
drawText(CharSequence text, int start, int end, float x, float y, Paint);//同上
drawText(char[] text, int index, int count, float x, float y, Paint);	//同样之画出部分,count不是结束位置,而是取出多少个字符index+count<=text.length

// hOffset与路径起始点的水平偏移距离,vOffset与路径中心点的垂直偏移量 
drawTextOnPath(String text, Path path, float hOffset, float vOffset, Paint);
drawTextOnPath(char[] text, int index, int count, Path path, float hOffset, float vOffset, Paint);

注意:x的位置跟文字对齐方式有关(通过设置画笔的 setTextAlign() 方法指定,默认为left)
           y的位置是基准线Baseline
在这里插入图片描述
通过这些来获取这些线的 y 的值

		Paint.FontMetrics fontMetrics=paint.getFontMetrics();
        // 注意:获取的值都是相对于Baseline的偏移量
        fontMetrics.top			//注意是负数,是相对于Baseline的偏移量
        fontMetrics.ascent
        fontMetrics.descent
        fontMetrics.bottom

在这里插入图片描述
由上图清晰得出,基线相对于文字中心点的偏移量为:

//偏移量
float distance = (fontMetrics.bottom - fontMetrics.top)/2 - fontMetrics.bottom;

在这里插入图片描述

	override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        paint = Paint()
        paint.setColor(Color.RED)
        paint.style = Paint.Style.FILL
        paint.strokeWidth = 1f;
        paint.textSize = 36f

        var path: Path = Path()
        path.moveTo(10f, 10f)
        path.lineTo(300f, 300f)

        canvas?.drawTextOnPath("Hello zwt!Hello zwt!", path, 0f ,0f ,paint)
        canvas?.drawTextOnPath("Hello zwt!Hello zwt!", path, 110f ,60f ,paint)

        paint.color = Color.YELLOW
        paint.style = Paint.Style.STROKE
        paint.strokeWidth = 1f;
        canvas?.drawPath(path ,paint)	//画出路径

        var path1: Path = Path()
        path1.arcTo(400f, 400f, 600f, 600f, 180f, 180f, false);

        canvas?.drawPath(path1 ,paint)	//画出路径

        paint.color = Color.RED
        paint.style = Paint.Style.FILL
        canvas?.drawTextOnPath("Hello zwt!Hello zwt!", path1, 0f ,-60f ,paint)
    }

      对画布裁剪及变形

save()		//将当前Canvas状态进行保存,会有一个int类型返回值
restore()	//将Canvas还原成最近的一个save()的状态
restoreToCount(int saveCount)	//将Canvas还原成某一个特定的save()状态, saveCount为调用save()所返回的数值
//平移
translate(float dx, float dy)
//旋转
rotate(float degrees) //以(0, 0)为原点
rotate(float degrees, float px, float py) //以(px, py)为原点
//斜切
skew(float sx, float sy) //sx,sy倾斜角度的tan值
//缩放
scale(float sx, float sy)
scale(float sx, float sy, float px, float py)
//裁剪
clipPath(Path path)					// DIFFERENCE
clipPath(Path path, Region.Op op) 	// 已弃用,功能与Path的op方法相同
clipOutPath(Path path)				//INTERSECT

在这里插入图片描述

	override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        paint: Paint = Paint()
        paint.setColor(Color.RED)
        paint.style = Paint.Style.FILL
        paint.strokeWidth = 1f;

        /*****************平移********************/
        canvas?.drawRect(10f,10f, 500f, 300f, paint)
        canvas?.translate(100f, 100f)
        paint.setARGB(180, 255, 255, 0)	//设置为黄色透明
        canvas?.drawRect(10f,10f, 500f, 300f, paint)


        /*****************旋转********************/
//        canvas?.save()      // 保存画布状态
//        canvas?.drawRect(10f,10f, 500f, 300f, paint)
//
//        canvas?.rotate(45f) // 以(0,0)点旋转45°
//        paint.setARGB(180, 255, 255, 0)
//        canvas?.drawRect(10f,10f, 500f, 300f, paint)
//
//        canvas?.restore()   //恢复画布状态
//        canvas?.rotate(90f, 250f, 150f) // 以(250,150)点旋转90°
//        paint.setARGB(180, 255, 0, 255)
//        canvas?.drawRect(10f,10f, 500f, 300f, paint)


        /*****************斜切********************/
//        canvas?.save()      // 保存画布状态
//        canvas?.drawRect(10f,10f, 500f, 300f, paint)
//
//        canvas?.skew(1f, 0f)    // tan45° = 1,即斜切45°
//        paint.setARGB(180, 255, 255, 0)
//        canvas?.drawRect(10f,10f, 500f, 300f, paint)
//
//        canvas?.restore()   //恢复画布状态
//        canvas?.skew(0f, 1f)
//        paint.setARGB(180, 255, 0, 255)
//        canvas?.drawRect(10f,10f, 500f, 300f, paint)


        /*****************缩放********************/
//        canvas?.drawRect(10f,10f, 500f, 300f, paint)
//
//        canvas?.scale(0.5f, 2f); // 宽度变为原来的一半,高度变为两倍
//        paint.setARGB(180, 255, 255, 0)
//        canvas?.drawRect(10f,10f, 500f, 300f, paint)
    }

Paint 画笔类

凡是跟画笔相关的设置,比如画笔的大小、粗细、颜色、透明度、字体样式等

      常用方法

setColor(int):设置画笔的颜色
setAlpha(int):设置画笔的透明度
setARGB(int a, int r, int g, int b):设置画笔的颜色,a代表透明度,r,g,b代表颜色值
setStrokeWidth(int):设置画笔的线宽
setAntiAlias(boolean):设置是否使用抗锯齿功能,设置后会平滑一些,但绘制速度会变慢
setDither(boolean):设定是否使用图像抖动处理,设置后图像更加清晰,但绘制速度会变慢
setStyle(Style):设置画笔的风格,Style.FILL 实心 Style.STROKE 空心 Style.FILL_AND_STROKE 同时显示实心和空心
在这里插入图片描述

	override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        var paint: Paint = Paint()
        paint.setColor(Color.RED)
        paint.strokeWidth = 50f;

        paint.style = Paint.Style.STROKE
        canvas?.drawCircle(150f, 300f, 75f, paint);
        paint.style = Paint.Style.FILL
        canvas?.drawCircle(350f, 300f, 75f, paint);
        paint.style = Paint.Style.FILL_AND_STROKE
        canvas?.drawCircle(550f, 300f, 75f, paint);

        paint.style = Paint.Style.FILL
        canvas?.drawCircle(800f, 300f, 75f, paint)
        paint.setARGB(128, 39, 117, 172)	//约50%的透明度
        paint.style = Paint.Style.STROKE
        canvas?.drawCircle(800f, 300f, 75f, paint)
    }

      图形线条相关

setStrokeCap(Cap):设置画笔的线帽Paint.Cap.BUTT无线帽、Paint.Join.ROUND圆形、Paint.Join.BEVEL方形
setStrokeJoin(Join):设置连接Paint.Join.MITER锐角、Paint.Join.ROUND圆弧、Paint.Join.BEVEL直线
在这里插入图片描述

	override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        paint: Paint = Paint()
        paint.setColor(Color.RED)
        paint.style = Paint.Style.STROKE
        paint.strokeWidth = 50f;

        paint.setStrokeCap(Paint.Cap.BUTT);
        canvas?.drawLine(100f, 100f, 500f, 100f, paint);

        paint.setStrokeCap(Paint.Cap.ROUND);
        canvas?.drawLine(100f, 200f, 500f, 200f, paint);

        paint.setStrokeCap(Paint.Cap.SQUARE);
        canvas?.drawLine(100f, 300f, 500f, 300f, paint);

    }

在这里插入图片描述

	override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        paint: Paint = Paint()
        paint.setColor(Color.RED)
        paint.style = Paint.Style.STROKE
        paint.strokeWidth = 50f;

        var path: Path = Path()
        path.moveTo(100f,100f)
        path.rLineTo(500f,0f)
        path.rLineTo(-200f,200f)

		paint.strokeJoin = Paint.Join.MITER
//		paint.strokeJoin = Paint.Join.ROUND
//      paint.strokeJoin = Paint.Join.BEVEL
        canvas?.drawPath(path, paint)
    }

      字符相关

setTextSize(int):设置字体大小
setFakeBoldText(boolean):设置文本仿粗体
setUnderlineText(boolean):设置文字的下划线
setTextSkewX(float):设置斜体字,值为负右倾值为正左倾
setStrikeThruText(boolean):设置文本删除线
setTextScaleX(float):文本沿X轴水平缩放,默认值为1
setLetterSpacing(float):设置行的间距
setShadowLayer(float radius, float dx, float dy, int shadowColor):设置阴影效果,radius为阴影角度,dx和dy为阴影在x轴和y轴上的距离,color为阴影的颜色
setTypeface(Typeface):设置文本字体样式
setTextAlign(Paint.Align):设置字体方向,对其方式,Paint.Align.LEFTPaint.Align.RIGHTPaint.Align.CENTER

       Path设置样式

setPathEffect(PathEffect):设置Path样式
      CornerPathEffect(float radius):圆滑,radius转折角度,越大越圆滑
      DashPathEffect(float intervals[], float phase):虚线:intervals[]指定虚实线长度,phase指定偏移量
      PathDashPathEffect(Path shape, float advance, float phase, Style style):自定义效果,shape定义路径填充的样式,advance是每个图形之间的间距,phase指定偏移量,style分为ROTATE、MORPH和TRANSLATE
      DiscretePathEffect(float segmentLength, float deviation):打散效果,segmentLength指定最大的段长,deviation则为绘制时的偏离量
在这里插入图片描述

	override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        paint: Paint = Paint()
        paint.setColor(Color.RED)
        paint.style = Paint.Style.STROKE
        paint.strokeWidth = 3f;

        var mPhase: Float = 5f //偏移量

        var path: Path = Path()
        path.moveTo(100f,100f)
        path.rLineTo(100f,100f)
        path.rLineTo(200f,-50f)
        path.rLineTo(50f,20f)
        path.rLineTo(100f,-60f)
        path.rLineTo(100f,80f)

        paint.pathEffect = null
        canvas?.drawPath(path, paint)

        var path1: Path = Path()
        path1.moveTo(100f,200f)
        path1.rLineTo(100f,100f)
        path1.rLineTo(200f,-50f)
        path1.rLineTo(50f,20f)
        path1.rLineTo(100f,-60f)
        path1.rLineTo(100f,80f)
        paint.pathEffect = CornerPathEffect(25f)  //圆滑
        canvas?.drawPath(path1, paint)

        var path2: Path = Path()
        path2.moveTo(100f,300f)
        path2.rLineTo(100f,100f)
        path2.rLineTo(200f,-50f)
        path2.rLineTo(50f,20f)
        path2.rLineTo(100f,-60f)
        path2.rLineTo(100f,80f)
        paint.pathEffect = DashPathEffect(floatArrayOf(20f, 5f, 10f, 5f), mPhase)  //圆滑
        canvas?.drawPath(path2, paint)

        var path3: Path = Path()
        path3.moveTo(100f,400f)
        path3.rLineTo(100f,100f)
        path3.rLineTo(200f,-50f)
        path3.rLineTo(50f,20f)
        path3.rLineTo(100f,-60f)
        path3.rLineTo(100f,80f)
        var shape: Path = Path()
        shape.addCircle(0f, 0f, 3f, Path.Direction.CW);
        paint.pathEffect = PathDashPathEffect(shape, 12f, mPhase, PathDashPathEffect.Style.ROTATE)
        canvas?.drawPath(path3, paint)

        var path4: Path = Path()
        path4.moveTo(100f,500f)
        path4.rLineTo(100f,100f)
        path4.rLineTo(200f,-50f)
        path4.rLineTo(50f,20f)
        path4.rLineTo(100f,-60f)
        path4.rLineTo(100f,80f)
        paint.pathEffect = DiscretePathEffect(5.0f, mPhase)
        canvas?.drawPath(path4, paint)
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/197159.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Vue】模板语法——内置指令

指令&#xff08;Directives&#xff09;是 vue 为开发者提供的模板语法&#xff0c;用于辅助开发者渲染页面的基本结构。vue 中的指令按照不同的用途可以分为如下几大类&#xff1a;① 内容渲染指令&#xff1a;v-text、v-html② 属性绑定指令&#xff1a;v-bind③ 事件绑定指…

<Java EE 进阶> 3.Spring简单的读和取

目录 1.存储Bean对象 &#xff08;1&#xff09;准备工作&#xff1a;配置扫描路径 &#xff08;2&#xff09;添加注解存储Bean对象 ① 类注解 ② 方法注解Bean 在String中更简单的存储和读取对象的核心是使用注解 1.存储Bean对象 &#xff08;1&#xff09;准备工作&am…

Linux内核的安装与加载

目录 一、tftp加载Linux内核和roootfs 二、 EMMC加载Linux内核和rootfs 三、tftp加载Linux内核nfs挂在根文件系统 四、EMMC加载uboot 一、tftp加载Linux内核和roootfs 这个就是Linux内核&#xff0c;它很轻量级只有2.949MB所以在嵌入式领域很受欢迎。 上面那个就是设备树文…

初识 Python 科学计算库之 NumPy(创建多维数组对象)

文章目录参考描述NumPy特点获取导入多维数组对象np.array()np.asarray()范围随机概览np.random.randn()np.random.normal()np.random.choice()np.random.random()np.random.randint()np.random.shuffle()np.random.seed()数列等差数列等比数列填充np.zeros()np.zeros_like()np.…

Spotify Q4用户增长再超预期,但为何还是赚不到钱?

2022年&#xff0c;美联储接连7次暴力加息&#xff0c;科技行业整体低迷&#xff0c;从Meta、Google再到亚马逊&#xff0c;大型科技公司接连宣告裁员过冬。 寒气已经传递到了更广阔的地方。1月下旬&#xff0c;瑞典音乐流媒体巨头Spotify宣布将裁员6%。 音乐流媒体的生意变得…

Python自动化测试实战篇(1)读取xlsx中账户密码,unittest框架实现通过requests接口post登录网站请求,JSON判断登录是否成功

Python接口项目实战篇&#xff08;1&#xff09;读取xlsx中账户密码&#xff0c;unittest框架实现通过requests接口post登录网站请求&#xff0c;JSON判断登录是否成功实现功能描述1.首先获取到接口谷歌浏览器中获取接口信息fiddler里面抓取接口信息2.创建一个xlsx文档3.导入我…

【C++】继承详解

目录继承的概念及定义继承的概念继承的定义定义格式继承关系和访问限定符继承基类成员访问方式的变化基类和派生类对象的赋值转换继承中的作用域派生类的默认成员函数继承和友元继承与静态成员复杂的菱形继承及菱形的虚拟继承菱形继承的概念虚拟继承**虚拟继承的原理**&#xf…

IT6512可编程直流电源的工作原理

现在各种的电子设备不断的发展&#xff0c;它们对直流供电的电源也有了更高的要求&#xff0c;相对于电子设备来说&#xff0c;用单一的直流电源是没有办法达到供电的要求&#xff0c;所以需要不同的直流电源来给电子设备供电。可编程直流电源就是这一种。在生产测试中&#xf…

Pandas的apply, map, transform介绍和性能测试

apply函数是我们经常用到的一个Pandas操作。虽然这在较小的数据集上不是问题&#xff0c;但在处理大量数据时&#xff0c;由此引起的性能问题会变得更加明显。虽然apply的灵活性使其成为一个简单的选择&#xff0c;但本文介绍了其他Pandas函数作为潜在的替代方案。 在这篇文章…

软测(基础)· 软件测试的生命周期 · 如何描述一个 Bug · Bug 的级别 · Bug 的生命周期 · 争执 · Bug 评审

一、软件测试的生命周期软件测试的生命周期 & 软件开发的生命周期二、如何描述一个 Bug三、如何定义 Bug 的级别四、Bug 的生命周期五、发生争执了怎么办&#xff1f;Bug 评审一、软件测试的生命周期 软件测试的生命周期&#xff1a;需求分析 → 测试计划 → 测试设计、测…

《巫师3:狂猎》4.01版更新 PC端已上线

去年12月&#xff0c;《巫师3》免费升级次世代版&#xff0c;加入DLSS 3支持&#xff0c;RTX 40系显卡的用户能直接提升体验感&#xff0c;RTX 30系用户能通过DLSS 2获得更稳定的帧数。 目前。《巫师3&#xff1a;狂猎》4.01版已更新上线&#xff0c;在PC、PlayStation 和 Xbo…

【配电网规划】配电网N-1扩展规划研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

OJ万题详解––[NOIP2010 提高组] 机器翻译(C++详解)

题目背景 小晨的电脑上安装了一个机器翻译软件&#xff0c;他经常用这个软件来翻译英语文章。 题目描述 这个翻译软件的原理很简单&#xff0c;它只是从头到尾&#xff0c;依次将每个英文单词用对应的中文含义来替换。对于每个英文单词&#xff0c;软件会先在内存中查找这个单词…

openstack cinder对接两个ceph后端配置

需求 需要做卷迁移的工作&#xff0c;从一个ceph集群迁移到另一个集群&#xff0c;因此需要配置两个ceph后端。由此开展后续工作&#xff0c;将配置过程及出现的问题做一记录。 另外两套ceph后端的访问用户都是cinder用户&#xff0c;网上找的资料均为两个用户&#xff0c;当为…

电子技术——BJT的物理结构

电子技术——BJT的物理结构 本节我们介绍另一种基本三端元件&#xff0c;BJT。 物理结构 下图展示了NPN型和PNP型BJT的物理结构简图。 从图中看出&#xff0c;BJT主要由三个区域组成&#xff0c;发射极&#xff08;n类型&#xff09;&#xff0c;基极&#xff08;p类型&#…

如何跑起一个Python Flask 项目

最近做项目迁移&#xff0c;从Google cloud 迁移到 AWS项目&#xff1a;Python Flask ORM是Alembic(我不是搞python的 这边看到这个了)python 是docker 跑起来的&#xff0c;一个docker-compose up就完事但我要进行数据库迁移测试&#xff0c;所以本地要跑起来我是mac先安装pyt…

财报解读:大裁员后Meta的元宇宙还有新故事吗?

美股科技巨头Facebook自更名为Meta Platforms后全面发力元宇宙&#xff0c;作为美国第一大社交平台以及全球流量池&#xff0c;转型后的Meta一度被市场寄予厚望&#xff0c;但同样受累于其元宇宙策略&#xff0c;年初至今&#xff0c;Meta的股价累计一度下跌近65%&#xff0c;也…

【超详细】一文看懂如何在PyCharm中集成Git

PyCharm环境集成Git 当我们在官网下载好Git后&#xff0c;按照要求进行安装&#xff0c;就可以通过快捷方式对本地仓库进行版本控制啦。但是这种方式处理整个工作环境还是比较麻烦的&#xff0c;接下来&#xff0c;我们将在PyCharm环境中配置Git。 基础配置 在设置中&#xf…

IPV6基本了解

参考&#xff1a;https://support.huawei.com/enterprise/zh/doc/EDOC1100116138#ZH-CN_TOPIC_0204809629&#xff0c; https://www.w3cschool.cn/ipv6/ipv6_address_types.html IPv6地址结构 和IPv4的10进制的表示方式不同&#xff0c;IPv6使用的是16进制的表示方式。 首先基…

FreeRTOS内存管理

内存管理是一个系统基本组成部分&#xff0c;FreeRTOS 中大量使用到了内存管理&#xff0c;比 如创建任务、信号量、队列等会自动从堆中申请内存。用户应用层代码也可以使 用 FreeRTOS 提供的内存管理函数来申请和释放内存。本章要实现的功能是&#xff1a;使 用 heap_4.c 方案…