Android 旋转盘导航栏
1.直接上源码:
package com.you.arc;import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.RectF;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;public class ArcFramelayout extends FrameLayout {private final String TAG = "ArcFramelayout";private Paint redPaint = new Paint();private Paint bluePaint = new Paint();private Paint greenPaint = new Paint();private boolean isLayout;private float[] srcDegreesArr = null;private float[] moveDegreesArr = null;private float defaultDegrees;private float minGapDg = 360f;private final int DEFAULT_INDEX = 2;private OnArcItemListener onItemSelectedListener;public void setOnArcItemListener(OnArcItemListener onItemSelectedListener) {this.onItemSelectedListener = onItemSelectedListener;}public interface OnArcItemListener {void onItemSelected(int pos);void onItemClick(int viewId);}public ArcFramelayout(Context context) {this(context, null);}public ArcFramelayout(Context context, @Nullable AttributeSet attrs) {this(context, attrs, 0);}public ArcFramelayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);redPaint.setColor(Color.RED);redPaint.setStyle(Paint.Style.FILL_AND_STROKE);redPaint.setAntiAlias(true);bluePaint.setColor(Color.BLUE);bluePaint.setStyle(Paint.Style.FILL_AND_STROKE);bluePaint.setAntiAlias(true);greenPaint.setColor(Color.GREEN);greenPaint.setStyle(Paint.Style.FILL_AND_STROKE);greenPaint.setAntiAlias(true);greenPaint.setStrokeWidth(9);}private float mDx, mDy, sweepAngle;//按下坐标值private int action;@Overridepublic boolean onTouchEvent(MotionEvent event) {this.action = event.getAction();switch (event.getAction()) {case MotionEvent.ACTION_DOWN:mDx = event.getX();mDy = event.getY();Log.i(TAG, "down=mDx=" + mDx + ",mDy=" + mDy);break;case MotionEvent.ACTION_MOVE:float mx = event.getX();float my = event.getY();float disW = mx - mDx;//x轴滑动距离float disH = my - mDy;//y轴滑动距离if (!isLayout) {if (Math.abs(disW) > Math.abs(disH)) {//滑动轴判断(这个条件可根据实际需求判断)if (disW > 0) {//往右滑touchHandle(mDy < oval.centerY());Log.i(TAG, "move=往右滑=mDx=" + mDx + ",mDy=" + mDy + ",mx=" + mx + ",my=" + my + ",disW=" + disW + ",disH=" + disH);} else {//往左滑touchHandle(mDy > oval.centerY());Log.i(TAG, "move=往左滑=mDx=" + mDx + ",mDy=" + mDy + ",mx=" + mx + ",my=" + my + ",disW=" + disW + ",disH=" + disH);}} else {if (disH > 0) {//往下滑touchHandle(mDx > oval.centerX());Log.i(TAG, "move=往下滑=mDx=" + mDx + ",mDy=" + mDy + ",mx=" + mx + ",my=" + my + ",disW=" + disW + ",disH=" + disH);} else {//往上滑touchHandle(mDx < oval.centerX());Log.i(TAG, "move=往上滑=mDx=" + mDx + ",mDy=" + mDy + ",mx=" + mx + ",my=" + my + ",disW=" + disW + ",disH=" + disH);}}}mDx = mx;//替换x轴坐标值mDy = my;//替换y轴坐标值break;case MotionEvent.ACTION_UP:
// updateSelected();break;}return true;}private void updateSelected() {isLayout = true;float srcDg = srcDegreesArr[DEFAULT_INDEX];float moveDg = moveDegreesArr[selectIndex];float diffDg = moveDg > srcDg ? moveDg - srcDg : srcDg - moveDg;Log.i(TAG, "updateSelected-srcDg=" + srcDg + ",moveDg=" + moveDg + ",diffDg=" + diffDg);for (int i = 0; i < moveDegreesArr.length; i++) {
// moveDegreesArr[i] = moveDg > srcDg ? moveDegreesArr[i] - diffDg : moveDegreesArr[i] + diffDg;}requestLayout();}private void touchHandle(boolean isAdd) {isLayout=true;rotate(isAdd);}private void touchHandle(boolean isAdd, float dis, boolean isRunAnim) {isLayout = true;if (!isRunAnim) {dis = Math.min(Math.abs(dis), 1.6f);}int childCount = getChildCount();for (int i = 0; i < childCount; i++) {float newDegrees = isAdd ? moveDegreesArr[i] + dis : moveDegreesArr[i] - dis;newDegrees = newDegrees > 360 ? newDegrees - 360 : newDegrees < 0 ? newDegrees + 360 : newDegrees;Log.i(TAG, "touchHandle-i=" + i + ",newDegrees=" + newDegrees);moveDegreesArr[i] = newDegrees;}/*int childCount = getChildCount();for (int i = 0; i < childCount; i++) {int nextIndex = i == childCount - 1 ? 0 : i + 1;float sdg = moveDegreesArr[nextIndex];float mdg = moveDegreesArr[i];float cwDiff = (sdg - mdg);cwDiff = cwDiff < 0 ? cwDiff + 360 : cwDiff;float ccwDiff = (mdg - sdg);ccwDiff = ccwDiff < 0 ? ccwDiff + 360 : ccwDiff;float diff = Math.min(cwDiff, ccwDiff);dis = (diff / 10f);float newDegrees = cwDiff < ccwDiff ? (mdg + dis) : (mdg - dis);newDegrees = newDegrees > 360 ? newDegrees - 360 : newDegrees < 0 ? newDegrees + 360 : newDegrees;moveDegreesArr[i] = newDegrees;Log.i(TAG, "touchHandle-i=" + i + ",cwDiff=" + cwDiff + ",ccwDiff="+ ccwDiff + ",dis=" + dis + ",degrees=" + mdg + ",newDegrees=" + newDegrees);}*/sweepAngle = isAdd ? sweepAngle + dis : sweepAngle - dis;sweepAngle = sweepAngle % 360f;Log.i(TAG, "touchHandle-isAdd=" + isAdd + ",dis=" + dis + ",sweepAngle=" + sweepAngle);requestLayout();}private float[] animDegreesArr = null;private void runAnim(boolean isAdd) {isLayout = true;int childCount = getChildCount();if (animDegreesArr == null) {animDegreesArr = new float[childCount];for (int i = 0; i < childCount; i++) {animDegreesArr[i] = moveDegreesArr[i];}}for (int i = 0; i < childCount; i++) {int nextIndex = isAdd ? (i == childCount - 1 ? 0 : i + 1) : (i == 0 ? childCount - 1 : i - 1);float sdg = animDegreesArr[nextIndex];float mdg = animDegreesArr[i];float cwDiff = (sdg - mdg);cwDiff = cwDiff < 0 ? cwDiff + 360 : cwDiff;float ccwDiff = (mdg - sdg);ccwDiff = ccwDiff < 0 ? ccwDiff + 360 : ccwDiff;float diff = isAdd ? cwDiff : ccwDiff;float dis = (diff / 10f);float newDegrees = isAdd ? (moveDegreesArr[i] + dis) : (moveDegreesArr[i] - dis);newDegrees = newDegrees > 360 ? newDegrees - 360 : newDegrees < 0 ? newDegrees + 360 : newDegrees;moveDegreesArr[i] = runCount==10 ? sdg : newDegrees;Log.i(TAG, "runAnim-i=" + i + ",cwDiff=" + cwDiff + ",ccwDiff=" + ccwDiff + ",dis=" + dis +",sdg=" + sdg + ",mdg=" + mdg + ",newDegrees=" + newDegrees);}requestLayout();}private boolean isCW = true;public void rotate(boolean isCW) {this.isCW=isCW;post(runnable);}private int runCount = 0;private Runnable runnable = new Runnable() {float mdg = -1;@Overridepublic void run() {isLayout = true;runCount++;if (runCount <= 10) {/*float sdg = srcDegreesArr[DEFAULT_INDEX];if (mdg == -1) {mdg = moveDegreesArr[clickIndex];}float cwDiff = (sdg - mdg);cwDiff = cwDiff < 0 ? cwDiff + 360 : cwDiff;float ccwDiff = mdg - sdg;ccwDiff = ccwDiff < 0 ? ccwDiff + 360 : ccwDiff;float diff = Math.min(cwDiff, ccwDiff);float rDg = (diff / 10f);touchHandle(cwDiff < ccwDiff, rDg, true);Log.i(TAG, "runnable-runCount=" + runCount + ",diff=" + diff + ",rDg=" + rDg + ",clickIndex=" + clickIndex + ",mdg=" + mdg + ",sdg=" + sdg);runAnim(cwDiff < ccwDiff);*/runAnim(isCW);Log.i(TAG, "runnable-runCount=" + runCount);postDelayed(this, 40);} else {animDegreesArr = null;runCount = 0;mdg = -1;isLayout = false;}}};private boolean checkDiret(int clickIndex) {float sdg = srcDegreesArr[DEFAULT_INDEX];float mdg = moveDegreesArr[clickIndex];float cwDiff = (sdg - mdg);cwDiff = cwDiff < 0 ? cwDiff + 360 : cwDiff;float ccwDiff = mdg - sdg;ccwDiff = ccwDiff < 0 ? ccwDiff + 360 : ccwDiff;return cwDiff < ccwDiff;}private int clickIndex;@Overrideprotected void onFinishInflate() {super.onFinishInflate();int childCount = getChildCount();srcDegreesArr = new float[childCount];moveDegreesArr = new float[childCount];for (int i = 0; i < childCount; i++) {View childView = getChildAt(i);/* childView.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View view) {if (view.isSelected()) {if (onItemSelectedListener != null) {onItemSelectedListener.onItemClick(view.getId());}} else {if (!isLayout) {isLayout = true;for (int j = 0; j < childCount; j++) {float d = Float.valueOf(childView.getTag().toString());if (d == srcDegreesArr[j]) {clickIndex = j;break;}}isCW=checkDiret(clickIndex);post(runnable);}}}});*/float degrees = Float.valueOf(childView.getTag().toString());int nextIndex = i == childCount - 1 ? 0 : i + 1;float nextDg = Float.valueOf(getChildAt(nextIndex).getTag().toString());float gapDg = (nextDg - degrees) < 0 ? (nextDg - degrees) + 360 : (nextDg - degrees);minGapDg = Math.min(gapDg, minGapDg);srcDegreesArr[i] = degrees;moveDegreesArr[i] = degrees;Log.i(TAG, "onFinishInflate-childCount=" + childCount + ",i=" + i + ",degrees=" + degrees + ",minGapDg=" + minGapDg);}}private boolean isContainDegrees(float moveDegrees) {float centerDg = srcDegreesArr[DEFAULT_INDEX];float preDg = srcDegreesArr[DEFAULT_INDEX == 0 ? srcDegreesArr.length - 1 : DEFAULT_INDEX - 1];float nextDg = srcDegreesArr[DEFAULT_INDEX == srcDegreesArr.length - 1 ? 0 : DEFAULT_INDEX + 1];float preHalfDg = (centerDg - preDg) < 0 ? 360 - (centerDg - preDg) : (centerDg - preDg);float nextHalfDg = (nextDg - centerDg) < 0 ? 360 - (nextDg - centerDg) : (nextDg - centerDg);float preCpDg = (centerDg - (preHalfDg * 0.5f)) < 0 ? 360f - (centerDg - (preHalfDg * 0.5f)) : (centerDg - (preHalfDg * 0.5f));float nextCpDg = (centerDg + (nextHalfDg * 0.5f)) > 360f ? (centerDg + nextHalfDg * 0.5f) - 360f : (centerDg + (nextHalfDg * 0.5f));Log.i(TAG, "isContainDegrees-moveDegrees=" + moveDegrees + ",centerDg=" + centerDg + ",preDg=" + preDg + ",nextDg=" + nextDg + ",preHalfDg=" + preHalfDg + ",nextHalfDg=" + nextHalfDg + ",preCpDg=" + preCpDg + ",nextCpDg=" + nextCpDg);return (moveDegrees >= preCpDg && moveDegrees < nextCpDg);
// return (moveDegrees >= centerDg && moveDegrees <= nextDg);}private int vWidth;private int vHeight;private int selectIndex = DEFAULT_INDEX;@Overrideprotected void onLayout(boolean changed, int l, int t, int r, int b) {isLayout = true;vWidth = getMeasuredWidth();vHeight = getMeasuredHeight();int childCount = getChildCount();Log.i(TAG, "onLayout-changed=" + changed + ",l=" + l + ",t=" + t + ",r=" + r + ",b=" + b + ",vWidth=" + vWidth + ",vHeight=" + vHeight + ",childCount=" + childCount + ",sweepAngle=" + sweepAngle);for (int i = 0; i < childCount; i++) {View childView = getChildAt(i);float degrees = moveDegreesArr[i];if (isContainDegrees(degrees)) {selectIndex = i;}Point endPoint = getEndPoint(oval.left, oval.top, oval.width(), oval.height(), 0, -degrees);int cvW = childView.getMeasuredWidth();int cvH = childView.getMeasuredHeight();Log.i(TAG, "onLayout-i=" + i + ",px=" + endPoint.x + ",py=" + endPoint.y + ",cvW=" + cvW + ",cvH=" + cvH + ",degrees=" + degrees);childView.layout((int) (endPoint.x - cvW * 0.5f), (int) (endPoint.y - cvH * 0.5f), (int) (endPoint.x + cvW * 0.5f), (int) (endPoint.y + cvH * 0.5f));}if (onItemSelectedListener != null) {onItemSelectedListener.onItemSelected(selectIndex);}isLayout = false;}private RectF oval = new RectF(-290, 65, 960, 525);@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);Log.i(TAG, "onDraw");Paint p = new Paint();p.setStrokeWidth(10);p.setColor(Color.RED);Paint p0 = new Paint();p0.setStrokeWidth(5);p0.setColor(Color.GREEN);Paint p1 = new Paint();p1.setColor(Color.parseColor("#808C8C8C"));// canvas.drawArc(oval.left, oval.top, oval.right, oval.bottom, 0, 360, true, p1);
// canvas.drawLine(oval.left, oval.top + oval.height() / 2, oval.right, oval.top + oval.height() / 2, p);
// canvas.drawLine(oval.left + oval.width() / 2f, oval.top, oval.left + oval.width() / 2f, oval.bottom, p);int childCount = getChildCount();for (int i = 0; i < childCount; i++) {View childView = getChildAt(i);float degrees = Float.valueOf(childView.getTag().toString());Point endPoint = getEndPoint(oval.left, oval.top, oval.width(), oval.height(), 0, -degrees);canvas.drawPoint(endPoint.x, endPoint.y, p0);}Point endPoint = getEndPoint(oval.left, oval.top, oval.width(), oval.height(), 0, -19);canvas.drawPoint(endPoint.x, endPoint.y, p);}private Point getEndPoint(float x, float y, float width, float height, float startAngle, float extentAngle) {double var1 = Math.toRadians(-startAngle - extentAngle);double var3 = x + (Math.cos(var1) * 0.5 + 0.5) * width;double var5 = y + (Math.sin(var1) * 0.5 + 0.5) * height;return new Point((int) var3, (int) var5);}}
2.MainActivity
package com.you.arc;import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.Toast;//import java.awt.geom.Arc2D;//这个类里面有圆周运动计算公式public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);ArcFramelayout arcFramelayout = findViewById(R.id.arc_framelayout);arcFramelayout.setOnArcItemListener(new ArcFramelayout.OnArcItemListener() {@Overridepublic void onItemSelected(int pos) {for (int i = 0; i < arcFramelayout.getChildCount(); i++) {if (i == pos) {ViewGroup parent = ((ViewGroup) arcFramelayout.getChildAt(i));parent.setSelected(true);for (int j = 0; j < parent.getChildCount(); j++) {parent.getChildAt(j).setSelected(true);}
// ((ViewGroup) arcFramelayout.getChildAt(i)).getChildAt(0).setBackgroundColor(Color.parseColor("#80FF0000"));} else {ViewGroup parent = ((ViewGroup) arcFramelayout.getChildAt(i));parent.setSelected(false);for (int j = 0; j < parent.getChildCount(); j++) {parent.getChildAt(j).setSelected(false);}
// ((ViewGroup) arcFramelayout.getChildAt(i)).getChildAt(0).setBackground(null);}}}@Overridepublic void onItemClick(int viewId) {Toast.makeText(MainActivity.this, "tag=" + findViewById(viewId).getTag(), Toast.LENGTH_SHORT).show();switch (viewId) {case R.id.ll_phone:break;case R.id.ll_flag:break;case R.id.ll_connect:break;case R.id.ll_setting:break;case R.id.ll_audi:break;case R.id.ll_dashboard:break;case R.id.ll_earth:break;case R.id.ll_cd:break;}}});findViewById(R.id.iv_small_arrow).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {arcFramelayout.rotate(false);}});findViewById(R.id.iv_big_arrow).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {arcFramelayout.rotate(true);}});}
}
3.布局
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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:background="@android:color/black"tools:context=".MainActivity"><com.you.arc.ArcViewandroid:layout_width="1200px"android:layout_height="550px"android:visibility="gone"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent" /><FrameLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"><ImageViewandroid:id="@+id/iv_small_arrow"android:layout_width="wrap_content"android:layout_height="wrap_content"android:src="@drawable/ic_small_arrow"android:layout_marginTop="140px"/><ImageViewandroid:id="@+id/iv_big_arrow"android:layout_width="wrap_content"android:layout_height="wrap_content"android:src="@drawable/ic_big_arrow"android:layout_gravity="bottom"android:layout_marginBottom="40px"/><com.you.arc.ArcFramelayoutandroid:id="@+id/arc_framelayout"android:layout_width="1400px"android:layout_height="match_parent"android:layout_marginStart="0px"android:layout_marginTop="76px"android:background="@android:color/transparent"><LinearLayoutandroid:id="@+id/ll_phone"android:layout_width="wrap_content"android:layout_height="wrap_content"android:tag="6"><ImageViewandroid:layout_width="150px"android:layout_height="180px"android:src="@drawable/phone_selector"android:background="@android:color/transparent"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_vertical"android:maxWidth="330px"android:background="@drawable/green_text_selector"android:text="电话"android:textColor="@android:color/white"android:textSize="45px"android:textStyle="bold" /></LinearLayout><LinearLayoutandroid:id="@+id/ll_flag"android:layout_width="wrap_content"android:layout_height="wrap_content"android:tag="36"><ImageViewandroid:layout_width="150px"android:layout_height="180px"android:src="@drawable/phone_selector"android:background="@android:color/transparent"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_vertical"android:maxWidth="330px"android:background="@drawable/blue_text_selector"android:text="旗帜"android:textColor="@android:color/white"android:textSize="45px"android:textStyle="bold" /></LinearLayout><LinearLayoutandroid:id="@+id/ll_connect"android:layout_width="wrap_content"android:layout_height="wrap_content"android:tag="62"><ImageViewandroid:layout_width="150px"android:layout_height="180px"android:background="@android:color/transparent"android:src="@drawable/phone_selector"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_vertical"android:maxWidth="330px"android:background="@drawable/green_text_selector"android:text="蓝牙连接"android:textColor="@android:color/white"android:textSize="45px"android:textStyle="bold" /></LinearLayout><LinearLayoutandroid:id="@+id/ll_setting"android:layout_width="wrap_content"android:layout_height="wrap_content"android:tag="90"><ImageViewandroid:layout_width="150px"android:layout_height="180px"android:src="@drawable/phone_selector"android:background="@android:color/transparent"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_vertical"android:background="@drawable/blue_text_selector"android:maxWidth="330px"android:text="设置"android:textColor="@android:color/white"android:textSize="45px"android:textStyle="bold" /></LinearLayout><LinearLayoutandroid:id="@+id/ll_audi"android:layout_width="wrap_content"android:layout_height="wrap_content"android:tag="262"><ImageViewandroid:layout_width="150px"android:layout_height="180px"android:src="@drawable/phone_selector"android:background="@android:color/transparent"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_vertical"android:maxWidth="330px"android:background="@drawable/red_text_selector"android:text="手机"android:textColor="@android:color/white"android:textSize="45px"android:textStyle="bold" /></LinearLayout><LinearLayoutandroid:id="@+id/ll_dashboard"android:layout_width="wrap_content"android:layout_height="wrap_content"android:tag="286"><ImageViewandroid:layout_width="150px"android:layout_height="180px"android:src="@drawable/phone_selector"android:background="@android:color/transparent"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_vertical"android:maxWidth="330px"android:background="@drawable/red_text_selector"android:text="时钟"android:textColor="@android:color/white"android:textSize="45px"android:textStyle="bold" /></LinearLayout><LinearLayoutandroid:id="@+id/ll_earth"android:layout_width="wrap_content"android:layout_height="wrap_content"android:tag="311"><ImageViewandroid:layout_width="150px"android:layout_height="180px"android:src="@drawable/phone_selector"android:background="@android:color/transparent"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_vertical"android:maxWidth="330px"android:background="@drawable/green_text_selector"android:text="地球"android:textColor="@android:color/white"android:textSize="45px"android:textStyle="bold" /></LinearLayout><LinearLayoutandroid:id="@+id/ll_cd"android:layout_width="wrap_content"android:layout_height="wrap_content"android:tag="337"><ImageViewandroid:layout_width="150px"android:layout_height="180px"android:src="@drawable/phone_selector"android:background="@android:color/transparent"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_vertical"android:maxWidth="330px"android:background="@drawable/yellow_text_selector"android:text="媒体"android:textColor="@android:color/white"android:textSize="45px"android:textStyle="bold" /></LinearLayout></com.you.arc.ArcFramelayout></FrameLayout>
</FrameLayout>
手势滑动目前尚未完善,可以根据实际需求完善
demo下载地址:https://download.csdn.net/download/qq_29364417/90203270
相关文章:

