尺寸相关→SizeUtils

本文介绍了一个尺寸相关的工具类,提供了dp、px、sp等单位之间的转换方法,以及获取视图尺寸的方法。
   
  import android.util.DisplayMetrics;
  import android.util.TypedValue;
  import android.view.View;
  import android.view.ViewGroup;
   
  /**
  * <pre>
  * author: Blankj
  * blog : http://blankj.com
  * time : 2016/8/2
  * desc : 尺寸相关工具类
  * </pre>
  */
  public final class SizeUtils {
   
  private SizeUtils() {
  throw new UnsupportedOperationException("u can't instantiate me...");
  }
   
  /**
  * dp转px
  *
  * @param dpValue dp值
  * @return px值
  */
  public static int dp2px(float dpValue) {
  final float scale = Utils.getContext().getResources().getDisplayMetrics().density;
  return (int) (dpValue * scale + 0.5f);
  }
   
  /**
  * px转dp
  *
  * @param pxValue px值
  * @return dp值
  */
  public static int px2dp( float pxValue) {
  final float scale = Utils.getContext().getResources().getDisplayMetrics().density;
  return (int) (pxValue / scale + 0.5f);
  }
   
  /**
  * sp转px
  *
  * @param spValue sp值
  * @return px值
  */
  public static int sp2px(float spValue) {
  final float fontScale = Utils.getContext().getResources().getDisplayMetrics().scaledDensity;
  return (int) (spValue * fontScale + 0.5f);
  }
   
  /**
  * px转sp
  *
  * @param pxValue px值
  * @return sp值
  */
  public static int px2sp( float pxValue) {
  final float fontScale = Utils.getContext().getResources().getDisplayMetrics().scaledDensity;
  return (int) (pxValue / fontScale + 0.5f);
  }
   
  /**
  * 各种单位转换
  * <p>该方法存在于TypedValue</p>
  *
  * @param unit 单位
  * @param value 值
  * @param metrics DisplayMetrics
  * @return 转换结果
  */
  public static float applyDimension(int unit, float value, DisplayMetrics metrics) {
  switch (unit) {
  case TypedValue.COMPLEX_UNIT_PX:
  return value;
  case TypedValue.COMPLEX_UNIT_DIP:
  return value * metrics.density;
  case TypedValue.COMPLEX_UNIT_SP:
  return value * metrics.scaledDensity;
  case TypedValue.COMPLEX_UNIT_PT:
  return value * metrics.xdpi * (1.0f / 72);
  case TypedValue.COMPLEX_UNIT_IN:
  return value * metrics.xdpi;
  case TypedValue.COMPLEX_UNIT_MM:
  return value * metrics.xdpi * (1.0f / 25.4f);
  }
  return 0;
  }
   
  /**
  * 在onCreate中获取视图的尺寸
  * <p>需回调onGetSizeListener接口,在onGetSize中获取view宽高</p>
  * <p>用法示例如下所示</p>
  * <pre>
  * SizeUtils.forceGetViewSize(view, new SizeUtils.onGetSizeListener() {
  * Override
  * public void onGetSize(View view) {
  * view.getWidth();
  * }
  * });
  * </pre>
  *
  * @param view 视图
  * @param listener 监听器
  */
  public static void forceGetViewSize(final View view, final onGetSizeListener listener) {
  view.post(new Runnable() {
  @Override
  public void run() {
  if (listener != null) {
  listener.onGetSize(view);
  }
  }
  });
  }
   
  /**
  * 获取到View尺寸的监听
  */
  public interface onGetSizeListener {
  void onGetSize(View view);
  }
   
  /**
  * 测量视图尺寸
  *
  * @param view 视图
  * @return arr[0]: 视图宽度, arr[1]: 视图高度
  */
  public static int[] measureView(View view) {
  ViewGroup.LayoutParams lp = view.getLayoutParams();
  if (lp == null) {
  lp = new ViewGroup.LayoutParams(
  ViewGroup.LayoutParams.MATCH_PARENT,
  ViewGroup.LayoutParams.WRAP_CONTENT
  );
  }
  int widthSpec = ViewGroup.getChildMeasureSpec(0, 0, lp.width);
  int lpHeight = lp.height;
  int heightSpec;
  if (lpHeight > 0) {
  heightSpec = View.MeasureSpec.makeMeasureSpec(lpHeight, View.MeasureSpec.EXACTLY);
  } else {
  heightSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
  }
  view.measure(widthSpec, heightSpec);
  return new int[]{view.getMeasuredWidth(), view.getMeasuredHeight()};
  }
   
  /**
  * 获取测量视图宽度
  *
  * @param view 视图
  * @return 视图宽度
  */
  public static int getMeasuredWidth(View view) {
  return measureView(view)[0];
  }
   
  /**
  * 获取测量视图高度
  *
  * @param view 视图
  * @return 视图高度
  */
  public static int getMeasuredHeight(View view) {
  return measureView(view)[1];
  }
  }
