自定义控件-01-绘图基础-绘制尺子
DipUtil
ublic class DipUtil {
/**
* 根据手机的分辨率从 dp 的单位 转成为 px(像素)
*/
public static int dipTopx(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
/**
* 根据手机的分辨率从 px(像素) 的单位 转成为 dp
*/
public int pxTodip(Context context, float pxValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (pxValue / scale + 0.5f);
}
}
DemoAView
public class DemoAView extends View {
// 刻度尺高度
private static final int DIVIDING_RULE_HEIGHT = 70;
// 距离左右间
private static final int DIVIDING_RULE_MARGIN_LEFT_RIGHT = 10;
// 第一条线距离边框距离
private static final int FIRST_LINE_MARGIN = 5;
// 打算绘制的厘米数
private static final int DEFAULT_COUNT = 9;
private Resources mResources;
private int mDividRuleHeight;
private int mHalfRuleHeight;
private int mDividRuleLeftMargin;
private int mFirstLineMargin;
private Paint mPaint;
private int mWidth,mHeight;
private Rect mOutRect;
public DemoAView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
initData();
}
private void initData() {
mResources = getResources();
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setColor(0xffff0000);
mPaint.setStrokeWidth(4);
mPaint.setStyle(Paint.Style.STROKE);
//数据转为对应像素值:
mDividRuleHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
DIVIDING_RULE_HEIGHT, mResources.getDisplayMetrics());
mHalfRuleHeight = mDividRuleHeight / 2;// 整数标记线
mDividRuleLeftMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
DIVIDING_RULE_MARGIN_LEFT_RIGHT, mResources.getDisplayMetrics());
mFirstLineMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
FIRST_LINE_MARGIN, mResources.getDisplayMetrics());
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//canvas.translate( )
//绘制外框
drawOuter(canvas);
//绘制刻度
drawLines(canvas);
//绘制数字
drawNumbers(canvas);
}
private void drawNumbers(Canvas canvas) {
canvas.drawText("1",60,140,mPaint);
}
private void drawLines(Canvas canvas) {
canvas.save();
canvas.translate(60,0);
int top = 80;
for(int i = 0;i<100;i++){
if(i%10 == 0){
top = 80;
}else if(i%5==0){
top = 60;
}else{
top = 40;
}
canvas.drawLine(0,20,0,top,mPaint);
canvas.translate(10,0);
}
//画布状态回滚
canvas.restore();
}
private void drawOuter(Canvas canvas) {
mOutRect = new Rect(50,20,1050,100);
canvas.drawRect(mOutRect,mPaint);
}
}
CommonUtils
public class CommonUtils {
/** dp转化成px */
public static int dip2px(Context context, float dpValue) {
final float scale = context.getApplicationContext().getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
/** sp转换成px */
public static int sp2px(Context context, float spValue) {
float fontScale=context.getApplicationContext().getResources().getDisplayMetrics().scaledDensity;
return (int) (spValue*fontScale+0.5f);
}
/**
* 缩放到固定尺寸。
*
* @param bitmap 待缩放的bitmap
* @param newWidth 缩放后的宽度
* @param newHeight 缩放后的高度
*/
public static Bitmap conversionBitmap(Bitmap bitmap, int newWidth, int newHeight) {
Bitmap b = bitmap;
int width = b.getWidth();
int height = b.getHeight();
// 计算缩放比例
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
// 取得想要缩放的matrix参数
Matrix matrix = new Matrix();
matrix.postScale(scaleWidth, scaleHeight);
// 得到新的图片
return Bitmap.createBitmap(b, 0, 0, width, height, matrix, true);
}
/**
* 生成圆角图片。
*
* @param bitmap 待转换的bitmap
* @param radius 圆弧半径
* @return 圆角bitmap
*/
public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, float radius) {
try {
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight(), Bitmap.Config.ARGB_4444);
Canvas canvas = new Canvas(output);
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, bitmap.getWidth(),
bitmap.getHeight());
final RectF rectF = new RectF(new Rect(0, 0, bitmap.getWidth(),
bitmap.getHeight()));
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(Color.BLACK);
canvas.drawRoundRect(rectF, radius, radius, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
final Rect src = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
canvas.drawBitmap(bitmap, src, rect, paint);
return output;
} catch (OutOfMemoryError outOfMemoryError) {
outOfMemoryError.printStackTrace();
return bitmap;
} catch (Exception e) {
return bitmap;
}
}
/**
* 依圆心坐标,半径,扇形角度,计算出扇形终射线与圆弧交叉点的xy坐标
*
* @param cirX 圆centerX
* @param cirY 圆centerY
* @param radius 圆半径
* @param cirAngle 当前弧角度
* @param orginAngle 起点弧角度
* @return 扇形终射线与圆弧交叉点的xy坐标
*/
public static PointF calcArcEndPointXY(float cirX, float cirY, float radius, float
cirAngle, float orginAngle) {
cirAngle = (orginAngle + cirAngle) % 360;
return calcArcEndPointXY(cirX, cirY, radius, cirAngle);
}
/**
* 依圆心坐标,半径,扇形角度,计算出扇形终射线与圆弧交叉点的xy坐标。
*
* @param cirX 圆centerX
* @param cirY 圆centerY
* @param radius 圆半径
* @param cirAngle 当前弧角度
* @return 扇形终射线与圆弧交叉点的xy坐标
*/
public static PointF calcArcEndPointXY(float cirX, float cirY, float radius, float
cirAngle) {
float posX;
float posY;
//将角度转换为弧度
float arcAngle = (float) (Math.PI * cirAngle / 180.0);
if (cirAngle < 90) {
posX = cirX + (float) (Math.cos(arcAngle)) * radius;
posY = cirY + (float) (Math.sin(arcAngle)) * radius;
} else if (cirAngle == 90) {
posX = cirX;
posY = cirY + radius;
} else if (cirAngle > 90 && cirAngle < 180) {
arcAngle = (float) (Math.PI * (180 - cirAngle) / 180.0);
posX = cirX - (float) (Math.cos(arcAngle)) * radius;
posY = cirY + (float) (Math.sin(arcAngle)) * radius;
} else if (cirAngle == 180) {
posX = cirX - radius;
posY = cirY;
} else if (cirAngle > 180 && cirAngle < 270) {
arcAngle = (float) (Math.PI * (cirAngle - 180) / 180.0);
posX = cirX - (float) (Math.cos(arcAngle)) * radius;
posY = cirY - (float) (Math.sin(arcAngle)) * radius;
} else if (cirAngle == 270) {
posX = cirX;
posY = cirY - radius;
} else {
arcAngle = (float) (Math.PI * (360 - cirAngle) / 180.0);
posX = cirX + (float) (Math.cos(arcAngle)) * radius;
posY = cirY - (float) (Math.sin(arcAngle)) * radius;
}
return new PointF(posX, posY);
}
/**
* 根据刻度获取当前渐变颜色。
*
* @param p 当前刻度
* @param specialColor 每个范围的颜色值
* @return 当前需要的颜色值
*/
public static int evaluateColor(int p, int[] specialColor) {
// 初始值
int startInt = 0xFFbebebe;
int endInt = 0xFFbebebe;
float fraction = 0.5f;
// 绿 蓝 黄 橙 红
if(p != 0 && p != 100) {
startInt = specialColor[p/20];
endInt = specialColor[p/20+1];
fraction = (p - (p/20)*20)/20f;
}
int startA = (startInt >> 24) & 0xff;
int startR = (startInt >> 16) & 0xff;
int startG = (startInt >> 8) & 0xff;
int startB = startInt & 0xff;
int endA = (endInt >> 24) & 0xff;
int endR = (endInt >> 16) & 0xff;
int endG = (endInt >> 8) & 0xff;
int endB = endInt & 0xff;
return ((startA + (int) (fraction * (endA - startA))) << 24)
| ((startR + (int) (fraction * (endR - startR))) << 16)
| ((startG + (int) (fraction * (endG - startG))) << 8)
| ((startB + (int) (fraction * (endB - startB))));
}
/**
* 获取屏幕高度
*/
public static int getScreenHeight(Context context) {
DisplayMetrics dm = context.getApplicationContext()
.getResources().getDisplayMetrics();
return dm.heightPixels;
}
/**
* 获取屏幕宽度
*/
public static int getScreenWidth(Context context) {
DisplayMetrics dm = context.getApplicationContext()
.getResources().getDisplayMetrics();
return dm.widthPixels;
}
/**
* 获取获取系统状态栏高度。
*
* @param appContext APP的上下文
* @return 状态栏高度
*/
public static int getStatusBarHeight(Context appContext) {
int result = 0;
int resourceId = appContext.getResources().getIdentifier
("status_bar_height", "dimen", "android");
if (resourceId > 0) {
result = appContext.getResources().getDimensionPixelSize(resourceId);
}
return result;
}
}
标签:
java
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· NetPad:一个.NET开源、跨平台的C#编辑器
· PowerShell开发游戏 · 打蜜蜂
· 凌晨三点救火实录:Java内存泄漏的七个神坑,你至少踩过三个!