Android 旋转盘导航栏
1.直接上源码: package com.you.arc;import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Point; import android.graphics.RectF; import android.support…...

空域降噪、频域降噪和时域降噪
目录 算法原理: 1.图像噪声 2.图像中常见的噪声的类型 3.不同域的定义 4.空域降噪 4.1.空域降噪的定义: 4.2.思想核心: 4.3.局部的线性算法 高斯降噪 4.4.非局部算法 5.频域降噪 傅里叶降噪: 小波降噪: …...

Cornerstone3D:了解Nifti文件,并查看元数据
Nifti 全称Neuroimaging Informatics Technology Initiative是一种专为存储医学和神经影像数据而设计的文件格式。设计目的是高效的存储三维或四维图像数据,同时将相关的元数据紧凑地嵌入文件中。Nifti文件的组成:头信息(元数据)…...

设计模式の状态策略责任链模式
文章目录 前言一、状态模式二、策略模式三、责任链模式 前言 本篇是关于设计模式中的状态模式、策略模式、以及责任链模式的学习笔记。 一、状态模式 状态模式是一种行为设计模式,核心思想在于,使某个对象在其内部状态改变时,改变该对象的行为…...

DevOps流程CICD之Jenkins使用操作
一、jenkins的docker-compose安装部署 请参考 jenkins的docker安装部署配置全网最详细教程-CSDN博客 二、创建repository 三、创建ssh 四、创建视图 五、创建任务 六、配置gitlab钩子 七、自动构建部署CI/CD验证...

