Android 自定义view 入门 案例
自定义一个圆环进度条:
1.首页Android Studio创建一个项目
2.在项目src/xxx/目录下右键选择创建一个自定义view页面:new->UICompoent->customer view
3.输入自定义名称,选择开发语言
4.确定之后,自动生成3个文件一个是:
第一个是逻辑代码:com.lan.lanidemo.customeview.SuperCircleView.class 第二个是布局: src\main\res\layout\sample_super_circle_view.xml 第三个是view需要使用的属性:src\main\res\values\attrs_super_circle_view.xml(通过这种方式创建属性,多次创建可能造成一些变量重复定义。)
attrs_super_circle_view.xml源码:
<resources><declare-styleable name="SuperCircleView"><attr name="exampleString" format="string" /><attr name="exampleDimension" format="dimension" /><attr name="exampleColor" format="color" /><attr name="exampleDrawable" format="color|reference" /></declare-styleable>
</resources>
其中declare-styeable节点的name属性值一般是你写的view的名字,如这里根据命名默认生成:SuperCirecleView。接下来定义可以在xml中定义的组件属性,在后面我会根据需要增加圆环宽度颜色等。其中format属性指定可接受值的类型,多个类型用“|”分隔。
sample_super_circle_view.xml布局源码
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"android:layout_height="match_parent"><com.lan.lanidemo.customeview.SuperCircleViewstyle="@style/Widget.Theme.LaniDemo.SuperCircleView"android:layout_width="300dp"android:layout_height="300dp"android:paddingLeft="20dp"android:paddingBottom="40dp"app:exampleDimension="24sp"app:exampleDrawable="@android:drawable/ic_menu_add"app:exampleString="Hello, SuperCircleView" /></FrameLayout>
SuperCircleView.class
package com.lan.lanidemo.customeview;import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.view.View;import com.lan.lanidemo.R;/*** TODO: document your custom view class.*/
public class SuperCircleView extends View {private String mExampleString; // TODO: use a default from R.string...private int mExampleColor = Color.RED; // TODO: use a default from R.color...private float mExampleDimension = 0; // TODO: use a default from R.dimen...private Drawable mExampleDrawable;private TextPaint mTextPaint;private float mTextWidth;private float mTextHeight;public SuperCircleView(Context context) {super( context );init( null, 0 );}public SuperCircleView(Context context, AttributeSet attrs) {super( context, attrs );init( attrs, 0 );}public SuperCircleView(Context context, AttributeSet attrs, int defStyle) {super( context, attrs, defStyle );init( attrs, defStyle );}private void init(AttributeSet attrs, int defStyle) {// Load attributesfinal TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.SuperCircleView, defStyle, 0 );mExampleString = a.getString(R.styleable.SuperCircleView_exampleString );mExampleColor = a.getColor(R.styleable.SuperCircleView_exampleColor,mExampleColor );// Use getDimensionPixelSize or getDimensionPixelOffset when dealing with// values that should fall on pixel boundaries.mExampleDimension = a.getDimension(R.styleable.SuperCircleView_exampleDimension,mExampleDimension );if (a.hasValue( R.styleable.SuperCircleView_exampleDrawable )) {mExampleDrawable = a.getDrawable(R.styleable.SuperCircleView_exampleDrawable );mExampleDrawable.setCallback( this );}a.recycle();// Set up a default TextPaint objectmTextPaint = new TextPaint();mTextPaint.setFlags( Paint.ANTI_ALIAS_FLAG );mTextPaint.setTextAlign( Paint.Align.LEFT );// Update TextPaint and text measurements from attributesinvalidateTextPaintAndMeasurements();}private void invalidateTextPaintAndMeasurements() {mTextPaint.setTextSize( mExampleDimension );mTextPaint.setColor( mExampleColor );mTextWidth = mTextPaint.measureText( mExampleString );Paint.FontMetrics fontMetrics = mTextPaint.getFontMetrics();mTextHeight = fontMetrics.bottom;}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw( canvas );// TODO: consider storing these as member variables to reduce// allocations per draw cycle.int paddingLeft = getPaddingLeft();int paddingTop = getPaddingTop();int paddingRight = getPaddingRight();int paddingBottom = getPaddingBottom();int contentWidth = getWidth() - paddingLeft - paddingRight;int contentHeight = getHeight() - paddingTop - paddingBottom;// Draw the text.canvas.drawText( mExampleString,paddingLeft + (contentWidth - mTextWidth) / 2,paddingTop + (contentHeight + mTextHeight) / 2,mTextPaint );// Draw the example drawable on top of the text.if (mExampleDrawable != null) {mExampleDrawable.setBounds( paddingLeft, paddingTop,paddingLeft + contentWidth, paddingTop + contentHeight );mExampleDrawable.draw( canvas );}}/*** Gets the example string attribute value.** @return The example string attribute value.*/public String getExampleString() {return mExampleString;}/*** Sets the view"s example string attribute value. In the example view, this string* is the text to draw.** @param exampleString The example string attribute value to use.*/public void setExampleString(String exampleString) {mExampleString = exampleString;invalidateTextPaintAndMeasurements();}/*** Gets the example color attribute value.** @return The example color attribute value.*/public int getExampleColor() {return mExampleColor;}/*** Sets the view"s example color attribute value. In the example view, this color* is the font color.** @param exampleColor The example color attribute value to use.*/public void setExampleColor(int exampleColor) {mExampleColor = exampleColor;invalidateTextPaintAndMeasurements();}/*** Gets the example dimension attribute value.** @return The example dimension attribute value.*/public float getExampleDimension() {return mExampleDimension;}/*** Sets the view"s example dimension attribute value. In the example view, this dimension* is the font size.** @param exampleDimension The example dimension attribute value to use.*/public void setExampleDimension(float exampleDimension) {mExampleDimension = exampleDimension;invalidateTextPaintAndMeasurements();}/*** Gets the example drawable attribute value.** @return The example drawable attribute value.*/public Drawable getExampleDrawable() {return mExampleDrawable;}/*** Sets the view"s example drawable attribute value. In the example view, this drawable is* drawn above the text.** @param exampleDrawable The example drawable attribute value to use.*/public void setExampleDrawable(Drawable exampleDrawable) {mExampleDrawable = exampleDrawable;}
}
5.在这里我是做一圆环进度条:如本文开始图片效果,更新代码如下。
6. 更新自定义属性:
attrs_super_circle_view.xml
<resources><declare-styleable name="SuperCircleView"><attr name="exampleString" format="string" /><attr name="exampleDimension" format="dimension" /><attr name="exampleColor" format="color" /><attr name="exampleDrawable" format="color|reference" /><!-- 圆的半径 --><attr name="min_circle_radio" format="integer" /><!-- 圆环的宽度 --><attr name="ring_width" format="float" /><!-- 内圆的颜色 --><attr name="circle_color" format="color" /><!-- 外圆的颜色 --><attr name="max_circle_color" format="color" /><!-- 圆环的默认颜色 --><attr name="ring_normal_color" format="color" /><!-- 圆环要显示的彩色的区域(随着数值的改变,显示不同大小的彩色区域)--><attr name="ring_color_select" format="integer" /><!-- 绘制内容的数值 --><attr name="maxValue" format="integer" /><attr name="value" format="integer" /><attr name="ring_radius" format="float" /></declare-styleable>
</resources>
7.更新自定义view控制代码:
SuperCircleView.class
package com.lan.lanidemo.customeview;import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.SweepGradient;
import android.graphics.drawable.Drawable;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.TextView;import com.lan.lanidemo.R;import static android.content.ContentValues.TAG;/*** TODO: document your custom view class.*/
public class SuperCircleView extends View {private String mExampleString; // TODO: use a default from R.string...private int mExampleColor = Color.RED; // TODO: use a default from R.color...private float mExampleDimension = 0; // TODO: use a default from R.dimen...private Drawable mExampleDrawable;private TextPaint mTextPaint;private float mTextWidth;private float mTextHeight;private ValueAnimator valueAnimator;private int mViewCenterX; //view宽的中心点(可以暂时理解为圆心)private int mViewCenterY; //view高的中心点(可以暂时理解为圆心)private int mMinRadio; //最里面白色圆的半径private float mRingWidth; //圆环的宽度private int mMinCircleColor; //最里面圆的颜色private int mRingNormalColor; //默认圆环的颜色private Paint mPaint;private int color[] = new int[3]; //渐变颜色private RectF mRectF; //圆环的矩形区域private int mSelectRing = 0; //要显示的彩色区域(岁数值变化)float ringRadius;private int mMaxValue;public SuperCircleView(Context context) {super( context );Log.d( TAG, "SuperCircleView: >>构造" );init( null, 0 );}public SuperCircleView(Context context, AttributeSet attrs) {super( context, attrs );Log.d( TAG, "SuperCircleView: >>构造2" );init( attrs, 0 );}public SuperCircleView(Context context, AttributeSet attrs, int defStyle) {super( context, attrs, defStyle );init( attrs, defStyle );}private void init(AttributeSet attrs, int defStyle) {// Load attributesTypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.SuperCircleView);//最里面白色圆的半径mMinRadio = a.getInteger(R.styleable.SuperCircleView_min_circle_radio, 300);//圆环宽度mRingWidth = a.getFloat(R.styleable.SuperCircleView_ring_width, 40);//最里面的圆的颜色(绿色)mMinCircleColor = a.getColor(R.styleable.SuperCircleView_circle_color,getContext().getResources().getColor(R.color.green));//圆环的默认颜色(圆环占据的是里面的圆的空间)mRingNormalColor = a.getColor(R.styleable.SuperCircleView_ring_normal_color,getContext().getResources().getColor(R.color.gray));//圆环要显示的彩色的区域mSelectRing = a.getInt(R.styleable.SuperCircleView_ring_color_select, 0);mMaxValue = a.getInt(R.styleable.SuperCircleView_maxValue, 100);ringRadius = a.getDimension( R.styleable.SuperCircleView_ring_radius, dp2px(100) );a.recycle();//抗锯齿画笔mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);//防止边缘锯齿mPaint.setAntiAlias(true);//需要重写onDraw就得调用此this.setWillNotDraw(false);//圆环渐变的颜色color[0] = Color.parseColor("#FFD300");color[1] = Color.parseColor("#FF0084");color[2] = Color.parseColor("#16FF00");}public int dp2px(float dpValue) {final float scale = Resources.getSystem().getDisplayMetrics().density;return (int) (dpValue * scale + 0.5f);}@Overrideprotected void onLayout(boolean changed, int left, int top, int right, int bottom) {super.onLayout(changed, left, top, right, bottom);//view的宽和高,相对于父布局(用于确定圆心)int viewWidth = getMeasuredWidth();int viewHeight = getMeasuredHeight();mViewCenterX = viewWidth / 2;mViewCenterY = viewHeight / 2;mRectF = new RectF(mViewCenterX - ringRadius,mViewCenterY - ringRadius,mViewCenterX + ringRadius,mViewCenterY + ringRadius);}private void invalidateTextPaintAndMeasurements() {mTextPaint.setTextSize( mExampleDimension );mTextPaint.setColor( mExampleColor );mTextWidth = mTextPaint.measureText( mExampleString );Paint.FontMetrics fontMetrics = mTextPaint.getFontMetrics();mTextHeight = fontMetrics.bottom;}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw( canvas );mPaint.setColor(mMinCircleColor);canvas.drawCircle(mViewCenterX, mViewCenterY, mMinRadio, mPaint);//画默认圆环drawNormalRing(canvas);//画彩色圆环drawColorRing(canvas);}/*** 画默认圆环** @param canvas*/private void drawNormalRing(Canvas canvas) {Paint ringNormalPaint = new Paint(mPaint);ringNormalPaint.setStyle(Paint.Style.STROKE);ringNormalPaint.setStrokeWidth(mRingWidth);ringNormalPaint.setColor(mRingNormalColor);//圆环默认颜色为灰色canvas.drawArc(mRectF, 360, 360, false, ringNormalPaint);}/*** 画彩色圆环** @param canvas*/private void drawColorRing(Canvas canvas) {Paint ringColorPaint = new Paint(mPaint);ringColorPaint.setStyle(Paint.Style.STROKE);ringColorPaint.setStrokeWidth(mRingWidth);ringColorPaint.setShader(new SweepGradient(mViewCenterX, mViewCenterX, color, null));//逆时针旋转90度canvas.rotate(-90, mViewCenterX, mViewCenterY);canvas.drawArc(mRectF, 360, mSelectRing, false, ringColorPaint);ringColorPaint.setShader(null);}//***************************************用于更新圆环表示的数值*****************************************************/*** 设置当前值** @param value*/public void setValue(int value,TextView textView) {if (value > mMaxValue) {value = mMaxValue;}int start = 0;int end = value;startAnimator(start, end, 2000,textView);}private void startAnimator(int start, int end, long animTime, final TextView textView) {valueAnimator = ValueAnimator.ofInt(start, end);valueAnimator.setDuration(animTime);valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {Log.i(TAG, "onAnimationUpdate: animation.getAnimatedValue()::"+animation.getAnimatedValue());int i = Integer.valueOf(String.valueOf(animation.getAnimatedValue()));textView.setText(i + "");//每个单位长度占多少度mSelectRing=(int) (360 * (i / 100f));Log.i(TAG, "onAnimationUpdate: mSelectRing::"+mSelectRing);invalidate();}});valueAnimator.start();}/*** Gets the example string attribute value.** @return The example string attribute value.*/public String getExampleString() {return mExampleString;}/*** Sets the view"s example string attribute value. In the example view, this string* is the text to draw.** @param exampleString The example string attribute value to use.*/public void setExampleString(String exampleString) {mExampleString = exampleString;invalidateTextPaintAndMeasurements();}/*** Gets the example color attribute value.** @return The example color attribute value.*/public int getExampleColor() {return mExampleColor;}/*** Sets the view"s example color attribute value. In the example view, this color* is the font color.** @param exampleColor The example color attribute value to use.*/public void setExampleColor(int exampleColor) {mExampleColor = exampleColor;invalidateTextPaintAndMeasurements();}/*** Gets the example dimension attribute value.** @return The example dimension attribute value.*/public float getExampleDimension() {return mExampleDimension;}/*** Sets the view"s example dimension attribute value. In the example view, this dimension* is the font size.** @param exampleDimension The example dimension attribute value to use.*/public void setExampleDimension(float exampleDimension) {mExampleDimension = exampleDimension;invalidateTextPaintAndMeasurements();}/*** Gets the example drawable attribute value.** @return The example drawable attribute value.*/public Drawable getExampleDrawable() {return mExampleDrawable;}/*** Sets the view"s example drawable attribute value. In the example view, this drawable is* drawn above the text.** @param exampleDrawable The example drawable attribute value to use.*/public void setExampleDrawable(Drawable exampleDrawable) {mExampleDrawable = exampleDrawable;}
}
8.更新自定义布局:sample_super_circle_view.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"android:layout_height="match_parent"><com.lan.lanidemo.customeview.SuperCircleViewstyle="@style/Widget.Theme.LaniDemo.MyView"android:layout_width="300dp"android:layout_height="300dp"android:paddingLeft="20dp"android:paddingBottom="40dp"app:exampleDimension="24sp"app:exampleDrawable="@android:drawable/ic_menu_add"app:exampleString="Hello, SuperCircleView" /></FrameLayout>
9.最后在新建一个页面:ThreeActivity, 并在AndroidManifest.xml,设置为启动页面。创建完成后,在xml添加自定义view:activity_three.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><TextViewandroid:id="@+id/tv_three"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="This is Three page"android:textSize="30sp" /><FrameLayoutandroid:layout_width="300dp"android:layout_height="300dp"android:layout_gravity="center"><com.lan.lanidemo.customeview.SuperCircleViewandroid:id="@+id/superview"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"app:maxValue="100"app:ring_width="60"app:value="20" /><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:layout_marginBottom="60dp"android:text="信息完成度"android:textColor="#CFD5DE"android:textSize="18sp" /><LinearLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:layout_marginTop="10dp"android:orientation="horizontal"><TextViewandroid:id="@+id/tv"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="0"android:textColor="#506946"android:textSize="80sp" /><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="%"android:textSize="28sp" /></LinearLayout></FrameLayout></LinearLayout>
10. ThreeActivity.class 在启动页设置百分比。 同时增加一个点击事件,点击view可以随机变化百分比值。
package com.lan.lanidemo;import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;import com.lan.lanidemo.customeview.SuperCircleView;import java.util.Random;import androidx.appcompat.app.AppCompatActivity;public class ThreeActivity extends AppCompatActivity {private static final String TAG = "ThreeActivity";private TextView mTextView;SuperCircleView mSuperCircleView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate( savedInstanceState );setContentView( R.layout.activity_three );initView();}private void initView() {mTextView = (TextView) findViewById( R.id.tv );mSuperCircleView = findViewById(R.id.superview);mSuperCircleView.setValue(70, mTextView);mSuperCircleView.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {//随机设定圆环大小int i = new Random().nextInt(100) + 1;Log.i(TAG, "onClick: i::" + i);mSuperCircleView.setValue(i, mTextView);}});}
}
11.最后运行,点击之后进度更新。
相关文章:

Android 自定义view 入门 案例
自定义一个圆环进度条: 1.首页Android Studio创建一个项目 2.在项目src/xxx/目录下右键选择创建一个自定义view页面:new->UICompoent->customer view 3.输入自定义名称,选择开发语言 4.确定之后,自动生成3个文件一个是&…...

[imangazaliev/didom]一个简单又快速的DOM操作库
DiDOM是一个功能齐全、易于使用和高性能的解析器和操作库,可以帮助PHP开发者更加高效地处理HTML文档。 为了更好地了解这个项目,我们先来看看下面的介绍。 安装 你可以使用composer来安装DiDOM,只需要在你的项目目录下执行下面的命令&…...

Cookie和Session的工作流程及区别(附代码案例)
目录 一、 HTTP协议 1.1 为什么HTTP协议是无状态的? 1.2 在HTTP协议中流式传输和分块传输编码的区别 二、Cookie和Session 2.1 Cookie 2.2 Session 2.3 Cookie和Session的区别 三、servlet中与Cookie和Session相关的API 3.1 HttpServletRequest 类中的相关方…...

适用于高级别自动驾驶的驾驶员可预见误用仿真测试
摘要 借助高级别自动驾驶(HAD),驾驶员可以从事与驾驶无关的任务。在系统出现失效的情况下,驾驶员应该合理地重新获得对自动驾驶车辆(AV)的控制。不正确的系统理解可能会引起驾驶员的误操作,并可能导致车辆级的危害。ISO 21448预期功能安全标…...

Linux之进程知识点
一、什么是进程 进程是一个运行起来的程序。 问题思考: ❓ 思考:程序是文件吗? 是!都读到这一章了,这种问题都无需思考!文件在磁盘哈。 本章一开始讲的冯诺依曼,磁盘就是外设,和内…...

一种供水系统物联网监测系统
1.1供水系统 1.1.1监测范围选择依据 (1)管网老化区域管网 管网建设年代久远,通常管网发生破损问题较大,根据管网本身属性和历史发生事件的统计分析,结合数理统计,优先选择管网老化区域的管段所在区域进行…...

Linux驱动开发——字符设备(2)
目录 虚拟串口设备驱动 一个驱动支持多个设备 习题 虚拟串口设备驱动 字符设备驱动除了前面搭建好代码的框架外,接下来最重要的就是要实现特定于设备的操作方法,这是驱动的核心和关键所在,是一个驱动区别于其他驱动的本质所在,…...

【MySQL数据库原理】MySQL Community安装与配置
目录 安装成功之后查看版本验证1、介绍、安装与配置数据库2、操作MySQL数据库3、MySQL数据库原理安装成功之后查看版本验证 SELECT VERSION();查看mysql版本号 1、介绍、安装与配置数据库 下载安装包:https://download.csdn.net/download/weixin_41194129/87672588 MySQL…...

【ROS参数服务器增删改c++操作1】
需求:实现参数服务器参数的增删改查操作。 在C中实现参数服务器数据的增删改查,可以通过两套API实现:. ros::NodeHandle ros::param下面为具体操作演示: 在src下面的自己定义的作用包下面新建文件。 比如我的是一直存在的demo03_ws文件下的src里面&…...
elasticsearch 常用数据类型详解和范例
主要内容 elasticsearch 中的字符串(keyword)类型 的详解和范例 elasticsearch 中的字符串/文本(text)类型 的详解和范例 elasticsearch 中的数字(数值)类型 的详解和范例 elasticsearch 中的布尔&#…...

力扣119杨辉三角 II:代码实现 + 方法总结(数学规律法 记忆法/备忘录)
文章目录第一部分:题目第二部分:解法①-数学规律法2.1 规律分析2.2 代码实现2.3 需要思考第三部分:解法②-记忆法(备忘录)第四部分:对比总结第一部分:题目 🏠 链接:119.…...
安装pandas遇到No module named ‘_bz2’ 的解决方案
出现这个问题我们可以按照这篇博客去解决: https://blog.csdn.net/bf96163/article/details/128654915 如果解决不了,可以这样去做: 1.确保安装了 对应的库 // ubuntu安装命令 sudo apt-get install bzip2-devel // centos安装命令 sudo y…...

【数据治理-05】什么数据才是货真价实的数据资产,一起聊聊数据资产
在国家层面一些列文件、纲要、政策、办法等政府力量的推动下,数据资产这个词越来越频繁的出现在我们寻常工作当中,现在越来越觉得这个词被滥用,大有“一切数据皆是资产”的感觉,业务数据是资产、技术数据是资产,不能共…...
第三章 ARM处理器体系结构【嵌入式系统】
第三章 ARM处理器体系结构【嵌入式系统】前言推荐第三章 ARM处理器体系结构3.1 概述3.2 ARM处理器的结构3.7 ARM的异常中断处理最后前言 以下内容源自《【嵌入式系统】》 仅供学习交流使用 推荐 无 第三章 ARM处理器体系结构 留着占位 敬请期待 3.1 概述 3.2 ARM处理器的…...
最速下降法
首先,计算函数f的梯度向量:∇f(x1,x2)[2x150x2]\nabla f(x_1,x_2) \begin{bmatrix}2x_1\\50x_2\end{bmatrix}∇f(x1,x2)[2x150x2] 然后,选择一个初始点(x10,x20)(x_1^0,x_2^0)(x10,x20),比如(0,0)(0,0)(0,0)。 接…...

R语言实践——ggplot2+ggrepel绘制散点+优化注释文本位置
简介 书接adjustText实践——调整matplotlib散点图标签,避免重复 上文中,matplotlibadjustText对于我的实例来说并没有起到很好的效果。所以,博主决定在R中利用gglot2ggrepel绘制,期待效果。 操作过程 博主不常使用Rÿ…...

[TIFS 2022] FLCert:可证明安全的联邦学习免受中毒攻击
FLCert: Provably Secure Federated Learning Against Poisoning Attacks | IEEE Journals & Magazine | IEEE Xplore 摘要 由于其分布式性质,联邦学习容易受到中毒攻击,其中恶意客户端通过操纵其本地训练数据和/或发送到云服务器的本地模型更新来毒…...
css3关键帧动画
CSS3关键帧动画是一种在网页设计中常用的技术,通过使用CSS3的关键帧动画功能,可以实现网页上各种形式的动画效果,例如淡入淡出、滑动、旋转、缩放等,这些动画效果可以让网页更加生动有趣,吸引用户的注意力,…...

在 macOS Mojave 之后的每一个版本中都隐藏着比特币白皮书(Bitcoin Whitepaper)
今天我在尝试解决打印机故障问题时,发现了自2018年Mojave版本以来,macOS都附带了一份Satoshi Nakamoto(即中本聪)的比特币白皮书PDF副本[1]。 我已经询问了十几位使用Mac的朋友,他们都确认macOS里面有这个文件。这个文…...

一文看懂SpringBoot操纵数据库
1.前言 很多同学进入公司就开始参与项目开发,大多数情况是对某个项目进行维护或者需求迭代,能够从0到1参与到项目中的机会很少,因此并没有多少机会了解某些技术的运行机制。换句话说,有的面试官在面试的时候就会探讨深层的技术问题…...

随笔20250530 C# 整合 IC卡读写技术解析与实现
以下是一个完整、最简化的 FeliCa 读取整合示例(无需 SDK,基于 PCSC NuGet 包),你可以直接运行这个控制台程序,验证能否识别 RC-S300 并读取卡片 UID: 🧪 示例说明 📦 使用 NuGet 包…...

linux驱动开发(1)-内核模块
内核模块 模块最大的好处是可以动态扩展应用程序的功能而无须重新编译链接生成新的应用程序镜像,在微软的Windows系统上动态链接库DLL(Dynamic Link Library),Linux系统上的共享库so(shared object)文件的…...

[HTML5]快速掌握canvas
背景 canvas 是 html5 标准中提供的一个标签, 顾名思义是定义在浏览器上的画布 通过其强大的绘图接口,我们可以实现各种各样的图形,炫酷的动画,甚至可以利用他开发小游戏,包括市面上很流行的数据可视化框架底层都用到了Canvas。…...
计算机网络物理层基础练习
第二章 物理层 填空题 从通信双方信息交互的方式来看,通信的三种基本方式为单工、半双工和全双工。其中,单工数据传输只支持数据在一个方向上传输,全双工数据传输则允许数据同时在两个方向上传输。最基本的带通调制方法包括三种:…...

LabelImg: 开源图像标注工具指南
LabelImg: 开源图像标注工具指南 1. 简介 LabelImg 是一个图形化的图像标注工具,使用 Python 和 Qt 开发。它是目标检测任务中最常用的标注工具之一,支持 PASCAL VOC 和 YOLO 格式的标注输出。该工具开源、免费,并且跨平台支持 Windows、Lin…...

智慧政务标准规范介绍:构建高效、协同的政务信息体系
在当今信息化快速发展的时代,智慧政务作为政府数字化转型的重要方向,正逐步改变着政府管理和服务的方式。为了确保智慧政务系统的建设能够有序、高效地进行,国家制定了一系列标准规范,其中GB∕T 21062系列标准《政务信息资源交换体…...
Go开发简历优化指南
一、简历格式与排版 (一)简洁至上 去除多余装饰:在 Go 后台开发简历中,应摒弃那些花哨却无实际作用的元素,比如复杂的封面、页眉、页脚等。设想招聘人员每日要处理大量简历,若你的简历有繁杂的封面设计&a…...

JWT安全:弱签名测试.【实现越权绕过.】
JWT安全:假密钥【签名随便写实现越权绕过.】 JSON Web 令牌 (JWT)是一种在系统之间发送加密签名 JSON 数据的标准化格式。理论上,它们可以包含任何类型的数据,但最常用于在身份验证、会话处理和访问控制机制中发送有关用户的信息(“声明”)。…...

AI 眼镜新纪元:贴片式TF卡与 SOC 芯片的黄金组合破局智能穿戴
目录 一、SD NAND:智能眼镜的“记忆中枢”突破空间限制的存储革命性能与可靠性的双重保障 二、SOC芯片:AI眼镜的“智慧大脑”从性能到能效的全面跃升多模态交互的底层支撑 三、SD NANDSOC:11>2的协同效应数据流水线的高效协同成本…...
如何设计一个支持线上线下的通用订单模块 —— 面向本地生活服务行业的架构思路
一、背景与目标 在本地生活服务行业中,订单模块作为连接用户、商户、商品、支付、履约的核心组件,支撑着平台内多样化的业务形态,例如外卖配送、到店服务、团购核销、即时零售、预约预订、线下消费等。 设计一个可支持线上线下融合的通用订…...