当前位置: 首页 > news >正文

Android自定义View实现打钩签到动画

效果图

实现原理

我们看实现的动画效果,其实是分为

1. 绘制未选中状态图形(圆弧和对号)

2. 绘制选中状态圆弧的旋转的动画

3. 绘制选中状态圆弧向中心收缩铺满动画

4. 绘制选中状态对号

5. 绘制选中状态下圆的放大回弹动画

6. 暴露接口接口回调传递选中未选中状态

我们一步一步来实现

首先我们完成准备工作自定义属性attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources><declare-styleable name="CustomTickView"><!--选中情况下基本颜色--><attr name="check_base_color" format="color" /><!--选中情况下对号颜色--><attr name="check_tick_color" format="color" /><!--未选中情况下基本颜色--><attr name="uncheck_base_color" format="color" /><!--未选中情况下对号颜色--><attr name="uncheck_tick_color" format="color" /><!--自定义动画执行时间--><attr name="custom_duration" format="integer" /><!--控件大小--><attr name="custom_size" format="dimension" /></declare-styleable>
</resources>

获取自定义属性并初始化画笔

private int mCustomSize;//画布大小private int mRadius;private int mCheckBaseColor;//选中状态基本颜色private int mCheckTickColor;//选中状态对号颜色private int mUnCheckTickColor;//未选中状态对号颜色private int mUnCheckBaseColor;//未选中状态基本颜色private Paint mCheckPaint;//选中状态画笔 下面的背景圆private Paint mCheckArcPaint;//选中状态画笔 下面的背景圆圆弧private Paint mCheckDeclinePaint;//选中状态画笔  (上面的随动画缩减的圆盖在上面)  和对号private Paint mUnCheckPaint;//未选中状态画笔private Paint mCheckTickPaint;//选中对号画笔private Paint mCheckPaintArc;//回弹圆画笔 设置不同宽度已达到回弹圆动画目的private boolean isCheckd = false;//选中状态private float[] mPoints;private int mCenter;
/*** 获取自定义属性** @param context* @param attrs*/private void initAttrs(Context context, AttributeSet attrs) {TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CustomTickView);mCustomSize = (int) typedArray.getDimension(R.styleable.CustomTickView_custom_size, dip2px(130));mCheckBaseColor = typedArray.getColor(R.styleable.CustomTickView_check_base_color, mCheckBaseColor);mCheckTickColor = typedArray.getColor(R.styleable.CustomTickView_check_tick_color, mCheckTickColor);mUnCheckBaseColor = typedArray.getColor(R.styleable.CustomTickView_uncheck_base_color, mUnCheckBaseColor);mUnCheckTickColor = typedArray.getColor(R.styleable.CustomTickView_uncheck_tick_color, mUnCheckTickColor);typedArray.recycle();mCenter = mCustomSize / 2;mRadius = mCenter - 50;//缩小圆半径大小 防止回弹动画弹出画布}
/**** 初始化画笔*/private void initPaint() {mCheckPaint = new Paint();mCheckPaint.setAntiAlias(true);mCheckPaint.setColor(mCheckBaseColor);mCheckPaintArc = new Paint();mCheckPaintArc.setAntiAlias(true);mCheckPaintArc.setColor(mCheckBaseColor);mCheckArcPaint = new Paint();mCheckArcPaint.setAntiAlias(true);mCheckArcPaint.setColor(mCheckBaseColor);mCheckArcPaint.setStyle(Paint.Style.STROKE);mCheckArcPaint.setStrokeWidth(20);mCheckDeclinePaint = new Paint();mCheckDeclinePaint.setAntiAlias(true);mCheckDeclinePaint.setColor(Color.parseColor("#3E3E3E"));mUnCheckPaint = new Paint();mUnCheckPaint.setAntiAlias(true);mUnCheckPaint.setColor(mUnCheckBaseColor);mUnCheckPaint.setStyle(Paint.Style.STROKE);mUnCheckPaint.setStrokeWidth(20);mCheckTickPaint = new Paint();mCheckTickPaint.setAntiAlias(true);mCheckTickPaint.setColor(mCheckTickColor);mCheckTickPaint.setStyle(Paint.Style.STROKE);mCheckTickPaint.setStrokeWidth(20);}