【玩转23种Java设计模式】行为型模式篇:备忘录模式
软件设计模式(Design pattern),又称设计模式,是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。 汇总目录链接&…...

Unity Shader TexelSize的意义
TexelSize在制作玻璃折射效果时会用到。 // Get the normal in tangent space fixed3 bump UnpackNormal(tex2D(_BumpMap, i.uv.zw)); // Compute the offset in tangent space float2 offset bump.xy * _Distortion * _RefractionTex_TexelSize.xy; i.scrPos.xy offset * i…...

三、STM32MP257系列之定制Yocto Machine
文章目录 STM32MP257系列之定制的Yocto Machine1. TFA 定制2. OPTEE OS定制3. Uboot 定制3.1 创建 board3.2 创建 board的头文件3.3 创建 board的配置文件3.4 添加我们自己的dtb文件3.5 生成新patch打包到uboot recipe中3.6 修改yocto中的配置 4. Kernel 定制4.1 定制设备树 5.…...

小程序信息收集(小迪网络安全笔记~
免责声明:本文章仅用于交流学习,因文章内容而产生的任何违法&未授权行为,与文章作者无关!!! 附:完整笔记目录~ ps:本人小白,笔记均在个人理解基础上整理,…...

使用 Docker 搭建 Drogon 框架
使用 Docker 搭建 Drogon 框架 Drogon 是一个基于 C 的高性能 Web 框架,支持异步 I/O 和协程。使用 Docker 可以快速搭建 Drogon 开发环境,避免依赖冲突和配置问题。 以下是使用 Docker 搭建 Drogon 框架的详细步骤: 1. 准备工作 安装 Doc…...

【Linux报告】实训一:GNME桌面环境的设置及应用
实训一:GNME桌面环境的设置及应用 【练习1】在图形模式和文本模式下登录Linux系统。 1、开启Linux虚拟机。 答:打开此虚拟机如图所示 2、观察屏幕上显示的启动信息。 3、当系统启动到图形界面时,用普通用户身份登录。 答:如图…...

活动预告 |【Part1】Microsoft Azure 在线技术公开课:基础知识
课程介绍 参加“Azure 在线技术公开课:基础知识”活动,培养有助于创造新的技术可能性的技能并探索基础云概念。参加我们举办的本次免费培训活动,扩充自身的云模型和云服务类型知识。你还可以查看以计算、网络和存储为核心的 Azure 服务。 活…...

vulnhub靶场【Hogwarts】之bellatrix
前言 靶机:hotwarts-dobby,ip地址为192.168.1.69 攻击:kali,ip地址为192.168.1.16 都采用虚拟机,网卡为桥接模式 主机发现 使用arp-scan -l或netdiscover -r 192.168.1.1/24扫描发现主机 信息收集 使用nmap扫描端…...

移动 APP 设计规范参考
一、界面设计规范 布局原则: 内容优先:以内容为核心进行布局,突出用户需要的信息,简化页面导航,提升屏幕空间利用率.一致性:保持界面元素风格一致,包括颜色、字体、图标等,使用户在…...

HarmonyOS:@Require装饰器:校验构造传参
一、前言 Require是校验Prop、State、Provide、BuilderParam和普通变量(无状态装饰器修饰的变量)是否需要构造传参的一个装饰器。 说明 从API version 11开始对Prop/BuilderParam进行校验。 从API version 11开始,该装饰器支持在元服务中使用。 从API version 12开…...

github提交不上去,网络超时问题解决
问题出现的原因: DNS服务器数据不同步,github的服务器发送迁移,在本地缓存的ip地址现在无效了。 解决方案: 1)点击这里,查询github.com最新的ip地址 2.0)编辑linux系统地址缓存文件&#x…...