package com.color.gamecolor.view import android.animation.ValueAnimator import android.content.Context import android.content.res.Resources import android.graphics.Canvas import android.graphics.Color import android.graphics.Paint import android.graphics.Rect import android.text.TextPaint import android.util.AttributeSet import android.view.View import android.view.animation.LinearInterpolator import androidx.core.animation.addListener import androidx.core.content.res.ResourcesCompat import com.blankj.utilcode.util.SizeUtils import com.color.gamecolor.R import com.color.gamecolor.bean.ColorPanelStructure /** * @author Sincerely yours. * @feature 色盘Adapter -> View */ class ColorPanelView(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : View(context, attrs, defStyleAttr) { constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0) constructor(context: Context) : this(context, null, 0) private val strokePaint = Paint() // 描边画笔 private val blockPaint = Paint() // 色块画笔 private val textPaint = TextPaint() private val textBounds = Rect() var strokeFraction = 2.5f // 控制进度环形的半径[2.5, 1.5] fun open(input: Float) { strokeFraction = (1.5f - 2.5f) * (input - 0) / (1 - 0) + 2.5f invalidate() } fun shrink(input: Float) { strokeFraction = (6.4f - 1.5f) * (input - 0) / (1 - 0) + 1.5f invalidate() } private var isChosen = false private var number = "0" var finish = 0 // 已填色进度 private var blockColor = 0 // 色块颜色 private var progressColor = 0 // 进度环形颜色 private var progressAnimator: ValueAnimator? = null private var sweepAngle = 0f var radiusOffset = SizeUtils.dp2px(5.6f).toFloat() // 完成时,缩小动画 set(value) { val a = SizeUtils.dp2px(5.6f) val b = SizeUtils.dp2px(12f) field = (b - a) * (value - 0) / (1 - 0) + a invalidate() } init { strokePaint.flags = Paint.ANTI_ALIAS_FLAG or Paint.DITHER_FLAG or Paint.FILTER_BITMAP_FLAG // 因为style是FILL,所以property strokeWidth存放的是间距 val offset = radiusOffset - SizeUtils.dp2px(4.4f) // 进度条圆环宽4.4dp strokePaint.strokeWidth = offset strokePaint.style = Paint.Style.FILL blockPaint.flags = Paint.ANTI_ALIAS_FLAG or Paint.DITHER_FLAG or Paint.FILTER_BITMAP_FLAG blockPaint.style = Paint.Style.FILL textPaint.textAlign = Paint.Align.CENTER textPaint.textSize = SizeUtils.dp2px(24F).toFloat() textPaint.flags = Paint.ANTI_ALIAS_FLAG or Paint.DITHER_FLAG or Paint.FILTER_BITMAP_FLAG textPaint.typeface = ResourcesCompat.getFont(context, R.font.nunito_medium) } override fun onDraw(canvas: Canvas) { super.onDraw(canvas) canvas.drawColor(Color.TRANSPARENT) // 曲线进度 if (isChosen) { val offset = strokePaint.strokeWidth * strokeFraction // 绘制时曲线会根据线宽左右两边扩展 // 进度条灰色底衬 strokePaint.color = progressColor canvas.drawArc( offset, offset, width.toFloat() - offset, height.toFloat() - offset, 0f, 360f, false, strokePaint ) // 真实进度 strokePaint.color = blockColor canvas.drawArc( offset, offset, width.toFloat() - offset, height.toFloat() - offset, 270f, sweepAngle, true, strokePaint ) } val r = width / 2f // 中心色块 canvas.drawCircle(r, r, r - radiusOffset, blockPaint) // Number文字 // 文字位数大于2字号变小 textPaint.textSize = if (number.length > 2) SizeUtils.dp2px(23F).toFloat() else SizeUtils.dp2px(24F) .toFloat() textPaint.getTextBounds(number, 0, number.length, textBounds) canvas.drawText(number, r, r + textBounds.height() / 2f, textPaint) } fun setChosen(isChosen: Boolean) { this.isChosen = isChosen invalidate() } fun getChosen(): Boolean { return this.isChosen } fun setNumber(num: String) { number = num } fun setTextColor(color: Int) { textPaint.color = color } fun setColors(strokeColor: Int, blockColor: Int) { strokePaint.color = strokeColor progressColor = strokeColor blockPaint.color = blockColor this.blockColor = blockColor invalidate() } fun setProgress( neoFinish: Int, weight: Float, panelData: ColorPanelStructure, l: FinishListener ) { // 预防onBindViewHolder()多次创建动画 if (finish < neoFinish) { panelData.finish += 1 // 创建前进动画 progressAnimator = ValueAnimator.ofFloat(finish * weight, neoFinish * weight) progressAnimator!!.setDuration(280) progressAnimator!!.interpolator = LinearInterpolator() progressAnimator!!.addUpdateListener { sweepAngle = it.animatedValue as Float invalidate() } progressAnimator!!.addListener( onEnd = { // 前进动画->上升动画->移除元素 l.stepProgress() }, ) // 赋新值 finish = neoFinish progressAnimator!!.start() } else { // 复用View sweepAngle = neoFinish * weight invalidate() } } interface FinishListener { fun stepProgress() } }
06-24
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值