开源 java android app 开发(十三)绘图定义控件、摇杆控件的制作

 文章的目的为了记录使用java 进行android app 开发学习的经历。本职为嵌入式软件开发,公司安排开发app,临时学习,完成app的开发。开发流程和要点有些记忆模糊,赶紧记录,防止忘记。

 相关链接:

开源 java android app 开发(一)开发环境的搭建-CSDN博客

开源 java android app 开发(二)工程文件结构-CSDN博客

开源 java android app 开发(三)GUI界面布局和常用组件-CSDN博客

开源 java android app 开发(四)GUI界面重要组件-CSDN博客

开源 java android app 开发(五)文件和数据库存储-CSDN博客

开源 java android app 开发(六)多媒体使用-CSDN博客

开源 java android app 开发(七)通讯之Tcp和Http-CSDN博客

开源 java android app 开发(八)通讯之Mqtt和Ble-CSDN博客

开源 java android app 开发(九)后台之线程和服务-CSDN博客

开源 java android app 开发(十)广播机制-CSDN博客

开源 java android app 开发(十一)调试、发布-CSDN博客

开源 java android app 开发(十二)封库.aar-CSDN博客

推荐链接:

开源C# .net mvc 开发(一)WEB搭建_c#部署web程序-CSDN博客

开源 C# .net mvc 开发(二)网站快速搭建_c#网站开发-CSDN博客

开源 C# .net mvc 开发(三)WEB内外网访问(VS发布、IIS配置网站、花生壳外网穿刺访问)_c# mvc 域名下不可訪問內網,內網下可以訪問域名-CSDN博客

开源 C# .net mvc 开发(四)工程结构、页面提交以及显示_c#工程结构-CSDN博客

开源 C# .net mvc 开发(五)常用代码快速开发_c# mvc开发-CSDN博客

本章节主要内容是如何进行绘图并自定义控件。在Android开发中,经常需要自定义控件来实现特殊功能,本章主要讲如何自定义一个摇杆控件,通过拖动中间的圆圈,实现上下左右位置的输出,可以用到机器人或无人机的控制中。

1.绘图基础

2.摇杆控件的制作

3.效果图

一、绘图

在Android中使用Java进行绘图主要涉及以下几个核心类和概念:

1.1  Canvas类是Android绘图的基础,提供了各种绘制方法,以下为代码

public class CustomView extends View {@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);// 设置画笔Paint paint = new Paint();paint.setColor(Color.RED);paint.setStyle(Paint.Style.FILL);paint.setStrokeWidth(5);// 绘制矩形canvas.drawRect(100, 100, 300, 300, paint);// 绘制圆形paint.setColor(Color.BLUE);canvas.drawCircle(200, 200, 50, paint);// 绘制文本paint.setColor(Color.BLACK);paint.setTextSize(40);canvas.drawText("Hello Android", 50, 50, paint);}
}

1.2  Paint类控制绘图的样式和颜色,以下为代码
 

Paint paint = new Paint();
paint.setColor(Color.GREEN);          // 设置颜色
paint.setStyle(Paint.Style.STROKE);   // 设置填充样式(STROKE, FILL, FILL_AND_STROKE)
paint.setStrokeWidth(10);             // 设置线条宽度
paint.setAntiAlias(true);             // 开启抗锯齿
paint.setTextSize(30);                // 设置文本大小

1.3  绘制基本图形,以下为具体代码

// 绘制直线
canvas.drawLine(startX, startY, endX, endY, paint);// 绘制矩形
canvas.drawRect(left, top, right, bottom, paint);// 绘制圆角矩形
canvas.drawRoundRect(left, top, right, bottom, rx, ry, paint);// 绘制圆形
canvas.drawCircle(centerX, centerY, radius, paint);// 绘制椭圆
canvas.drawOval(left, top, right, bottom, paint);// 绘制弧形
canvas.drawArc(left, top, right, bottom, startAngle, sweepAngle, useCenter, paint);// 绘制路径
Path path = new Path();
path.moveTo(x1, y1);
path.lineTo(x2, y2);
path.quadTo(controlX, controlY, endX, endY);
canvas.drawPath(path, paint);

