class /** * Created by Venn on 2016/3/25. */ public class ShadowView extends View { private static final int RECT = 100;//shape rectangular private static final int CIRCLE = 101;//shape circle private static final int ARC = 110;//shape arc private Context mContext; private Paint mPaint; private int mShape;//shape what you want to draw private int mColor;//the color of the shape private boolean isStroke;//whether the shape is stroke private int border;//the width of the border private float radiusX, radiusY;//the radius of the shape(only use in rectangular) private float startAngle, endAngle;//the angle of the shape(only use in arc) private int gradientInterval;//the gradient interval of the color public ShadowView(Context context) { this(context, null); } public ShadowView(Context context, AttributeSet attrs) { super(context, attrs); mContext = context; TypedArray attributes = mContext.obtainStyledAttributes(attrs, R.styleable.ShadowView); //get enum by getInt(int index,int defaultValue) mShape = attributes.getInt(R.styleable.ShadowView_shadow_shape, RECT); mColor = attributes.getColor(R.styleable.ShadowView_shadow_color, Color.GREEN); isStroke = attributes.getBoolean(R.styleable.ShadowView_shadow_border_stroke, false); border = attributes.getInteger(R.styleable.ShadowView_shadow_border, 5); radiusX = attributes.getFloat(R.styleable.ShadowView_shadow_radius_x, 5.0f); radiusY = attributes.getFloat(R.styleable.ShadowView_shadow_radius_y, 5.0f); startAngle = attributes.getFloat(R.styleable.ShadowView_shadow_start_angle, 0); endAngle = attributes.getFloat(R.styleable.ShadowView_shadow_end_angle, 90); gradientInterval = attributes.getInteger(R.styleable.ShadowView_shadow_gradient_interval, 2); attributes.recycle(); init(); } private void init() { mPaint = new Paint(); mPaint.setColor(mColor); mPaint.setStyle(isStroke ? Paint.Style.STROKE : Paint.Style.FILL); mPaint.setStrokeWidth(border); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); //handle wrap_content, if not handle, wrap_content will equals match_parent int defaultDimension = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 200, mContext.getResources().getDisplayMetrics()); int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec); int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec); int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec); int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec); //according to the specMode calculate the display size if (widthSpecMode == MeasureSpec.AT_MOST && heightSpecMode == MeasureSpec.AT_MOST) { setMeasuredDimension(defaultDimension, defaultDimension); } else if (widthSpecMode == MeasureSpec.AT_MOST) { setMeasuredDimension(defaultDimension, heightSpecSize); } else if (heightSpecMode == MeasureSpec.AT_MOST) { setMeasuredDimension(widthSpecSize, defaultDimension); } } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //handle the padding, if not handle, the attribute won't effect int paddingLeft = getPaddingLeft(); int paddingRight = getPaddingRight(); int paddingTop = getPaddingTop(); int paddingBottom = getPaddingBottom(); //calculate the real size int left = paddingLeft; int right = getWidth() - paddingRight; int top = paddingTop; int bottom = getHeight() - paddingBottom; int len = Math.min(right - left, bottom - top) / gradientInterval; int space = 0; int drawColor = mColor; //TODO can't parse color(need survey) int alpha = mColor & Color.BLACK; int red = mColor & Color.RED; int green = mColor & Color.GREEN; int blue = mColor & Color.BLUE; switch (mShape) { case RECT: for (int i = 0; i < len; i++) { space = i * gradientInterval; //drawColor = Color.argb(alpha - space, red - space, green - space, blue - // space); mPaint.setColor(drawColor); RectF rect = new RectF(left + space, top + space, right - space, bottom - space); canvas.drawRoundRect(rect, radiusX, radiusY, mPaint); mPaint.setColor(Color.YELLOW); space += gradientInterval; RectF rectS = new RectF(left + space, top + space, right - space, bottom - space); canvas.drawRoundRect(rectS, radiusX, radiusY, mPaint); } break; case CIRCLE: for (int i = 0; i < len; i++) { space = i * gradientInterval; mPaint.setColor(drawColor); int width = right - left; int height = bottom - top; int xPoint = width / 2 + paddingLeft; int yPoint = height / 2 + paddingTop; canvas.drawCircle(xPoint, yPoint, Math.min(width, height) / 2 - space, mPaint); mPaint.setColor(Color.BLUE); space += gradientInterval; canvas.drawCircle(xPoint, yPoint, Math.min(width, height) / 2 - space, mPaint); } break; case ARC: for (int i = 0; i < len; i++) { space = i * gradientInterval; mPaint.setColor(drawColor); RectF aRect = new RectF(left, top, right, bottom); canvas.drawArc(aRect, startAngle, endAngle, isStroke, mPaint); mPaint.setColor(Color.RED); space += gradientInterval; RectF rectS = new RectF(left + space, top + space, right - space, bottom - space); canvas.drawArc(rectS, startAngle, endAngle, isStroke, mPaint); } break; } } // handle Touch event @Override public boolean onTouchEvent(MotionEvent event) { //get VelocityTracker(速度追踪器) what is used to get the slide speed VelocityTracker tracker = VelocityTracker.obtain(); tracker.addMovement(event); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: // get touchSlop(触摸溢出):the min distance that a touch should slid, // if the distance less than the touchSlop, think that's not a slide ViewConfiguration configuration = ViewConfiguration.get(mContext); int touchSlop = configuration.getScaledTouchSlop(); Log.i("touchSlop", "touchSlop:" + touchSlop); break; case MotionEvent.ACTION_MOVE: //calculate the speed in 1000ms(distance in 1000ms/1000ms) tracker.computeCurrentVelocity(1000); float xVelocity = tracker.getXVelocity(); float yVelocity = tracker.getYVelocity(); Log.i("velocity", "xVelocity:" + xVelocity + ",yVelocity:" + yVelocity); break; case MotionEvent.ACTION_UP: break; default: break; } //clear and recycle the VelocityTracker tracker.clear(); tracker.recycle(); return true; } private int getRandomColor() { Random random = new Random(255); int alpha = random.nextInt(); int red = random.nextInt(); int green = random.nextInt(); int blue = random.nextInt(); return Color.argb(alpha, red, green, blue); } } 格式<declare-styleable name="ShadowView"> <attr name="shadow_color" format="color"/> <attr name="shadow_border_stroke" format="boolean"/> <attr name="shadow_border" format="integer"/> <attr name="shadow_shape"> <enum name="RECT" value="100"/> <enum name="CIRCLE" value="101"/> <enum name="ARC" value="110"/> </attr> <attr name="shadow_radius_x" format="float"/> <attr name="shadow_radius_y" format="float"/> <attr name="shadow_start_angle" format="float"/> <attr name="shadow_end_angle" format="float"/> <attr name="shadow_gradient_interval" format="integer"/> </declare-styleable>
布局<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:orientation="vertical" > <com.example.venn.costumeview.ui.customer.ShadowView android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@android:color/holo_orange_light" android:padding="20dp" app:shadow_border="3" app:shadow_border_stroke="true" app:shadow_color="@android:color/holo_red_light" app:shadow_end_angle="180" app:shadow_gradient_interval="20" app:shadow_radius_x="10.0" app:shadow_radius_y="10.0" app:shadow_shape="CIRCLE" app:shadow_start_angle="30" /> </LinearLayout>
自定义view-二,使用枚举
最新推荐文章于 2022-02-03 19:37:54 发布