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

news2024/12/25 2:37:04

效果图

实现原理

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

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);

    }

测量布局

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

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

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


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

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


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

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


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

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

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

4. 绘制选中状态对号


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

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

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


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

    @Override
    protected 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() {
            @Override
            public 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() {
            @Override
            public 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);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(mCustomSize, mCustomSize);

    }

    @Override
    protected 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() {
            @Override
            public 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.CustomTickView
        android: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>

    <TextView
        android: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")
        @Override
        protected 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() {
                @Override
                public void onCheckedChanged(CustomTickView tickView, boolean isCheckd) {
                    if(!isCheckd){
                        tv_show.setText("未完成签到");
                    }else{
                        tv_show.setText("已签到");
                    }
    
                }
            });
    
        }
    }

源码地址

https://gitee.com/Mkingm/CustomTickView

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

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

相关文章

FEBC2022|打造VR内容生态闭环 佳创视讯持续加码轻量化内容建设

2月24日&#xff0c;由陀螺科技主办的未来商业生态链接大会作为 2023 癸卯兔年开年率先召开的行业重要影响力盛会在深圳成功召开。今年大会云集了科技、软件、游戏、XR等元宇宙领域的世界500强、上市公司及行业独角兽企业&#xff0c;围绕游戏、元宇宙、XR、数字营销等多项热门…

ZigBee基本概念

本文主要介绍zigbee中profile、cluster、attribute、command的概念&#xff0c;以及zigbee的一些基本思想。zigbee联盟为了不同厂商的zigbee设备之间能够互联互通&#xff0c;于是制订了的zigbee协议标准&#xff0c;到今天&#xff08;2016.3.28&#xff09;已经到了版本3.0。…

【数据结构】知识点总结(C语言)

线性表、栈和队列、串、数组和广义表、树和二叉树、图、查找、排序线性表线性表&#xff08;顺序表示&#xff09;线性表是具有相同特性元素的一个有限序列&#xff0c;数据元素之间是线性关系&#xff0c;起始元素称为线性起点&#xff0c;终端元素称为线性终点。线性表的顺序…

python线程通信

在现实生活中&#xff0c;如果一个人团队正在共同完成任务&#xff0c;那么他们之间应该有通信&#xff0c;以便正确完成任务。 同样的比喻也适用于线程。 在编程中&#xff0c;要减少处理器的理想时间&#xff0c;我们创建了多个线程&#xff0c;并为每个线程分配不同的子任务…

线上监控诊断神器arthas

目录 什么是arthas 常用命令列表 1、dashboard仪表盘 2、heapdump dumpJAVA堆栈快照 3、jvm 4、thread 5、memory 官方文档 安装使用 1、云安装arthas 2、获取需要监控进程ID 3、运行arthas 4、进入仪表盘 5、其他命令使用查看官方文档 什么是arthas arthas是阿…

【自然语言处理】BERT GPT

BERT & GPT近年来&#xff0c;随着大规模预训练语言模型的发展&#xff0c;自然语言处理领域发生了巨大变革。BERT 和 GPT 是其中最流行且最有影响力的两种模型。在本篇博客中&#xff0c;我们将讨论 BERT 和 GPT 之间的区别以及它们的演变过程。 1.起源 201820182018 年&a…

2023软件测试现状,点工如何破局成为卷王····

近几年来的特殊情况&#xff0c;综合过去的大形势变化&#xff0c;所有行业都会自下而上的进行一轮技术“大清洗”&#xff0c;技术停滞不前的“点工”或将被逐步取代。 软件测试现状 测试行业在十几年间发生了翻天覆地的变化&#xff0c;从早期站在风口上的快速发展&#xf…

【mybatis】 01- mybatis快速入门