1.4  创建自定义View,自定义控件可以直接继承自View,以下为典型代码
 

public class MyCustomView extends View {private Paint paint;private Path path;public MyCustomView(Context context) {super(context);init();}public MyCustomView(Context context, AttributeSet attrs) {super(context, attrs);init();}private void init() {paint = new Paint();paint.setColor(Color.BLUE);paint.setStyle(Paint.Style.STROKE);paint.setStrokeWidth(5);paint.setAntiAlias(true);path = new Path();}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);canvas.drawPath(path, paint);}@Overridepublic boolean onTouchEvent(MotionEvent event) {float x = event.getX();float y = event.getY();switch (event.getAction()) {case MotionEvent.ACTION_DOWN:path.moveTo(x, y);return true;case MotionEvent.ACTION_MOVE:path.lineTo(x, y);break;default:return false;}// 重绘视图invalidate();return true;}
}

二、遥杆控件的制作,在app开发中经常需要使用到摇杆控件,比如机器人控制,比如无人机的控制,以下为摇杆控件的具体制作方法。

2.1  创建基础类继承自view,JoystickView.java。主要实现摇杆控件的绘制和事件定义,摇杆通常外围会有底座,中间会有小圆圈代表摇杆,中间用三角形来代表方向。拉动时触发事件,提供回调接口供调用者使用。

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PointF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;public class JoystickView extends View {// 绘制参数private Paint basePaint;        // 底座画笔private Paint outerRingPaint;   // 外圈浅灰色圆环private Paint middleRingPaint;  // 中间白色圆环private Paint trianglePaint;    // 三角形画笔private PointF centerPoint;     // 中心点private PointF stickPoint;      // 摇杆当前位置private float baseRadius;       // 底座半径private float stickRadius;      // 摇杆半径private float maxDistance;      // 最大移动距离private Path upTriangle;        // 上三角形路径private Path downTriangle;      // 下三角形路径private Bitmap stickBitmap;     // 摇杆图片private int stickImageResId = R.drawable.arr_fb; // 默认图片资源ID// 回调接口public interface OnJoystickMoveListener {void onValueChanged(float xPercent, float yPercent);void onReleased();}private OnJoystickMoveListener listener;// 构造方法public JoystickView(Context context) {super(context);init(null);}public JoystickView(Context context, AttributeSet attrs) {super(context, attrs);init(attrs);}public JoystickView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);init(attrs);}private void init(AttributeSet attrs) {// 从XML属性获取自定义属性if (attrs != null) {TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.JoystickView);stickImageResId = a.getResourceId(R.styleable.JoystickView_stickImage, R.drawable.arr_fb);a.recycle();}// 初始化底座画笔(主灰色)basePaint = new Paint();//basePaint.setColor(Color.rgb(150, 150, 150));basePaint.setColor(Color.rgb(47, 47, 47));basePaint.setStyle(Paint.Style.FILL);basePaint.setAntiAlias(true);// 初始化外圈浅灰色圆环(宽度2)outerRingPaint = new Paint();outerRingPaint.setColor(Color.rgb(200, 200, 200));outerRingPaint.setStyle(Paint.Style.STROKE);outerRingPaint.setStrokeWidth(6f);outerRingPaint.setAntiAlias(true);// 初始化中间白色圆环(宽度3)middleRingPaint = new Paint();middleRingPaint.setColor(Color.WHITE);middleRingPaint.setStyle(Paint.Style.STROKE);middleRingPaint.setStrokeWidth(9f);middleRingPaint.setAntiAlias(true);// 初始化三角形画笔(白色)trianglePaint = new Paint();trianglePaint.setColor(Color.WHITE);trianglePaint.setStyle(Paint.Style.FILL);trianglePaint.setAntiAlias(true);//stickBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.arr_fb);if (stickBitmap != null && !stickBitmap.isRecycled()) {stickBitmap.recycle();}stickBitmap = BitmapFactory.decodeResource(getResources(), stickImageResId);centerPoint = new PointF();stickPoint = new PointF();upTriangle = new Path();downTriangle = new Path();}@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);// 计算中心点centerPoint.set(w / 2f, h / 2f);stickPoint.set(centerPoint);// 计算半径baseRadius = Math.min(w, h) * 0.4f;stickRadius = baseRadius * 0.3f;maxDistance = baseRadius - stickRadius - 20;// 如果图片太大,可以缩放if (stickBitmap != null) {int desiredSize = (int)(stickRadius * 2);stickBitmap = Bitmap.createScaledBitmap(stickBitmap, desiredSize, desiredSize, true);}// 初始化三角形路径updateTrianglePaths();}private void updateTrianglePaths() {/*float triangleHeight = stickRadius * 0.4f; // 三角形高度float triangleBase = (float) (2 * triangleHeight / Math.tan(Math.toRadians(30))); // 计算底边长度(120度角)float triangleSpacing = stickRadius * 0.4f; // 三角形间距// 上三角形(向上120度)upTriangle.reset();upTriangle.moveTo(stickPoint.x, stickPoint.y - triangleSpacing - triangleHeight);upTriangle.lineTo(stickPoint.x - triangleBase/2, stickPoint.y - triangleSpacing);upTriangle.lineTo(stickPoint.x + triangleBase/2, stickPoint.y - triangleSpacing);upTriangle.close();// 下三角形(向下120度)downTriangle.reset();downTriangle.moveTo(stickPoint.x, stickPoint.y + triangleSpacing + triangleHeight);downTriangle.lineTo(stickPoint.x - triangleBase/2, stickPoint.y + triangleSpacing);downTriangle.lineTo(stickPoint.x + triangleBase/2, stickPoint.y + triangleSpacing);downTriangle.close();*/}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);// 1. 绘制底座主圆canvas.drawCircle(centerPoint.x, centerPoint.y, baseRadius, basePaint);// 2. 绘制外圈浅灰色圆环(最外层)canvas.drawCircle(centerPoint.x, centerPoint.y, baseRadius - 3f, outerRingPaint);// 3. 绘制中间白色圆环canvas.drawCircle(centerPoint.x, centerPoint.y, baseRadius - 9f, middleRingPaint);// 4. 绘制摇杆图片(替换原来的圆圈)if (stickBitmap != null) {canvas.drawBitmap(stickBitmap,stickPoint.x - stickBitmap.getWidth()/2,stickPoint.y - stickBitmap.getHeight()/2,null);} else {// 如果图片加载失败,绘制默认圆圈Paint stickPaint = new Paint();stickPaint.setColor(Color.rgb(220, 220, 220));stickPaint.setStyle(Paint.Style.FILL);stickPaint.setAntiAlias(true);canvas.drawCircle(stickPoint.x, stickPoint.y, stickRadius, stickPaint);}// 5. 绘制三角形(白色)canvas.drawPath(upTriangle, trianglePaint);canvas.drawPath(downTriangle, trianglePaint);}@Overrideprotected void onDetachedFromWindow() {super.onDetachedFromWindow();// 回收Bitmap资源if (stickBitmap != null && !stickBitmap.isRecycled()) {stickBitmap.recycle();}}@Overridepublic boolean onTouchEvent(MotionEvent event) {float touchX = event.getX();float touchY = event.getY();switch (event.getAction()) {case MotionEvent.ACTION_DOWN:case MotionEvent.ACTION_MOVE:float dx = touchX - centerPoint.x;float dy = touchY - centerPoint.y;float distance = (float) Math.sqrt(dx * dx + dy * dy);if (distance <= maxDistance) {stickPoint.set(touchX, touchY);} else {float ratio = maxDistance / distance;stickPoint.set(centerPoint.x + dx * ratio,centerPoint.y + dy * ratio);}updateTrianglePaths();float xPercent = (stickPoint.x - centerPoint.x) / maxDistance;float yPercent = (stickPoint.y - centerPoint.y) / maxDistance;if (listener != null) {listener.onValueChanged(xPercent, -yPercent);}invalidate();return true;case MotionEvent.ACTION_UP:stickPoint.set(centerPoint);updateTrianglePaths();invalidate();if (listener != null) {listener.onReleased();}return true;}return super.onTouchEvent(event);}public void setOnJoystickMoveListener(OnJoystickMoveListener listener) {this.listener = listener;}
}