国产数据库OceanBase从入门到放弃教程
1. 介绍 是由蚂蚁集团(Ant Group,原蚂蚁金服)自主研发的分布式关系型数据库。它旨在解决海量数据存储和高并发访问的问题,特别适合金融级应用场景,如支付宝等对数据一致性、可靠性和性能有极高要求的服务。以下是关于…...

风力涡轮机缺陷检测数据集,91.4%准确识别率,18912张图片,支持yolo,PASICAL VOC XML,COCO JSON格式的标注
风力涡轮机缺陷检测数据集,91.4%准确识别率,18912张图片,支持yolo,PASICAL VOC XML,COCO JSON格式的标注 数据集下载: yolo v&#…...

Rabbitmq追问2
分析rabbitmq 默认使用姿势是什么 direct fanout还是什么 public void convertAndSend(String exchange, String routingKey, Object object, CorrelationData correlationData) throws AmqpException { this.send(exchange, routingKey, this.convertMessageIfNecessary(obje…...

郑州时空-TMS运输管理系统 GetDataBase 信息泄露漏洞复现
0x01 产品简介 郑州时空-TMS运输管理系统是一款专为物流运输企业设计的综合性管理软件,旨在提高运输效率、降低运输成本,并实现供应链的协同运作。系统基于现代计算机技术和物流管理方法,结合了郑州时空公司的专业经验和技术优势,为物流运输企业提供了一套高效、智能的运输…...

如何使用React,透传各类组件能力/属性?
在23年的时候,我主要使用的框架还是Vue,当时写了一篇“如何二次封装一个Vue3组件库?”的文章,里面涉及了一些如何使用Vue透传组件能力的方法。在我24年接触React之后,我发现这种扩展组件能力的方式有一个专门的术语&am…...

汇编点灯练习
要求: 1、轮流将LED1、LED2、LED3及蜂鸣器点亮 2、基于STM32MP157AAA,阅读原理图和STM32MP157芯片手册 3、ARM汇编指令点灯 1、运行效果 汇编点灯 2、通过查询原理图和芯片手册,得到以下结论: 3、汇编源码 .text .global _start…...

数据结构与算法之动态规划: LeetCode 213. 打家劫舍 II (Ts版)
打家劫舍 II https://leetcode.cn/problems/house-robber-ii/description/ 描述 你是一个专业的小偷,计划偷窃沿街的房屋,每间房内都藏有一定的现金这个地方所有的房屋都 围成一圈 ,这意味着第一个房屋和最后一个房屋是紧挨着的同时&#…...

Git工具
安装教程 详细安装教程 基本命令...

SpringBoot3.3.3+shardingsphere-jdbc5.5.0读写分离、自定义生成主键策略
最近在开发项目搭建框架时,考虑后期支付模块的订单数据量可能会比较大,于是使用现在主流的shardingsphere的读写分离、水平分表来解决后期数据量大影响查询效率的问题。 项目技术栈:jdk17Springboot3.3.3shardingsphere-jdbc5.5.0mybatis-pl…...

开发运维基本功:无需复杂配置快速实现本地Nginx的公网远程访问
文章目录 前言1. 本地连接测试2. 飞牛云安装Cpolar3. 配置公网连接地址4. 飞牛云APP连接测试5. 固定APP远程地址6. 固定APP地址测试 前言 现在生活和工作中的各种设备都变得越来越智能,而数据存储的需求也随之剧增。想象一下:你正在外地出差,…...

金融租赁系统助力企业转型与市场竞争力提升
内容概要 在现代商业环境中,金融租赁系统不仅是一个简单的工具,而是企业转型的重要推动力。通过优化业务流程,提升自动化水平,它帮助企业在复杂的市场中找到自己的立足之地。想象一下,一个企业在使用传统方法时&#…...
【漫话机器学习系列】028.CP
Mallows’ Cp:标准化公式解析与应用 Mallows’ Cp 是一种常用的模型选择工具,用于在一系列候选模型中权衡拟合度和复杂性,帮助我们选择性能最优的模型。本文将基于其标准化公式展开详细解析,并探讨其应用场景、实现方法、优点与局…...

软件测试——面试八股文(入门篇)
今天给大家分享软件测试面试题入门篇,看看大家能答对几题 一、 请你说一说测试用例的边界 参考回答: 边界值分析法就是对输入或输出的边界值进行测试的一种黑盒测试方法。通常边界值分析法是作为对等价类划分法的补充,这种情况下ÿ…...

如何在不同工作场景下优化嵌入式系统的电源消耗
在不同工作场景下优化嵌入式系统的电源消耗是一个复杂但至关重要的任务,它涉及到硬件设计、软件编程以及系统级管理等多个方面。以下是一些具体的策略和方法: 1. 动态电压频率调节(DVFS) 原理:根据处理器的当前负载动…...