测量布局

    @Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {setMeasuredDimension(mCustomSize, mCustomSize);//正方形布局长宽一致}

准备工作完成,接下来我们按照刚才的步骤一步一步实现

1. 绘制未选中状态图形(圆弧和对号)


@Overrideprotected void onDraw(Canvas canvas) {if (mCustomSize > 0) {if (!isCheckd) {canvas.drawCircle(mCenter, mCenter, mRadius, mUnCheckPaint);//未选中状态的圆canvas.drawLines(mPoints, mUnCheckPaint);return;}}    }

2. 绘制选中状态圆弧的旋转的动画


    @Overrideprotected void onDraw(Canvas canvas) {//省略以上代码mRingCounter += 10;//按照如下速率转动if (mRingCounter >= 360) {mRingCounter = 360;}canvas.drawArc(mRectF, 90, mRingCounter, false, mCheckArcPaint);}

3. 绘制选中状态圆弧向中心收缩铺满动画


这里向中心收缩的动画我们可以逆向思维

先绘制指定颜色的整体圆,然后在指定颜色整体圆的图层上在绘制一个背景色的圆(半径不断缩小) 半径不断缩小,背景就不断露出来,达到向中心收缩的效果。

    @Overrideprotected void onDraw(Canvas canvas) {//省略以上代码if (mRingCounter == 360) {//先绘制指定颜色的圆canvas.drawCircle(mCenter, mCenter, mRadius, mCheckPaint);//然后在指定颜色的图层上,再绘制背景色的圆(半径不断缩小) 半径不断缩小,背景就不断露出来,达到向中心收缩的效果mCircleCounter += 10;canvas.drawCircle(mCenter, mCenter, mRadius - mCircleCounter, mCheckDeclinePaint);        }

4. 绘制选中状态对号


我们让对号出现的有延迟效果并加上透明出现的效果

        @Overrideprotected void onDraw(Canvas canvas) {//省略以上代码if (mCircleCounter >= mRadius + 100) {//做延迟效果mAlphaCount += 20;if (mAlphaCount >= 255) mAlphaCount = 255; //显示对号(外加一个透明的渐变)mCheckTickPaint.setAlpha(mAlphaCount);//设置透明度//画白色的对号canvas.drawLines(mPoints, mCheckTickPaint);}}

5. 绘制选中状态下圆的放大回弹动画


这里我们的实现思路是在整体圆图层上在画一个圆弧,圆弧的宽度由增大到缩小最后直至为0,这样达到放大回弹的效果

    @Overrideprotected void onDraw(Canvas canvas) {if (mCustomSize > 0) {if (!isCheckd) {canvas.drawCircle(mCenter, mCenter, mRadius, mUnCheckPaint);//未选中状态的圆canvas.drawLines(mPoints, mUnCheckPaint);return;}mRingCounter += 10;if (mRingCounter >= 360) {mRingCounter = 360;}canvas.drawArc(mRectF, 90, mRingCounter, false, mCheckArcPaint);if (mRingCounter == 360) {//先绘制指定颜色的圆canvas.drawCircle(mCenter, mCenter, mRadius, mCheckPaint);//然后在指定颜色的图层上,再绘制背景色的圆(半径不断缩小) 半径不断缩小,背景就不断露出来,达到向中心收缩的效果mCircleCounter += 10;canvas.drawCircle(mCenter, mCenter, mRadius - mCircleCounter, mCheckDeclinePaint);if (mCircleCounter >= mRadius + 100) {mAlphaCount += 20;if (mAlphaCount >= 255) mAlphaCount = 255; //显示对号(外加一个透明的渐变)mCheckTickPaint.setAlpha(mAlphaCount);//设置透明度//画白色的对号canvas.drawLines(mPoints, mCheckTickPaint);scaleCounter -= 4;//获取是否回弹if (scaleCounter <= -50) {//scaleCounter从大于0到小于0的过程中 画笔宽度也是由增加到减少最后减为0 实现了圆放大收缩的回弹效果scaleCounter = -50;}//放大并回弹,设置画笔的宽度float strokeWith = mCheckArcPaint.getStrokeWidth() +(scaleCounter > 0 ? 6 : -6);System.out.println(strokeWith);mCheckArcPaint.setStrokeWidth(strokeWith);canvas.drawArc(mRectArc, 90, 360, false, mCheckArcPaint);}}postInvalidate();//重绘}}

以上我们就实现了所有的动画效果 下面我们需要定义接口并暴露接口

6. 暴露接口接口回调传递选中未选中状态


    /*** 初始化点击事件*/public void setUpEvent() {this.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View view) {isCheckd = !isCheckd;reset();if (mOnCheckedChangeListener != null) {//此处回调mOnCheckedChangeListener.onCheckedChanged((CustomTickView) view, isCheckd);}}});}private OnCheckedChangeListener mOnCheckedChangeListener;public interface OnCheckedChangeListener {void onCheckedChanged(CustomTickView tickView, boolean isCheckd);}public void setOnCheckedChangeListener(OnCheckedChangeListener listener) {this.mOnCheckedChangeListener = listener;}

现在我们就可以通过点击自定义控件实现动画并且接受选中状态

customTickView.setUpEvent();//运行动画customTickView.setOnCheckedChangeListener(new CustomTickView.OnCheckedChangeListener() {@Overridepublic void onCheckedChanged(CustomTickView tickView, boolean isCheckd) {if(!isCheckd){tv_show.setText("未完成签到");}else{tv_show.setText("已签到");}}});

完整代码

CustomTickView.java

public class CustomTickView extends View {private int mCustomSize;//画布大小private int mRadius;private int mCheckBaseColor;//选中状态基本颜色private int mCheckTickColor;//选中状态对号颜色private int mUnCheckTickColor;//未选中状态对号颜色private int mUnCheckBaseColor;//未选中状态基本颜色private Paint mCheckPaint;//选中状态画笔 下面的背景圆private Paint mCheckArcPaint;//选中状态画笔 下面的背景圆圆弧private Paint mCheckDeclinePaint;//选中状态画笔  (上面的随动画缩减的圆盖在上面)  和对号private Paint mUnCheckPaint;//未选中状态画笔private Paint mCheckTickPaint;//选中对号画笔private Paint mCheckPaintArc;//回弹圆画笔 设置不同宽度已达到回弹圆动画目的private boolean isCheckd = false;//选中状态private float[] mPoints;private int mCenter;private RectF mRectF;private int mRingCounter;private int mCircleCounter = 0;//盖在上面的背景色圆逐渐缩小  逆向思维模拟向圆心收缩动画private int mAlphaCount = 0;private int scaleCounter = 50;private RectF mRectArc;public CustomTickView(Context context) {super(context);}public CustomTickView(Context context, @Nullable AttributeSet attrs) {super(context, attrs);initAttrs(context, attrs);//获取自定义属性initPaint();//初始化画笔}public CustomTickView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, 0);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {setMeasuredDimension(mCustomSize, mCustomSize);}@Overrideprotected void onDraw(Canvas canvas) {if (mCustomSize > 0) {if (!isCheckd) {canvas.drawCircle(mCenter, mCenter, mRadius, mUnCheckPaint);//未选中状态的圆canvas.drawLines(mPoints, mUnCheckPaint);return;}mRingCounter += 10;if (mRingCounter >= 360) {mRingCounter = 360;}canvas.drawArc(mRectF, 90, mRingCounter, false, mCheckArcPaint);if (mRingCounter == 360) {//先绘制指定颜色的圆canvas.drawCircle(mCenter, mCenter, mRadius, mCheckPaint);//然后在指定颜色的图层上,再绘制背景色的圆(半径不断缩小) 半径不断缩小,背景就不断露出来,达到向中心收缩的效果mCircleCounter += 10;canvas.drawCircle(mCenter, mCenter, mRadius - mCircleCounter, mCheckDeclinePaint);if (mCircleCounter >= mRadius + 100) {mAlphaCount += 20;if (mAlphaCount >= 255) mAlphaCount = 255; //显示对号(外加一个透明的渐变)mCheckTickPaint.setAlpha(mAlphaCount);//设置透明度//画白色的对号canvas.drawLines(mPoints, mCheckTickPaint);scaleCounter -= 4;//获取是否回弹if (scaleCounter <= -50) {//scaleCounter从大于0到小于0的过程中 画笔宽度也是由增加到减少最后减为0 实现了圆放大收缩的回弹效果scaleCounter = -50;}//放大并回弹,设置画笔的宽度float strokeWith = mCheckArcPaint.getStrokeWidth() +(scaleCounter > 0 ? 6 : -6);System.out.println(strokeWith);mCheckArcPaint.setStrokeWidth(strokeWith);canvas.drawArc(mRectArc, 90, 360, false, mCheckArcPaint);}}postInvalidate();//重绘}}/*** 获取自定义属性** @param context* @param attrs*/private void initAttrs(Context context, AttributeSet attrs) {TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CustomTickView);mCustomSize = (int) typedArray.getDimension(R.styleable.CustomTickView_custom_size, dip2px(130));mCheckBaseColor = typedArray.getColor(R.styleable.CustomTickView_check_base_color, mCheckBaseColor);mCheckTickColor = typedArray.getColor(R.styleable.CustomTickView_check_tick_color, mCheckTickColor);mUnCheckBaseColor = typedArray.getColor(R.styleable.CustomTickView_uncheck_base_color, mUnCheckBaseColor);mUnCheckTickColor = typedArray.getColor(R.styleable.CustomTickView_uncheck_tick_color, mUnCheckTickColor);typedArray.recycle();mCenter = mCustomSize / 2;mRadius = mCenter - 50;//缩小圆半径大小 防止回弹动画弹出画布mPoints = new float[8];//简易模拟对号 未做适配mPoints[0] = mCenter - mCenter / 3;mPoints[1] = mCenter;mPoints[2] = mCenter;mPoints[3] = mCenter + mCenter / 4;mPoints[4] = mCenter - 8;mPoints[5] = mCenter + mCenter / 4;mPoints[6] = mCenter + mCenter / 2;mPoints[7] = mCenter - mCenter / 5;mRectF = new RectF(mCenter - mRadius, mCenter - mRadius, mCenter + mRadius, mCenter + mRadius);//选中状态的圆弧 动画mRectArc = new RectF(mCenter - mRadius, mCenter - mRadius, mCenter + mRadius, mCenter + mRadius);//选中状态的圆弧 动画}/**** 初始化画笔*/private void initPaint() {mCheckPaint = new Paint();mCheckPaint.setAntiAlias(true);mCheckPaint.setColor(mCheckBaseColor);mCheckPaintArc = new Paint();mCheckPaintArc.setAntiAlias(true);mCheckPaintArc.setColor(mCheckBaseColor);mCheckArcPaint = new Paint();mCheckArcPaint.setAntiAlias(true);mCheckArcPaint.setColor(mCheckBaseColor);mCheckArcPaint.setStyle(Paint.Style.STROKE);mCheckArcPaint.setStrokeWidth(20);mCheckDeclinePaint = new Paint();mCheckDeclinePaint.setAntiAlias(true);mCheckDeclinePaint.setColor(Color.parseColor("#3E3E3E"));mUnCheckPaint = new Paint();mUnCheckPaint.setAntiAlias(true);mUnCheckPaint.setColor(mUnCheckBaseColor);mUnCheckPaint.setStyle(Paint.Style.STROKE);mUnCheckPaint.setStrokeWidth(20);mCheckTickPaint = new Paint();mCheckTickPaint.setAntiAlias(true);mCheckTickPaint.setColor(mCheckTickColor);mCheckTickPaint.setStyle(Paint.Style.STROKE);mCheckTickPaint.setStrokeWidth(20);}/*** 重置*/private void reset() {mRingCounter = 0;mCircleCounter = 0;mAlphaCount = 0;scaleCounter = 50;mCheckArcPaint.setStrokeWidth(20); //画笔宽度重置postInvalidate();}/*** dp转px** @param dpValue* @return*/public int dip2px(float dpValue) {final float scale = getResources().getDisplayMetrics().density;return (int) (dpValue * scale + 0.5f);}/*** 初始化点击事件*/public void setUpEvent() {this.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View view) {isCheckd = !isCheckd;reset();if (mOnCheckedChangeListener != null) {//此处回调mOnCheckedChangeListener.onCheckedChanged((CustomTickView) view, isCheckd);}}});}private OnCheckedChangeListener mOnCheckedChangeListener;public interface OnCheckedChangeListener {void onCheckedChanged(CustomTickView tickView, boolean isCheckd);}public void setOnCheckedChangeListener(OnCheckedChangeListener listener) {this.mOnCheckedChangeListener = listener;}}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><com.custom.customtickview.CustomTickViewandroid:id="@+id/customTickView"android:layout_width="wrap_content"android:layout_height="wrap_content"app:check_base_color="@color/mis"app:check_tick_color="@color/white"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintHorizontal_bias="0.498"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent"app:layout_constraintVertical_bias="0.378"app:uncheck_base_color="@color/gray"app:uncheck_tick_color="@color/gray"></com.custom.customtickview.CustomTickView><TextViewandroid:id="@+id/tv_show"android:layout_width="wrap_content"android:layout_height="wrap_content"android:width="100dp"android:gravity="center"android:text="未完成签到"android:textSize="20dp"android:textStyle="bold"android:textColor="@color/white"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintHorizontal_bias="0.498"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toBottomOf="@+id/customTickView"app:layout_constraintVertical_bias="0.099"></TextView></androidx.constraintlayout.widget.ConstraintLayout>

MainActivity.java

 public class MainActivity extends AppCompatActivity {private CustomTickView customTickView;private TextView tv_show;@SuppressLint("ObsoleteSdkInt")@Overrideprotected void onCreate(Bundle savedInstanceState) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {Window window = getWindow();window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);}super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);tv_show = findViewById(R.id.tv_show);customTickView = findViewById(R.id.customTickView);customTickView.setUpEvent();//运行动画customTickView.setOnCheckedChangeListener(new CustomTickView.OnCheckedChangeListener() {@Overridepublic void onCheckedChanged(CustomTickView tickView, boolean isCheckd) {if(!isCheckd){tv_show.setText("未完成签到");}else{tv_show.setText("已签到");}}});}}

源码地址

https://gitee.com/Mkingm/CustomTickView

相关文章:

Android自定义View实现打钩签到动画

效果图实现原理我们看实现的动画效果&#xff0c;其实是分为1. 绘制未选中状态图形&#xff08;圆弧和对号&#xff09;2. 绘制选中状态圆弧的旋转的动画3. 绘制选中状态圆弧向中心收缩铺满动画4. 绘制选中状态对号5. 绘制选中状态下圆的放大回弹动画6. 暴露接口接口回调传递选…...

python+pytest接口自动化(3)-接口测试一般流程及方法

首先我们要明确&#xff0c;通常所接口测试其实就属于功能测试&#xff0c;主要校验接口是否实现预定的功能&#xff0c;虽然有些情况下可能还需要对接口进行性能测试、安全性测试。在学习接口自动化测试之前&#xff0c;我们先来了解手工接口测试怎样进行。URL组成为了更好的理…...

《MySQL学习》 表中随机取记录的方式

一.初始化测试表 创建表 words CREATE TABLE words ( id int(11) NOT NULL AUTO_INCREMENT, word varchar(64) DEFAULT NULL, PRIMARY KEY (id)) ENGINEInnoDB;插入测试数据 create procedure idata()begin declare i int; set i 0; while i<10000 do insert into words…...

功率信号源有什么作用和功能呢

功率信号源是指集信号发生器与功率放大器为一体的电子测量仪器&#xff0c;它具有高电压、大功率的特点&#xff0c;在电子实验室中能够帮助用来驱动压电陶瓷、换能器以及电磁线圈等&#xff0c;可以有效的帮助电子工程师解决驱动负载和放大功率的问题。功率信号源和功率放大器…...

一些cmake error fixed

建完虚拟环境后 运行 pip install . 出现报错&#xff0c;显示svox2安装出错&#xff0c;然后开始进入到svox2中进行手动编译和安装。 1. cmake svox2/csrc pybind11找不到 conda install pybind11用 pip install 在虚拟环境中安装不行&#xff0c;据说会安装到全局下… 2. c…...

CentOS 7安装Docker并使用tomcat测试

文章目录环境准备Docker安装安装tomcat环境准备 CentOS 7以上版本linux内核版本需要在3.10以上&#xff0c;可通过uname -r 查看系统内核。 Docker安装 检查docker安装源 yum list docker yum安装docker &#xff1a; yum install docker.x86_64 启动 docker &#xff1a; s…...

隐私计算头条周刊(2.20-2.26)

开放隐私计算收录于合集#企业动态45个#周刊合辑45个#政策聚焦38个#隐私计算92个#行业研究37个开放隐私计算开放隐私计算OpenMPC是国内第一个且影响力最大的隐私计算开放社区。社区秉承开放共享的精神&#xff0c;专注于隐私计算行业的研究与布道。社区致力于隐私计算技术的传播…...

安装kibana 报错/访问不了

安装kibana 报错1&#xff0c;elasticsearch.yaml 和kibana.yaml 配置问题2&#xff0c;elasticsearch 和kibana版本不一致3&#xff0c;索引问题1&#xff0c;elasticsearch.yaml 和kibana.yaml 配置问题 我的RPM安装的&#xff0c;配置文件都在/etc/ vim /etc/elasticsearc…...

【华为OD机试模拟题】用 C++ 实现 - 身高排序(2023.Q1)

最近更新的博客 【华为OD机试模拟题】用 C++ 实现 - 去重求和(2023.Q1) 文章目录 最近更新的博客使用说明身高排序题目输入输出示例一输入输出Code使用说明 参加华为od机试,一定要注意不要完全背诵代码,需要理解之后模仿写出,通过率才会高。 华为 OD 清单查看地址:ht…...

MK60DX256VLQ10(256KB)MK60DN256VLQ10 Kinetis K60 MCU FLASH

MK60DX256VLQ10(256KB)MK60DN256VLQ10 Kinetis K60 MCU 32BIT 256KB FLASH 144LQFP【说明】Kinetis K6x MCU系列是一个可扩展的组合&#xff0c;具有不同级别的集成&#xff0c;提供丰富的模拟、通信、定时和控制外设套件&#xff0c;以适应广泛的需求。应用楼宇自动化控制器人…...

Prometheus 告警模块配置深度解析

本文您将了解到Prometheus 告警模块Alertmanager 配置的深度解析 Alertmanager 配置解析 Alertmanager 配置可以用命令行配置&#xff0c;也可以通过配置文件配置。命令行用来配置不可变的系统参数&#xff0c;配置文件用来定义限制规则用于通知路由和通知接收者。 Alertmana…...

《分布式技术原理与算法解析》学习笔记Day23

分布式数据复制 我们在进行分布式数据存储设计时&#xff0c;通常会考虑对数据进行备份&#xff0c;以提高数据的可用性和可靠性&#xff0c;“数据复制技术”就是实现数据备份的关键技术。 什么是数据复制技术&#xff1f; 在分布式数据库系统中&#xff0c;通常会设置主备…...

毕业设计 基于51单片机的手机蓝牙控制8位LED灯亮灭设计

基于51单片机的手机蓝牙控制8位LED灯亮灭设计1、项目简介1.1 系统构成1.2 系统功能2、部分电路设计2.1 STC89C52单片机核心系统电路设计2.2 LED电路设计2.3 蓝牙模块电路设计3、部分代码展示3.1 定时器初始化以及中断处理3.2 串口初始化3.3 串口中断处理1、项目简介 选题指导&…...

一起Talk Android吧(第五百零八回:多层布局功能)

文章目录功能介绍使用方法示例代码各位看官们大家好&#xff0c;上一回中咱们说的例子是"图片滤镜ImageFilterView",这一回中咱们说的例子是" 多层布局功能"。闲话休提&#xff0c;言归正转&#xff0c; 让我们一起Talk Android吧&#xff01;功能介绍 我…...

丁小喜の兵器谱(学生管理系统)

我的第一个独立看需求完成项目&#xff0c;虽然很简单&#xff08;笑&#xff09;建立一个可以增加&#xff0c;修改&#xff0c;删除&#xff0c;展示学生信息的系统首先是一个界面&#xff0c;让你决定进行哪个操作1.2.3.4.5分别对应不同的操作&#xff0c;switch与这一操作完…...

linux:字符串拷贝的五种方法:使用指针下标,指针变量加偏移量,指针变量自加等

字符串数组名做函数形参&#xff0c;会退化正指针变量&#xff0c;需要使用指针变量操作字符串 代码&#xff1a; #include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <s…...

cesium常用方法汇集(工具篇)

1.Scene.prototype.pickPositionWorldCoordinates 根据屏幕坐标获取世界坐标 2&#xff0c;Scene.prototype.pickPosition 根据屏幕坐标获取世界坐标 3&#xff0c;Scene.prototype.drillPick 通过屏幕坐标拾取多个对象 4&#xff0c;Scene.prototype.pickFromRay 通过射线拾…...

分布式一致性与共识算法(一)

这里写目录标题是什么ACIDCAP组合一致性概念共识为什么需要共识算法会如何发展列举Paxos算法ZAB&#xff08;Zookeeper Atomic Broadcast&#xff09;协议Raft 算法参考引用是什么 从实现效果上来说&#xff0c;很多人或多或少都了解或者设计过具有强一致性的系统。但是&#…...

C++---最长上升子序列模型---怪盗基德的滑翔翼(每日一道算法2023.2.27)

注意事项&#xff1a; 本题为"线性dp—最长上升子序列的长度"的扩展题&#xff0c;所以dp思路这里就不再赘述。 题目&#xff1a; 怪盗基德是一个充满传奇色彩的怪盗&#xff0c;专门以珠宝为目标的超级盗窃犯。 而他最为突出的地方&#xff0c;就是他每次都能逃脱中…...

Python 之 Pandas 文件操作和读取 CSV 参数详解

文章目录一、Pandas 读取文件二、CSV 文件读取1. 基本参数2. 通用解析参数3. 空值处理相关参数4. 时间处理相关参数5. 分块读入相关参数一、Pandas 读取文件 当使用 Pandas 做数据分析的时&#xff0c;需要读取事先准备好的数据集&#xff0c;这是做数据分析的第一步。Panda 提…...

微服务的异步通信技术RabbitMQ

文章目录前言1.WorkQueue&#xff08;工作队列&#xff09;消息预取机制2.Publish&Subscribe&#xff08;发布-订阅&#xff09;1.Fanout&#xff08;广播&#xff09;2.DirectExchange&#xff08;路由&#xff09;3.TopicExchange&#xff08;话题&#xff09;MQ的优点前…...

Word处理控件Aspose.Words功能演示:使用 C++ 在 Word (DOC/DOCX) 中添加或删除水印

Aspose.Words 是一种高级Word文档处理API&#xff0c;用于执行各种文档管理和操作任务。API支持生成&#xff0c;修改&#xff0c;转换&#xff0c;呈现和打印文档&#xff0c;而无需在跨平台应用程序中直接使用Microsoft Word。此外&#xff0c; Aspose API支持流行文件格式处…...

chatGPT模型原理

文章目录简介BertGPT 初代GPT-2GPT-3chatGPT开源ChatGPT简介 openai 的 GPT 大模型的发展历程。 Bert 2018年&#xff0c;自然语言处理 NLP 领域也步入了 LLM 时代&#xff0c;谷歌出品的 Bert 模型横空出世&#xff0c;碾压了以往的所有模型&#xff0c;直接在各种NLP的建模…...

四、阻塞队列

文章目录基础概念生产者消费者概念JUC阻塞队列的存取方法ArrayBlockingQueueArrayBlockingQueue的基本使用生产者方法实现原理ArrayBlockingQueue的常见属性add方法实现offer方法实现offer(time,unit)方法put方法消费者方法实现原理remove方法poll方法poll(time,unit)方法take方…...

企业电子招投标采购系统源码之登录页面

​ 信息数智化招采系统 服务框架&#xff1a;Spring Cloud、Spring Boot2、Mybatis、OAuth2、Security 前端架构&#xff1a;VUE、Uniapp、Layui、Bootstrap、H5、CSS3 涉及技术&#xff1a;Eureka、Config、Zuul、OAuth2、Security、OSS、Turbine、Zipkin、Feign、Monitor、…...

SQL零基础入门学习(十三)

上一篇&#xff08;SQL零基础入门学习&#xff08;十二&#xff09;&#xff09; SQL 视图&#xff08;Views&#xff09; 视图是可视化的表。 SQL CREATE VIEW 语句 在 SQL 中&#xff0c;视图是基于 SQL 语句的结果集的可视化的表。 视图包含行和列&#xff0c;就像一个…...

Java实现简单KV数据库

用Java实现一个简单的KV数据库 开发思路&#xff1a; 用map存储数据&#xff0c;再用一个List记录操作日志&#xff0c;开一个新线程将List中的操作写入日志文件中&#xff0c;再开一个线程用于网络IO服务接收客户端的命令&#xff0c;再启动时检查日志&#xff0c;如果有数据就…...

【Spark分布式内存计算框架——Spark Streaming】5. DStream(上)

3. DStream SparkStreaming模块将流式数据封装的数据结构&#xff1a;DStream&#xff08;Discretized Stream&#xff0c;离散化数据流&#xff0c;连续不断的数据流&#xff09;&#xff0c;代表持续性的数据流和经过各种Spark算子操作后的结果数据流。 3.1 DStream 是什么…...

Spring系列-9 Async注解使用与原理

背景&#xff1a; 本文作为Spring系列的第九篇&#xff0c;介绍Async注解的使用、注意事项和实现原理&#xff0c;原理部分会结合Spring框架代码进行。 本文可以和Spring系列-8 AOP原理进行比较阅读 1.使用方式 Async一般注解在方法上&#xff0c;用于实现方法的异步&#xf…...

Python自动化测试实战篇(6)用PO分层模式及思想,优化unittest+ddt+yaml+request登录接口自动化测试

这些是之前的文章&#xff0c;里面有一些基础的知识点在前面由于前面已经有写过&#xff0c;所以这一篇就不再详细对之前的内容进行描述 Python自动化测试实战篇&#xff08;1&#xff09;读取xlsx中账户密码&#xff0c;unittest框架实现通过requests接口post登录网站请求&…...

苹果手机如何做微电影网站/游戏优化大师下载安装

vxe-table官网...

政府英文网站建设外包服务方案/网络营销模式有哪些?

前言对于Qt应用来说&#xff0c;为了更大的跨平台通用性&#xff0c;使用SDL播放音频&#xff0c;同时也能做更多的扩充操作。声波声音是通过空气传播的一种连续的波&#xff0c;简称声波。声音的强弱体现在声波压力的大小上&#xff0c;音调的音调体现在声音的频率上。声音信号…...

互联网技术网站/著名营销策划公司

一、先把适量的盐加到面粉里面&#xff0c;倒上适量的清水&#xff0c;和成面团&#xff0c;再切下一半来&#xff0c;放上适量的红曲粉&#xff0c;肉成红面团&#xff0c;把两个面团揉光滑之后用保鲜膜盖起来&#xff0c;发一下面。七、把捏好的面团切成剂子&#xff0c;擀成…...

网站群建设调研报告/seo优化工具大全

文件名称为 build.gradle 所在行内容为 #appVersionCode : 20220811, 取出shell的脚本为 APP_VERSION_CODE$(egrep "appVersionCode :(.*?)," build.gradle -o | sed s/appVersionCode : //g | sed s/\,//g | sed s/ //g)sed语法解释下 替换文本 sed s/…...

日本真人做爰无遮挡视频免费网站/关键词优化排名哪家好

我认为这是一套适合初学者由浅到深的文章&#xff0c;所以强烈推荐给大家&#xff0c;作者从基础讲到最近比较火的漏洞&#xff0c;可能有些人看来是浅了些&#xff0c;但是的确很适合想干点啥但又不知道怎么办的菜鸟们 。 第一节&#xff0c;伸展运动。这节操我们要准备道具&a…...

云浮网站建设兼职/长沙做搜索引擎的公司

本届TechEd 2009微软技术大会&#xff0c;将于2009年11月5日-7日在北京国家会议中心隆重开幕&#xff01;不过目前微软还没有给出详细的课程信息&#xff0c;只知道会有6个技术发布&#xff1a;Windows7、Windows Server 2008 R2、Exchange Server 2010、Forefront、System Cen…...