2.2  添加属性文件res\values\attrs.xml文件,当外部调用希望通过界面文件在初始化就传入参数的时候,需要添加属性文件。

<resources><declare-styleable name="JoystickView"><attr name="stickImage" format="reference" /></declare-styleable>
</resources>

2.3  activity_first.xml文件代码,通过设置新建属性可以设置摇杆中心的图片,app:stickImage="@drawable/arr_lr"

<?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"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"android:background="#FF2F2F2F"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="200dp"android:orientation="horizontal"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_weight="5"android:text="" /><com.hy.ble.send.JoystickViewandroid:id="@+id/joystickLeft"android:layout_width="220dp"android:layout_height="200dp"app:stickImage="@drawable/arr_fb"android:layout_centerInParent="true"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_weight="5"android:text="" /><com.hy.ble.send.JoystickViewandroid:id="@+id/joystickRight"android:layout_width="200dp"android:layout_height="200dp"app:stickImage="@drawable/arr_lr"android:layout_centerInParent="true"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_weight="5"android:text="" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:orientation="horizontal"android:background="@drawable/bottom"></LinearLayout>
</LinearLayout>

2.3  mainactivity.java的调用

package com.hy.ble.send;import android.Manifest;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattServer;
import android.bluetooth.BluetoothGattServerCallback;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.le.AdvertiseCallback;
import android.bluetooth.le.AdvertiseData;
import android.bluetooth.le.AdvertiseSettings;
import android.bluetooth.le.BluetoothLeAdvertiser;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.ParcelUuid;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;import com.tbruyelle.rxpermissions2.RxPermissions;
import com.trello.rxlifecycle2.android.ActivityEvent;
import com.trello.rxlifecycle2.components.support.RxAppCompatActivity;import java.util.ArrayList;
import java.util.List;
import java.util.UUID;import butterknife.ButterKnife;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.annotations.Nullable;public class FirstActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_first);// 在Activity中初始化两个JoystickViewJoystickView joystickLeft = findViewById(R.id.joystickLeft);JoystickView joystickRight = findViewById(R.id.joystickRight);// 为左摇杆设置监听joystickLeft.setOnJoystickMoveListener(new JoystickView.OnJoystickMoveListener() {@Overridepublic void onValueChanged(float xPercent, float yPercent) {// 这里可以添加控制逻辑,例如:// - 控制机器人移动// - 控制游戏角色// - 控制无人机等// 示例:根据摇杆位置控制电机if (xPercent > 0.5f) {//向右} else if (xPercent < -0.5f) {// 向左转}if (yPercent > 0.5f) {//前进} else if (yPercent < -0.5f) {// 后退}Log.d("Joystick", "Left - X: " + xPercent + ", Y: " + yPercent);}@Overridepublic void onReleased() {// 处理左摇杆释放Log.d("JoystickLeft", "Left released");}});// 为右摇杆设置监听joystickRight.setOnJoystickMoveListener(new JoystickView.OnJoystickMoveListener() {@Overridepublic void onValueChanged(float xPercent, float yPercent) {// 这里可以添加控制逻辑,例如:// - 控制机器人移动// - 控制游戏角色// - 控制无人机等// 示例:根据摇杆位置控制电机if (xPercent > 0.5f) {// 向右转} else if (xPercent < -0.5f) {// 向左转}if (yPercent > 0.5f) {// 前进} else if (yPercent < -0.5f) {// 后退}Log.d("Joystick", "right - X: " + xPercent + ", Y: " + yPercent);}@Overridepublic void onReleased() {// 处理左摇杆释放Log.d("JoystickRight", "right released");}});}
}

