本文共 16307 字,大约阅读时间需要 54 分钟。
package com.example.zxtext.diyUi;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.View;import com.example.zxtext.bean.PieData;import java.util.ArrayList;import java.util.List;import androidx.annotation.Nullable;public class PieView extends View { // 颜色表 (注意: 此处定义颜色使用的是ARGB,带Alpha通道的) private int[] mColors = { 0xFFCCFF00, 0xFF6495ED, 0xFFE32636, 0xFF800000, 0xFF808000, 0xFFFF8C69, 0xFF808080, 0xFFE6B800, 0xFF7CFC00}; //初始角度 private float startAngel = 0; //数据集合 private ListmPieData; //宽高 private int mWidth,mHeight; //画笔 private Paint mPaint; public PieView(Context context) { super(context); initPaint(); } public PieView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); initPaint(); } private void initPaint(){ mPaint = new Paint(); mPaint.setStyle(Paint.Style.FILL); mPaint.setAntiAlias(true); mPaint.setTextSize(10); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); mWidth = w; mHeight = h; } @Override protected void onDraw(Canvas canvas) { if(mPieData.size() == 0 || null == mPieData){ return; } float currentAngle = startAngel; canvas.translate(mWidth/2,mHeight/2); float r = (float) (Math.min(mWidth, mHeight) / 2 * 0.8); RectF rectF = new RectF(-r,-r,r,r); for(int i = 0;i mData) { this.mPieData = mData; initData(mData); invalidate(); // 刷新 } private void initData(ArrayList mData) { if(mData.size() == 0 || null == mData){ return; } float sumValue = 0; for(int i = 0;i
package com.example.zxtext.diyUi;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Path;import android.graphics.Rect;import android.text.TextPaint;import android.util.AttributeSet;import android.util.Log;import android.view.View;import androidx.annotation.Nullable;/** 模仿LPL选手六芒星图* 场均击杀、分均输出、生存能力、分均承伤、分均补刀、分均经济* */public class HexagramView extends View { private int count = 6; //数据个数 private float radius; //网格最大半径 private int centerX,centerY;//中心点 private float angle = (float) (Math.PI*2/count);//角度 private int layerCount; private String [] titles = { "场均击杀","分均输出","生存能力","分均承伤","分均补刀","分均经济"}; private double [] data = { 80,50,100,20,40,80}; private float maxValue = 100; private Paint textPaint;//文本画笔 private Paint viewPaint;//六边形画笔 private Paint valuePaint; //数据区画笔 public HexagramView(Context context) { this(context,null); init(); } public HexagramView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); init(); } private void init(){ textPaint = new Paint(); textPaint.setTextSize(10); textPaint.setColor(Color.BLACK); textPaint.setAntiAlias(true); viewPaint = new Paint(); viewPaint.setAntiAlias(true); viewPaint.setColor(Color.WHITE); viewPaint.setStrokeWidth(2); viewPaint.setStyle(Paint.Style.STROKE); valuePaint = new Paint(); valuePaint.setColor(Color.RED); valuePaint.setAlpha(125); valuePaint.setStrokeWidth(1); valuePaint.setStyle(Paint.Style.FILL_AND_STROKE); valuePaint.setAntiAlias(true); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { radius = Math.min(h,w)/2 * 0.9f;//半径 //中心坐标 centerX = w/2; centerY = h/2; postInvalidate(); super.onSizeChanged(w, h, oldw, oldh); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int width = MeasureSpec.getSize(widthMeasureSpec); int height = MeasureSpec.getSize(heightMeasureSpec); int th = Math.max(width,height); setMeasuredDimension(th,th); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //canvas.drawColor(Color.RED); drawPolygon(canvas); //drawLinkLine(canvas); drawValueShape(canvas); drawTextTitles(canvas); } /*画正多边形*/ private void drawPolygon(Canvas canvas){ //PI = π=180度 (180度 * 2 /6) 每个角的角度 // float angle = (float) (Math.PI*2/count);//角度 Path path = new Path(); float r = radius /(count-1);//每个六边形的半径 我们需要画5个 //开始绘制六边形 for(int i = 1;i0 && angle * i < Math.PI / 2) { //微调 分均输出 60 canvas.drawText(titles[i], x+70 ,y-65 , textPaint); } else if (angle * i >= Math.PI / 2 && angle * i < Math.PI) { canvas.drawText(titles[i], x+75, y+35, textPaint);//生存能力 120 } else if (angle * i >= Math.PI && angle * i <= Math.PI *1.2) { String txt = titles[i]; Rect bounds = new Rect(); textPaint.getTextBounds(txt, 0, txt.length(), bounds); float width = textPaint.measureText(txt); float height = bounds.bottom - bounds.top; //180 canvas.drawText(txt, x - width * 0.4f, y+95, textPaint); } else if (angle * i >= Math.PI && angle * i <= Math.PI *1.5 ) { String txt = titles[i]; float width = textPaint.measureText(txt);//240 canvas.drawText(txt, x-110, y+75, textPaint); }else if(angle * i >= Math.PI && angle * i <= Math.PI *2 ){ //300 String txt = titles[i]; canvas.drawText(txt, x-110, y-25, textPaint); } } } //重新设置数据 public void setData(double [] data){ this.data = data; invalidate(); } //需要绘制几边形 public void setCount(int count){ this.count =count; angle = (float) ((Math.PI *2)/count); invalidate(); } //设置层数 public void setLayerCount(int layerCount){ this.layerCount = layerCount; invalidate(); }}
package com.naman14.timber.widgets;import android.animation.ObjectAnimator;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Bitmap;import android.graphics.BitmapShader;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.ColorFilter;import android.graphics.Matrix;import android.graphics.Paint;import android.graphics.RectF;import android.graphics.Shader;import android.graphics.drawable.BitmapDrawable;import android.graphics.drawable.ColorDrawable;import android.graphics.drawable.Drawable;import android.net.Uri;import androidx.annotation.ColorRes;import androidx.annotation.DrawableRes;import androidx.annotation.RequiresApi;import androidx.core.content.ContextCompat;import android.os.Build;import android.util.AttributeSet;import android.view.animation.LinearInterpolator;import android.widget.ImageView;import com.naman14.timber.R;public class CircleImageView extends ImageView { private static final ScaleType SCALE_TYPE = ScaleType.CENTER_CROP; private static final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888; private static final int COLORDRAWABLE_DIMENSION = 2; private static final int DEFAULT_BORDER_WIDTH = 0; private static final int DEFAULT_BORDER_COLOR = Color.BLACK; private static final boolean DEFAULT_BORDER_OVERLAY = false; private final RectF mDrawableRect = new RectF(); private final RectF mBorderRect = new RectF(); private final Matrix mShaderMatrix = new Matrix(); private final Paint mBitmapPaint = new Paint(); private final Paint mBorderPaint = new Paint(); private int mBorderColor = DEFAULT_BORDER_COLOR; private int mBorderWidth = DEFAULT_BORDER_WIDTH; private Bitmap mBitmap; private BitmapShader mBitmapShader; private int mBitmapWidth; private int mBitmapHeight; private float mDrawableRadius; private float mBorderRadius; private ColorFilter mColorFilter; private boolean mReady; private boolean mSetupPending; private boolean mBorderOverlay; private ObjectAnimator mObjectAnimator; public static final int STATE_PLAYING =1;//正在播放 public static final int STATE_PAUSE =2;//暂停 public static final int STATE_STOP =3;//停止 public int state; public CircleImageView(Context context) { super(context); init(); } public CircleImageView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public CircleImageView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CircleImageView, defStyle, 0); mBorderWidth = a.getDimensionPixelSize(R.styleable.CircleImageView_border_width, DEFAULT_BORDER_WIDTH); mBorderColor = a.getColor(R.styleable.CircleImageView_border_color, DEFAULT_BORDER_COLOR); mBorderOverlay = a.getBoolean(R.styleable.CircleImageView_border_overlay, DEFAULT_BORDER_OVERLAY); a.recycle(); init(); } private void init() { super.setScaleType(SCALE_TYPE); mReady = true; if (mSetupPending) { setup(); mSetupPending = false; } state = STATE_STOP; mObjectAnimator = ObjectAnimator.ofFloat(this, "rotation", 0f, 359f);//添加旋转动画,旋转中心默认为控件中点 mObjectAnimator.setDuration(80000);//设置动画时间 mObjectAnimator.setInterpolator(new LinearInterpolator());//动画时间线性渐变 mObjectAnimator.setRepeatCount(ObjectAnimator.INFINITE); mObjectAnimator.setRepeatMode(ObjectAnimator.RESTART); } @RequiresApi(api = Build.VERSION_CODES.KITKAT) public void playMusic(){ if(state == STATE_STOP){ mObjectAnimator.start();//动画开始 state = STATE_PLAYING; }else if(state == STATE_PAUSE){ mObjectAnimator.resume();//动画重新开始 state = STATE_PLAYING; }else if(state == STATE_PLAYING){ mObjectAnimator.pause();//动画暂停 state = STATE_PAUSE; } } public void stopMusic(){ mObjectAnimator.end();//动画结束 state = STATE_STOP; } @Override public ScaleType getScaleType() { return SCALE_TYPE; } @Override public void setScaleType(ScaleType scaleType) { if (scaleType != SCALE_TYPE) { throw new IllegalArgumentException(String.format("ScaleType %s not supported.", scaleType)); } } @Override public void setAdjustViewBounds(boolean adjustViewBounds) { if (adjustViewBounds) { throw new IllegalArgumentException("adjustViewBounds not supported."); } } @Override protected void onDraw(Canvas canvas) { if (getDrawable() == null) { return; } canvas.drawCircle(getWidth() / 2, getHeight() / 2, mDrawableRadius, mBitmapPaint); if (mBorderWidth != 0) { canvas.drawCircle(getWidth() / 2, getHeight() / 2, mBorderRadius, mBorderPaint); } } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); setup(); } public int getBorderColor() { return mBorderColor; } public void setBorderColor(int borderColor) { if (borderColor == mBorderColor) { return; } mBorderColor = borderColor; mBorderPaint.setColor(mBorderColor); invalidate(); } public void setBorderColorResource(@ColorRes int borderColorRes) { setBorderColor(ContextCompat.getColor(getContext(), borderColorRes)); } public int getBorderWidth() { return mBorderWidth; } public void setBorderWidth(int borderWidth) { if (borderWidth == mBorderWidth) { return; } mBorderWidth = borderWidth; setup(); } public boolean isBorderOverlay() { return mBorderOverlay; } public void setBorderOverlay(boolean borderOverlay) { if (borderOverlay == mBorderOverlay) { return; } mBorderOverlay = borderOverlay; setup(); } @Override public void setImageBitmap(Bitmap bm) { super.setImageBitmap(bm); mBitmap = bm; setup(); } @Override public void setImageDrawable(Drawable drawable) { super.setImageDrawable(drawable); mBitmap = getBitmapFromDrawable(drawable); setup(); } @Override public void setImageResource(@DrawableRes int resId) { super.setImageResource(resId); mBitmap = getBitmapFromDrawable(getDrawable()); setup(); } @Override public void setImageURI(Uri uri) { super.setImageURI(uri); mBitmap = getBitmapFromDrawable(getDrawable()); setup(); } @Override public void setColorFilter(ColorFilter cf) { if (cf == mColorFilter) { return; } mColorFilter = cf; mBitmapPaint.setColorFilter(mColorFilter); invalidate(); } private Bitmap getBitmapFromDrawable(Drawable drawable) { if (drawable == null) { return null; } if (drawable instanceof BitmapDrawable) { return ((BitmapDrawable) drawable).getBitmap(); } try { Bitmap bitmap; if (drawable instanceof ColorDrawable) { bitmap = Bitmap.createBitmap(COLORDRAWABLE_DIMENSION, COLORDRAWABLE_DIMENSION, BITMAP_CONFIG); } else { bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), BITMAP_CONFIG); } Canvas canvas = new Canvas(bitmap); drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); drawable.draw(canvas); return bitmap; } catch (OutOfMemoryError e) { return null; } } private void setup() { if (!mReady) { mSetupPending = true; return; } if (mBitmap == null) { return; } mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); mBitmapPaint.setAntiAlias(true); mBitmapPaint.setShader(mBitmapShader); mBorderPaint.setStyle(Paint.Style.STROKE); mBorderPaint.setAntiAlias(true); mBorderPaint.setColor(mBorderColor); mBorderPaint.setStrokeWidth(mBorderWidth); mBitmapHeight = mBitmap.getHeight(); mBitmapWidth = mBitmap.getWidth(); mBorderRect.set(0, 0, getWidth(), getHeight()); mBorderRadius = Math.min((mBorderRect.height() - mBorderWidth) / 2, (mBorderRect.width() - mBorderWidth) / 2); mDrawableRect.set(mBorderRect); if (!mBorderOverlay) { mDrawableRect.inset(mBorderWidth, mBorderWidth); } mDrawableRadius = Math.min(mDrawableRect.height() / 2, mDrawableRect.width() / 2); updateShaderMatrix(); invalidate(); } private void updateShaderMatrix() { float scale; float dx = 0; float dy = 0; mShaderMatrix.set(null); if (mBitmapWidth * mDrawableRect.height() > mDrawableRect.width() * mBitmapHeight) { scale = mDrawableRect.height() / (float) mBitmapHeight; dx = (mDrawableRect.width() - mBitmapWidth * scale) * 0.5f; } else { scale = mDrawableRect.width() / (float) mBitmapWidth; dy = (mDrawableRect.height() - mBitmapHeight * scale) * 0.5f; } mShaderMatrix.setScale(scale, scale); mShaderMatrix.postTranslate((int) (dx + 0.5f) + mDrawableRect.left, (int) (dy + 0.5f) + mDrawableRect.top); mBitmapShader.setLocalMatrix(mShaderMatrix); }}
转载地址:http://thrii.baihongyu.com/