数据库创建(注意&#xff1a;最好先创建好数据库设置utf8再进行表创建) create database mybatis; use mybatis;drop table if exists tb_user;create table tb_user(id int primary key auto_increment,username varchar(20),password varchar(20),gender char(1),addr varch…

【数据结构】初识二叉树(二叉树的入门知识)

初识二叉树一、树概念及结构1、树的概念2、树的相关概念3、树的表示4、树在实际中的运用&#xff08;表示文件系统的目录树结构&#xff09;二、二叉树概念及结构1、概念2、特殊的二叉树3、二叉树的性质4、二叉树的存储结构三、结语一、树概念及结构 1、树的概念 树是一种非线…

【win10网络重置后,网络适配器消失或者不能使用】

注&#xff1a;此文章为重新整理的版本&#xff0c;旧版本&#xff1a;https://blog.csdn.net/Viwise/article/details/123263847?spm1001.2014.3001.5502 目录 一、问题描述 【总结】 【过程】 二、方法 1、针对设备问题代码为56的解决方法&#xff1a;安装CCleaner &am…

建模算法整理

优化 改进的蝙蝠算法 2022 E 2218144 使用背景&#xff1a;将每年砍伐树木比例定义为n&#xff0c;每年树木种植比例定义为m&#xff0c;设置一系列指标以及指标的加权计算方法&#xff08;即函数F(X)的设定&#xff09;&#xff0c;寻找最优的n,m。 蝙蝠算法主要用于目标函数…

算法leetcode|38. 外观数列(多语言实现)

文章目录38. 外观数列&#xff1a;样例 1&#xff1a;样例 2&#xff1a;提示&#xff1a;分析&#xff1a;题解&#xff1a;rustgocpythonjava38. 外观数列&#xff1a; 给定一个正整数 n &#xff0c;输出外观数列的第 n 项。 「外观数列」是一个整数序列&#xff0c;从数字…

【C++】map和set的封装(红黑树)

map和set的封装一、介绍二、stl源码剖析三、仿函数获取数值四、红黑树的迭代器五、map的[]5.1 普通迭代器转const迭代器六、set源码七、map源码八、红黑树源码一、介绍 首先要知道map和set的底层都是用红黑树实现的 【数据结构】红黑树 set只需要一个key&#xff0c;但是map既…

分布式-分布式消息笔记

消息队列应用场景 消息队列 消息队列是进程之间的一种很重要的通信机制。参与消息传递的双方称为生产者和消费者&#xff0c;生产者和消费者可以只有一个实例&#xff0c;也可以集群部署。 消息体是参与生产和消费两方传递的数据&#xff0c;消息格式既可以是简单的字符串&am…

MYSQL安装部署 - Linux 本地安装及卸载

声明 &#xff1a;# 此次我们安装的 MYSQL 版本是 8.0.32 版本我们本次安装 MYSQL 总共要介绍 四种方式# 仓库安装# 本地安装# 容器安装# 源码安装我们本篇介绍的是 本地安装 我们还是去官网下载 &#xff1a;我们就是找着 .bundle.tar 这个包&#xff0c;里面就包含了所有 mys…

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

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

过滤器,监听器,拦截器的原理与在Servlet和Spring的应用

在Java Web的开发中&#xff0c;最原始和初期的学习都是从Servlet开始的&#xff0c;Servlet是Java最为耀眼的技术&#xff0c;也是Java EE的技术变革。目前大火主流的框架spring boot也的spring mvc部分也是基于拓展servlet完成的。回到之前的文章spring 实现了对servlet的封装…

SQL语句大全(详解)

SQL前言1 DDL1.1 显示所包含的数据库1.2 创建数据库1.3 删除数据库1.4 使用数据库1.4.1 创建表1.4.2 查看表的结构1.4.3 查看当前数据库下的所有表1.4.4 基础的增删改查1.4.4.1 删除表1.4.4.2 添加列1.4.4.3 修改表名1.4.4.4 修改数据类型1.4.4.5 修改列名和数据类型2 DML2.1 给…

http协议简介

http 1.简介 超文本传输协议&#xff08;HTTP&#xff0c;HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议。所有的WWW文件都必须遵守这个标准。设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法。1960年美国人Ted Nelson构思了一种通过计算机处…

Python实现GWO智能灰狼优化算法优化循环神经网络分类模型(LSTM分类算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。1.项目背景灰狼优化算法(GWO)&#xff0c;由澳大利亚格里菲斯大学学者 Mirjalili 等人于2014年提出来的一种群智能优…