3.效果图

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

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

相关文章

Python 库 包 sentence-transformers

sentence-transformers 是一个非常流行的 Python 库&#xff0c;专门用于将文本&#xff08;句子、段落、文档&#xff09;转换为高质量的语义向量&#xff08;嵌入&#xff09;。它基于 Transformer 架构&#xff08;如 BERT、RoBERTa、DistilBERT 等&#xff09; 的预训练模型…

《聚类算法》入门--大白话篇:像整理房间一样给数据分类

一、什么是聚类算法&#xff1f; 想象一下你的衣柜里堆满了衣服&#xff0c;但你不想一件件整理。聚类算法就像一个聪明的助手&#xff0c;它能自动帮你把衣服分成几堆&#xff1a;T恤放一堆、裤子放一堆、外套放一堆。它通过观察衣服的颜色、大小、款式这些特征&#xff0c;把…

AutoGen(五) Human-in-the-Loop(人类在环)实战与进阶:多智能体协作与Web交互全流程(附代码)

AutoGen Human-in-the-Loop&#xff08;人类在环&#xff09;实战与进阶&#xff1a;多智能体协作与Web交互全流程&#xff08;附代码&#xff09; 引言&#xff1a;AI自动化的极限与人类参与的价值 在大模型&#xff08;LLM&#xff09;驱动的AI应用开发中&#xff0c;完全自…

