效果如上图所示
关键点:
1.需要解决的问题是 自定义view的 适配问题 在不同的 手机上 显示出来的效果一致
2.所需要的 工具类 一个转换工具 px与dp之间的互转
package com.shenlei.servicemoneynew.util; import android.content.Context; import android.util.DisplayMetrics; import android.util.Log; import android.view.WindowManager; /** * dp、sp 转换为 px 的工具类 * * @author fxsky 2012.11.12 * */ public class DisplayUtil { /** * 将px值转换为dip或dp值,保证尺寸大小不变 * * @param pxValue * @return */ public static int px2dip(Context context, float pxValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (pxValue / scale + 0.5f); } /** * 将dip或dp值转换为px值,保证尺寸大小不变 * * @param dipValue * @return */ public static int dip2px(Context context, float dipValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (dipValue * scale + 0.5f); } /** * 将dip或dp值转换为px值,保证尺寸大小不变 * * @param dipValue * @return */ public static float dip2pxFolat(Context context, float dipValue) { final float scale = context.getResources().getDisplayMetrics().density; return dipValue * scale + 0.5f; } /** * 将px值转换为sp值,保证文字大小不变 * * @param pxValue * @return */ public static int px2sp(Context context, float pxValue) { final float fontScale = context.getResources().getDisplayMetrics().scaledDensity; return (int) (pxValue / fontScale + 0.5f); } /** * 将sp值转换为px值,保证文字大小不变 * * @param spValue * @return */ public static int sp2px(Context context, float spValue) { final float fontScale = context.getResources().getDisplayMetrics().scaledDensity; return (int) (spValue * fontScale + 0.5f); } /** * *获取系数 * @return */ public static double getCoefficient(Context context) { double d = 1; DisplayMetrics dm = new DisplayMetrics(); WindowManager windowManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE); windowManager.getDefaultDisplay().getMetrics(dm); double diagonalPixels = Math.sqrt(Math.pow(dm.widthPixels, 2) + Math.pow(dm.heightPixels, 2)); double screenInches = diagonalPixels / (160 * dm.density); Log.d("wh", "Screen Size : " + diagonalPixels / (160 * dm.density)); if (screenInches >= 6.0) { d = screenInches/5.0; } return d; } }
3.自定义的圆环类的 代码如下所示:
package com.shenlei.servicemoneynew.view; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.RectF; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import android.widget.Toast; import com.shenlei.servicemoneynew.R; import com.shenlei.servicemoneynew.app.App; import com.shenlei.servicemoneynew.util.DisplayUtil; /** * Created by CY on 2018/3/26. * 自定义的圆形的view * 1.自定义的方法 */ public class MyCircleView extends View { //画笔 private Paint mPaint; private Paint mPaintTwo;//外层圆环 private Paint mPaintText;//写文字的画笔 private Paint mPaintTextTwo;//写百分比的画笔 private double mInnerProgress;//外部圆环的进度 //圆的半径 调用此方法 可以适配所有手机 保证不同型号手机的效果一致 private float mRadius= DisplayUtil.dip2pxFolat(getContext(),50f); //圆的圆心的x坐标 private float pointX ; //圆的圆心的Y坐标 private float pointY; // 文本的中心x轴位置 private int mXCenter; // 文本的中心y轴位置 private int mYCenter; // 百分比文本的宽度 private float mTxtWidth; // 描述文本的宽度 private float mTxtWidth2; //控制是否可以移动的变量 true的时候可以移动 private boolean moveable; public MyCircleView(Context context) { super(context); } public MyCircleView(Context context, AttributeSet attrs) { super(context, attrs); //构造一个paint 内层 mPaint = new Paint(); mPaint.setColor(getResources().getColor(R.color.targetColor1)); mPaint.setStrokeWidth(DisplayUtil.dip2pxFolat(getContext(),10f)); mPaint.setStyle(Paint.Style.STROKE); mPaint.setAntiAlias(true);//设置防锯齿 mPaint.setDither(true);//设置防抖 //构造一个paint 外层 mPaintTwo = new Paint(); mPaintTwo.setColor(getResources().getColor(R.color.targetColor2)); mPaintTwo.setStrokeWidth(DisplayUtil.dip2pxFolat(getContext(),10f)); mPaintTwo.setStyle(Paint.Style.STROKE); mPaintTwo.setAntiAlias(true);//设置防锯齿 mPaintTwo.setDither(true);//设置防抖 mPaintText = new Paint(); mPaintText.setAntiAlias(true); mPaintText.setStyle(Paint.Style.FILL); mPaintText.setColor(getResources().getColor(R.color.targetColor2));//设置黑色字体 mPaintText.setTextSize(DisplayUtil.dip2pxFolat(getContext(),16f));//设置字体大小 mPaintText.setDither(true);//设置防抖 mPaintTextTwo = new Paint(); mPaintTextTwo.setAntiAlias(true); mPaintTextTwo.setStyle(Paint.Style.FILL); mPaintTextTwo.setColor(getResources().getColor(R.color.targetColor2));//设置黑色字体 mPaintTextTwo.setTextSize(DisplayUtil.dip2pxFolat(getContext(),16f));//设置字体大小 mPaintTextTwo.setDither(true);//设置防抖 } public MyCircleView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); mXCenter = getWidth() / 2; mYCenter = getHeight() / 2; //根据圆心的坐标来绘制圆的位置的,而圆心的坐标,我们触摸屏幕的时候被我们修改了 canvas.drawCircle(mXCenter, mYCenter, mRadius, mPaint); /*canvas.drawCircle(mXCenter, mYCenter, mRadius + 20, mPaintTwo);*/ String txt2 = "已完成"; mTxtWidth2 = mPaintText.measureText(txt2, 0, txt2.length()); String txt1 = mInnerProgress+"%";//已完成百分比 mTxtWidth = mPaintTextTwo.measureText(txt1, 0, txt1.length()); canvas.drawText(txt1, mXCenter -mTxtWidth / 2, mYCenter + mTxtWidth/2, mPaintText); canvas.drawText(txt2, mXCenter - mTxtWidth2 / 2, mYCenter + mTxtWidth/8, mPaintTextTwo); if (mInnerProgress>0){ RectF oval = new RectF(); // 用于定义的圆弧的形状和大小的界限 oval.left = (mXCenter - DisplayUtil.dip2pxFolat(getContext(),60f)); oval.top = (mYCenter - DisplayUtil.dip2pxFolat(getContext(),60f)); oval.right = DisplayUtil.dip2pxFolat(getContext(),120f) + (mXCenter - DisplayUtil.dip2pxFolat(getContext(),60f)); oval.bottom = DisplayUtil.dip2pxFolat(getContext(),120f)+ (mYCenter - DisplayUtil.dip2pxFolat(getContext(),60f)); canvas.drawArc(oval, -90, ((float) mInnerProgress / 100) * 360, false, mPaintTwo); // }else if (mInnerProgress==0){ RectF oval = new RectF(); // 用于定义的圆弧的形状和大小的界限 oval.left = (mXCenter - DisplayUtil.dip2pxFolat(getContext(),60f)); oval.top = (mYCenter - DisplayUtil.dip2pxFolat(getContext(),60f)); oval.right = DisplayUtil.dip2pxFolat(getContext(),120f) + (mXCenter - DisplayUtil.dip2pxFolat(getContext(),60f)); oval.bottom = DisplayUtil.dip2pxFolat(getContext(),120f)+ (mYCenter - DisplayUtil.dip2pxFolat(getContext(),60f)); canvas.drawArc(oval, -90,360, false, mPaintTwo); // } } //要单点拖动,保证手指在圆上的时候才移动,我们需要判断触摸的位置 /* @Override public boolean onTouchEvent(MotionEvent event) { //手指触摸的x坐标 float touchX; //手指触摸的y坐标 float touchY; //event.getAction()判断事件的类型 switch (event.getAction()) { //按下的事件 case MotionEvent.ACTION_DOWN: touchX = event.getX(); touchY = event.getY(); if (touchX > pointX - mRadius && touchX < pointX + mRadius && touchY > pointY - mRadius && touchY < pointY + mRadius) { moveable = true; Toast.makeText(getContext(), "我按下了", Toast.LENGTH_LONG).show(); } else { moveable = false; } break; //移动的事件 case MotionEvent.ACTION_MOVE: if (moveable) { //重新设置一下圆心的位置, 把我们圆心的位置(pointX,pointY)设置成 // 当前触摸的位置(event.getX(),event.getY()) pointX = event.getX(); pointY = event.getY(); //去重新绘制, 会重新走onDraw()方法 invalidate(); } break; //抬起的事件 case MotionEvent.ACTION_UP: break; } return true; }*/ public void setInnerProgress(double progress) { mInnerProgress = progress; // invalidate(); postInvalidate(); } }
4.比较重要的点 就是 在自定义的ui类 里面 ,需要将 设置的字体大小 ,距离等 将写的具体数字或者dp ,
用工具类 转换 ,亲测有效。