并查集 Union-Find

目录 引言 简单介绍 浅浅总结 算法图解 初始化 根节点查找 集合合并 连通性检查 例题 大概思路 完整代码&#xff1a; 引言 一个小小的并查集让我们在ccpc卡了那么久(还有unordered_map,如果不是忘了map自动排序这么一回事也不至于试那么多发)&#xff0c;至今仍然心有…

书籍在行列都排好序的矩阵中找数(8)0626

题目&#xff1a; 给定一个有N*M的整型矩阵matrix和一个整数K&#xff0c;matrix的每一行和每一列都是排好序的。实现一个函数&#xff0c;判断K是否在matrix中。 0 1 2 5 2 3 4 7 4 4 4 8 5 …

深度学习04 卷积神经网络CNN

卷积神经网络与人工神经网络关系与区别 概念 卷积神经网络&#xff08;Convolutional Neural Network, CNN&#xff09;是人工神经网络&#xff08;Artificial Neural Network, ANN&#xff09;的一种特殊形式&#xff0c;两者在核心思想和基础结构上存在关联&#xff0c;但在…

vue基础之组件通信(VUE3)

文章目录 前言一、父子组件通信1.父组件向子组件通信2.子组件向父组件通信3.ref父组件直接操作子组件通信。 二、跨代通信1. 跨层级通信2.事件总线通信 总结 前言 vue3的组件通信和vue2相比在语法上会有些差距&#xff0c;且vue3有的通信方式也在功能上比vue2更加完善&#xf…

【RidgeUI AI+系列】中文重复统计器

中文重复统计器 文字重复统计是一个使用文本处理工具&#xff0c; 输入文本内容并指定最小词长度后&#xff0c; 就能自动高亮显示重复的词。 本教程将会借助AI实现这个应用的开发 页面脚本编写 该工具的基础流程较为清晰&#xff1a;用户输入一段文字后&#xff0c;调用提取…

代码随想录|图论|05岛屿数量(深搜DFS)

leetcode:99. 岛屿数量 题目 题目描述&#xff1a; 给定一个由 1&#xff08;陆地&#xff09;和 0&#xff08;水&#xff09;组成的矩阵&#xff0c;你需要计算岛屿的数量。岛屿由水平方向或垂直方向上相邻的陆地连接而成&#xff0c;并且四周都是水域。你可以假设矩阵外均…

数据结构-第二节-堆栈与队列

一、概念&#xff1a; 堆栈与队列也是线性表&#xff0c;但是&#xff1a; 堆栈&#xff1a;只能在一个端进行插入删除&#xff0c;此端称为栈顶。&#xff08;特点&#xff1a;后来居上&#xff09; 队列&#xff1a;在一端进行插入&#xff08;队尾&#xff09;&#xff0…

HarmonyNext动画大全02-显式动画

HarmonyOS NEXT显式动画详解 1. 核心接口 显式动画通过animateTo接口实现&#xff0c;主要特点包括&#xff1a; 触发方式&#xff1a;需主动调用接口触发动画 参数配置 &#xff1a; animateTo({duration: 1000, // 动画时长(ms)curve: Curve.Ease, // 动画曲线delay: 200…

芯谷科技--高压降压型 DC-DC 转换器D7005

在当今电子设备日益复杂且对电源性能要求极高的背景下&#xff0c;一款高效、稳定的电源管理芯片至关重要。 D7005凭借其卓越的性能和广泛的应用适配性&#xff0c;成为众多工程师在设计电源方案时的优选。 产品简介 D7005 是一款高效、高压降压型 DC-DC 转换器&#xff0c;具…

MySQL的GTID详解

GTID&#xff08;Global Transaction Identifier&#xff0c;全局事务标识符&#xff09;是MySQL 5.6及以上版本引入的重要特性&#xff0c;用于在主从复制环境中唯一标识每个事务&#xff0c;简化复制管理、故障转移和数据一致性维护。以下从多维度详细介绍GTID&#xff1a; …

专题:2025中国游戏科技发展研究报告|附130+份报告PDF、原数据表汇总下载

原文链接&#xff1a;https://tecdat.cn/?p42756 本报告汇总解读基于艾瑞咨询《2025中国游戏科技发展白皮书》、伽马数据《2025年1-3月中国游戏产业季度报告》、嘉世咨询《2025中国单机游戏市场现状报告》等多份行业研报数据。当《黑神话&#xff1a;悟空》以虚幻引擎5复刻东…

【数据挖掘】数据挖掘综合案例—银行精准营销

要求&#xff1a; 1、根据相关的信息预测通过电话推销&#xff0c;用户是否会在银行进行存款 2、数据bank.csv&#xff0c;约4520条数据&#xff0c;17个属性值 提示&#xff1a; 17个属性&#xff0c;分别是年龄&#xff0c;工作类型&#xff0c;婚姻状况&#xff0c;受教育…

postgresql查看锁的sql语句

发现一个查看postgresql锁比较好的sql语句&#xff0c;参考链接地址如下 链接地址 查看锁等待sql witht_wait as(select a.mode,a.locktype,a.database,a.relation,a.page,a.tuple,a.classid,a.granted,a.objid,a.objsubid,a.pid,a.virtualtransaction,a.virtualxid,a.trans…

JSON 格式详解

JSON 格式详解 随着互联网的发展和各种 Web 应用程序的普及&#xff0c;数据交换已经成为了我们日常开发中的重要环节。而在各种数据交换格式中&#xff0c;JSON&#xff08;JavaScript Object Notation&#xff09;作为一种轻量级的数据交换格式&#xff0c;以其简洁、易于阅…

原型设计Axure RP网盘资源下载与安装教程共享

对于初学者来说&#xff0c;我们熟悉一下其定义&#xff1a;‌Axure RP是一款常用的快速原型设计工具‌&#xff0c;主要用于创建应用软件或Web网站的线框图、流程图、原型和规格说明文档&#xff0c;广泛应用于产品经理、UI/UX设计师等专业领域。‌‌ 主要用户群体&#xff1…

iframe嵌套 redirect中转页面 route跳转

需求是项目A要使用iframe内嵌项目B的页面&#xff0c; 由于需要嵌套的页面很多&#xff0c;每个页面路径和参数又各不相同&#xff0c; 所以我们在项目B里做了一个中转页面&#xff0c;这样就能自己掌控项目A传递过来的东西了&#xff1b; routes.js 增加一个菜单&#xff1a;…

IP数据报 封装成 MAC帧 ( 目的MAC地址6B 源MAC地址6B 类型2B 数据部分 FCS校验和4B )

将 IP 数据报&#xff08;Internet Protocol Datagram&#xff09;封装成 MAC 帧 需要在数据链路层添加适当的头部信息&#xff0c;以便在局域网内进行传输。这个过程涉及将网络层&#xff08;IP 层&#xff09;的数据通过数据链路层&#xff08;MAC 层&#xff09;封装成适合物…