From d977a742f50f602b38d80be656bc46eb77985673 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=BA=86=E5=B9=B4?= <1713923044@qq.com> Date: Thu, 1 Jun 2017 18:07:06 +0800 Subject: [PATCH 1/2] =?UTF-8?q?1=E3=80=81=E5=AE=9E=E7=8E=B0=E6=8C=89?= =?UTF-8?q?=E9=92=AE=E7=82=B9=E5=87=BB=E6=95=88=E6=9E=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 4 + .../coorchice/supertextview/MainActivity.java | 53 +- .../SuperTextView/Adjuster/BtnAdjuster.java | 120 ++ .../Adjuster/RippleAdjuster.java | 2 +- app/src/main/res/color/button_color_sel.xml | 25 + app/src/main/res/layout/activity_main.xml | 6 +- app/src/main/res/values/colors.xml | 2 +- .../com/coorchice/library/SuperTextView.java | 1398 +++++++++-------- 8 files changed, 914 insertions(+), 696 deletions(-) create mode 100644 app/src/main/java/com/coorchice/supertextview/SuperTextView/Adjuster/BtnAdjuster.java create mode 100644 app/src/main/res/color/button_color_sel.xml diff --git a/app/build.gradle b/app/build.gradle index b760f41..934c23c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -15,6 +15,10 @@ android { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } + + debug{ + debuggable true + } } // compileOptions { // targetCompatibility 1.8 diff --git a/app/src/main/java/com/coorchice/supertextview/MainActivity.java b/app/src/main/java/com/coorchice/supertextview/MainActivity.java index 610657b..06272cf 100644 --- a/app/src/main/java/com/coorchice/supertextview/MainActivity.java +++ b/app/src/main/java/com/coorchice/supertextview/MainActivity.java @@ -1,6 +1,7 @@ package com.coorchice.supertextview; import com.coorchice.library.SuperTextView; +import com.coorchice.supertextview.SuperTextView.Adjuster.BtnAdjuster; import com.coorchice.supertextview.SuperTextView.Adjuster.MoveEffectAdjuster; import com.coorchice.supertextview.SuperTextView.Adjuster.OpportunityDemoAdjuster; import com.coorchice.supertextview.SuperTextView.Adjuster.RippleAdjuster; @@ -11,6 +12,7 @@ public class MainActivity extends AppCompatActivity { // +private SuperTextView stv_0; private SuperTextView stv_17; private SuperTextView stv_18; private SuperTextView stv_19; @@ -27,33 +29,36 @@ protected void onCreate(Bundle savedInstanceState) { private void initView() { findViews(); - stv_17.setAdjuster(new MoveEffectAdjuster()) - .setAutoAdjust(true) - .startAnim(); +// stv_0.setAdjuster(new BtnAdjuster(getResources().getColor(R.color.opacity_5_a58fed))); - stv_18.setAdjuster(new RippleAdjuster(getResources().getColor(R.color.opacity_5_a58fed))); - - OpportunityDemoAdjuster opportunityDemoAdjuster1 = new OpportunityDemoAdjuster(); - opportunityDemoAdjuster1.setOpportunity(SuperTextView.Adjuster.Opportunity.BEFORE_DRAWABLE); - stv_19.setAdjuster(opportunityDemoAdjuster1); - stv_19.setAutoAdjust(true); - - OpportunityDemoAdjuster opportunityDemoAdjuster2 = new OpportunityDemoAdjuster(); - opportunityDemoAdjuster2.setOpportunity(SuperTextView.Adjuster.Opportunity.BEFORE_TEXT); - stv_20.setAdjuster(opportunityDemoAdjuster2); - stv_20.setAutoAdjust(true); - - OpportunityDemoAdjuster opportunityDemoAdjuster3 = new OpportunityDemoAdjuster(); - opportunityDemoAdjuster3.setOpportunity(SuperTextView.Adjuster.Opportunity.AT_LAST); - stv_21.setAdjuster(opportunityDemoAdjuster3); - stv_21.setAutoAdjust(true); +// stv_17.setAdjuster(new MoveEffectAdjuster()) +// .setAutoAdjust(true) +// .startAnim(); +// +// stv_18.setAdjuster(new RippleAdjuster(getResources().getColor(R.color.opacity_5_a58fed))); +// +// OpportunityDemoAdjuster opportunityDemoAdjuster1 = new OpportunityDemoAdjuster(); +// opportunityDemoAdjuster1.setOpportunity(SuperTextView.Adjuster.Opportunity.BEFORE_DRAWABLE); +// stv_19.setAdjuster(opportunityDemoAdjuster1); +// stv_19.setAutoAdjust(true); +// +// OpportunityDemoAdjuster opportunityDemoAdjuster2 = new OpportunityDemoAdjuster(); +// opportunityDemoAdjuster2.setOpportunity(SuperTextView.Adjuster.Opportunity.BEFORE_TEXT); +// stv_20.setAdjuster(opportunityDemoAdjuster2); +// stv_20.setAutoAdjust(true); +// +// OpportunityDemoAdjuster opportunityDemoAdjuster3 = new OpportunityDemoAdjuster(); +// opportunityDemoAdjuster3.setOpportunity(SuperTextView.Adjuster.Opportunity.AT_LAST); +// stv_21.setAdjuster(opportunityDemoAdjuster3); +// stv_21.setAutoAdjust(true); } private void findViews() { - stv_17 = (SuperTextView) findViewById(R.id.stv_17); - stv_18 = (SuperTextView) findViewById(R.id.stv_18); - stv_19 = (SuperTextView) findViewById(R.id.stv_19); - stv_20 = (SuperTextView) findViewById(R.id.stv_20); - stv_21 = (SuperTextView) findViewById(R.id.stv_21); + stv_0 = (SuperTextView) findViewById(R.id.stv_0); +// stv_17 = (SuperTextView) findViewById(R.id.stv_17); +// stv_18 = (SuperTextView) findViewById(R.id.stv_18); +// stv_19 = (SuperTextView) findViewById(R.id.stv_19); +// stv_20 = (SuperTextView) findViewById(R.id.stv_20); +// stv_21 = (SuperTextView) findViewById(R.id.stv_21); } } diff --git a/app/src/main/java/com/coorchice/supertextview/SuperTextView/Adjuster/BtnAdjuster.java b/app/src/main/java/com/coorchice/supertextview/SuperTextView/Adjuster/BtnAdjuster.java new file mode 100644 index 0000000..48b7012 --- /dev/null +++ b/app/src/main/java/com/coorchice/supertextview/SuperTextView/Adjuster/BtnAdjuster.java @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2017 CoorChice + *

+ * Licensed under the Apache License, Version 2.0 (the "License");you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + *

+ * Last modified 17-5-23 上午9:41 + */ + +package com.coorchice.supertextview.SuperTextView.Adjuster; + +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.PorterDuff; +import android.graphics.PorterDuffXfermode; +import android.graphics.RectF; +import android.view.MotionEvent; + +import com.coorchice.library.SuperTextView; +import com.coorchice.supertextview.Utils.LogUtils; + +/** + * Project Name:SuperTextView + * Author:CoorChice + * Date:2017/4/17 + * Notes: + */ + +public class BtnAdjuster extends SuperTextView.Adjuster { + private static final float DEFAULT_RADIUS = 50; + + private PorterDuffXfermode xfermode = new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP); + private int rippleColor = Color.parseColor("#ce938d"); + private float x = -1; + private float y = -1; + private Paint paint; + private float density; + private float radius = DEFAULT_RADIUS; + private RectF rectF = new RectF(); + private float velocity = 2f; + + + + public BtnAdjuster(int rippleColor) { + this.rippleColor = rippleColor; + initPaint(); + } + + private void initPaint() { + paint = new Paint(); + paint.setAntiAlias(true); + paint.setColor(rippleColor); + } + + + @Override + protected void adjust(SuperTextView v, Canvas canvas) { + int width = v.getWidth(); + int height = v.getHeight(); + + if (density == 0) { + density = v.getResources().getDisplayMetrics().density; + } + if (x == -1) { + x = width / 2; + } + if (y == -1) { + x = height / 2; + + } + if (radius < ((float) width) * 1.1) { + radius = (radius + velocity); + } + rectF.setEmpty(); + rectF.set(0, 0, width, height); + // 创建一个图层,在图层上演示图形混合后的效果 + int sc = canvas.saveLayer(0, 0, width, height, null, Canvas.MATRIX_SAVE_FLAG | + Canvas.CLIP_SAVE_FLAG | + Canvas.HAS_ALPHA_LAYER_SAVE_FLAG | + Canvas.FULL_COLOR_LAYER_SAVE_FLAG | + Canvas.CLIP_TO_LAYER_SAVE_FLAG); + paint.setColor(v.getSolid()); + canvas.drawRoundRect(rectF, height / 2, height / 2, paint); + paint.setXfermode(xfermode); + paint.setColor(rippleColor); + canvas.drawCircle(x, y, radius * density, paint); + paint.setXfermode(null); + canvas.restoreToCount(sc); + } + + @Override + public boolean onTouch(SuperTextView v, MotionEvent event) { + int action = event.getAction(); + LogUtils.e("action = " + action); + switch (action) { + case MotionEvent.ACTION_DOWN: + x = event.getX(); + y = event.getY(); + radius = DEFAULT_RADIUS; + v.setAutoAdjust(true); + v.startAnim(); + break; + case MotionEvent.ACTION_UP: + case MotionEvent.ACTION_CANCEL: + v.stopAnim(); + v.setAutoAdjust(false); + LogUtils.e("stopAnim()"); + break; + } + return true; + } +} diff --git a/app/src/main/java/com/coorchice/supertextview/SuperTextView/Adjuster/RippleAdjuster.java b/app/src/main/java/com/coorchice/supertextview/SuperTextView/Adjuster/RippleAdjuster.java index 0fa1e44..f9bf836 100644 --- a/app/src/main/java/com/coorchice/supertextview/SuperTextView/Adjuster/RippleAdjuster.java +++ b/app/src/main/java/com/coorchice/supertextview/SuperTextView/Adjuster/RippleAdjuster.java @@ -35,7 +35,7 @@ */ public class RippleAdjuster extends SuperTextView.Adjuster { - private static final float DEFAULT_RADIUS = 50; + private static final float DEFAULT_RADIUS = 10; private PorterDuffXfermode xfermode = new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP); private int rippleColor = Color.parseColor("#ce938d"); diff --git a/app/src/main/res/color/button_color_sel.xml b/app/src/main/res/color/button_color_sel.xml new file mode 100644 index 0000000..45d50a5 --- /dev/null +++ b/app/src/main/res/color/button_color_sel.xml @@ -0,0 +1,25 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 7ad730b..c9ff154 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -33,10 +33,10 @@ android:textColor="@color/white" android:textSize="14sp" app:corner="10dp" - app:solid="@color/opacity_5_red" + app:solid="@color/button_color_sel" /> - + />--> diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 0cca382..40b6a9d 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -84,7 +84,7 @@ #ccA233BE #A233BE - #80A58FED + #FFFF00 diff --git a/library/src/main/java/com/coorchice/library/SuperTextView.java b/library/src/main/java/com/coorchice/library/SuperTextView.java index addb581..f84d196 100644 --- a/library/src/main/java/com/coorchice/library/SuperTextView.java +++ b/library/src/main/java/com/coorchice/library/SuperTextView.java @@ -1,5 +1,3 @@ - - /* * Copyright (C) 2017 CoorChice *

@@ -21,6 +19,7 @@ import android.annotation.TargetApi; import android.content.Context; +import android.content.res.ColorStateList; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Color; @@ -36,761 +35,826 @@ public class SuperTextView extends TextView { - // Some Property Default Value - private static final float DEFAULT_CORNER = 0f; - private static final int DEFAULT_SOLID = Color.WHITE; - private static final float DEFAULT_STROKE_WIDTH = 0f; - private static final int DEFAULT_STROKE_COLOR = Color.BLACK; - private static final int DEFAULT_STATE_DRAWABLE_MODE = 4; - private static final int DEFAULT_TEXT_STROKE_COLOR = Color.BLACK; - private static final int DEFAULT_TEXT_FILL_COLOR = Color.BLACK; - private static final float DEFAULT_TEXT_STROKE_WIDTH = 0f; - - private float corner; - private boolean leftTopCornerEnable; - private boolean rightTopCornerEnable; - private boolean leftBottomCornerEnable; - private boolean rightBottomCornerEnable; - private int solid; - private float strokeWidth; - private int strokeColor; - private int stateDrawableMode; - private boolean isShowState; - - private Paint paint; - private int width; - private int height; - private Drawable drawable; - private float density; - private boolean autoAdjust; - private Adjuster adjuster; - private boolean textStroke; - private int textStrokeColor; - private int textFillColor; - private float textStrokeWidth; - private boolean runnable = false; - private boolean needRun = false; - private Thread animThread; - private Path strokeWidthPath; - private Path solidPath; - private RectF strokeLineRectF; - private RectF solidRectF; - private float leftTopCorner[] = new float[2]; - private float rightTopCorner[] = new float[2]; - private float leftBottomCorner[] = new float[2]; - private float rightBottomCorner[] = new float[2]; - private float corners[] = new float[8]; - private float[] drawableBounds = new float[4]; - private float drawableWidth; - private float drawableHeight; - private float drawablePaddingLeft; - private float drawablePaddingTop; - private boolean cacheRunnableState; - private boolean cacheNeedRunState; - private int frameRate = 60; - private Runnable invalidate; - - - public SuperTextView(Context context) { - super(context); - init(null); - } - - public SuperTextView(Context context, AttributeSet attrs) { - super(context, attrs); - init(attrs); - } - - public SuperTextView(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - init(attrs); - } - - @TargetApi(Build.VERSION_CODES.LOLLIPOP) - public SuperTextView(Context context, AttributeSet attrs, int defStyleAttr, - int defStyleRes) { - super(context, attrs, defStyleAttr, defStyleRes); - init(attrs); - } - - private void init(AttributeSet attrs) { - density = getContext().getResources().getDisplayMetrics().density; - initAttrs(attrs); - paint = new Paint(); - initPaint(); - } - - private void initAttrs(AttributeSet attrs) { - if (attrs != null) { - TypedArray typedArray = - getContext().obtainStyledAttributes(attrs, R.styleable.SuperTextView); - corner = typedArray.getDimension(R.styleable.SuperTextView_corner, DEFAULT_CORNER); - leftTopCornerEnable = - typedArray.getBoolean(R.styleable.SuperTextView_left_top_corner, false); - rightTopCornerEnable = - typedArray.getBoolean(R.styleable.SuperTextView_right_top_corner, false); - leftBottomCornerEnable = - typedArray.getBoolean(R.styleable.SuperTextView_left_bottom_corner, false); - rightBottomCornerEnable = - typedArray.getBoolean(R.styleable.SuperTextView_right_bottom_corner, false); - solid = typedArray.getColor(R.styleable.SuperTextView_solid, DEFAULT_SOLID); - strokeWidth = typedArray.getDimension(R.styleable.SuperTextView_stroke_width, - DEFAULT_STROKE_WIDTH); - strokeColor = - typedArray.getColor(R.styleable.SuperTextView_stroke_color, DEFAULT_STROKE_COLOR); - drawable = typedArray.getDrawable(R.styleable.SuperTextView_state_drawable); - drawableWidth = - typedArray.getDimension(R.styleable.SuperTextView_state_drawable_width, 0); - drawableHeight = - typedArray.getDimension(R.styleable.SuperTextView_state_drawable_height, 0); - drawablePaddingLeft = - typedArray.getDimension(R.styleable.SuperTextView_state_drawable_padding_left, 0); - drawablePaddingTop = - typedArray.getDimension(R.styleable.SuperTextView_state_drawable_padding_top, 0); - isShowState = typedArray.getBoolean(R.styleable.SuperTextView_isShowState, false); - stateDrawableMode = typedArray.getInteger(R.styleable.SuperTextView_state_drawable_mode, - DEFAULT_STATE_DRAWABLE_MODE); - textStroke = typedArray.getBoolean(R.styleable.SuperTextView_text_stroke, false); - textStrokeColor = typedArray.getColor(R.styleable.SuperTextView_text_stroke_color, - DEFAULT_TEXT_STROKE_COLOR); - textFillColor = typedArray.getColor(R.styleable.SuperTextView_text_fill_color, - DEFAULT_TEXT_FILL_COLOR); - textStrokeWidth = typedArray.getDimension(R.styleable.SuperTextView_text_stroke_width, - DEFAULT_TEXT_STROKE_WIDTH); - autoAdjust = typedArray.getBoolean(R.styleable.SuperTextView_autoAdjust, false); - typedArray.recycle(); - } - } - - private void initPaint() { - paint.reset(); - paint.setAntiAlias(true); - paint.setDither(true); - } - - @Override - protected void onSizeChanged(int w, int h, int oldw, int oldh) { - super.onSizeChanged(w, h, oldw, oldh); - } - - @Override - protected void onDraw(Canvas canvas) { - width = getWidth(); - height = getHeight(); - drawStrokeLine(canvas); - drawSolid(canvas); - isNeedToAdjust(canvas, Adjuster.Opportunity.BEFORE_DRAWABLE); - drawStateDrawable(canvas); - isNeedToAdjust(canvas, Adjuster.Opportunity.BEFORE_TEXT); - if (textStroke) { - getPaint().setStyle(Paint.Style.STROKE); - setTextColor(textStrokeColor); - getPaint().setFakeBoldText(true); - getPaint().setStrokeWidth(textStrokeWidth); - super.onDraw(canvas); - getPaint().setStyle(Paint.Style.FILL); - getPaint().setFakeBoldText(false); - setTextColor(textFillColor); - } - super.onDraw(canvas); - isNeedToAdjust(canvas, Adjuster.Opportunity.AT_LAST); - } - - private void drawStrokeLine(Canvas canvas) { - if (strokeWidth > 0) { - if (strokeWidthPath == null) { - strokeWidthPath = new Path(); - } else { - strokeWidthPath.reset(); - } - if (strokeLineRectF == null) { - strokeLineRectF = new RectF(); - } else { - strokeLineRectF.setEmpty(); - } - strokeLineRectF.set(strokeWidth / 2, strokeWidth / 2, width - strokeWidth / 2, - height - strokeWidth / 2); - getCorners(corner); - strokeWidthPath.addRoundRect(strokeLineRectF, corners, Path.Direction.CW); - initPaint(); - paint.setStyle(Paint.Style.STROKE); - paint.setColor(strokeColor); - paint.setStrokeWidth(strokeWidth); - canvas.drawPath(strokeWidthPath, paint); - } - } - - private void drawSolid(Canvas canvas) { - if (solidPath == null) { - solidPath = new Path(); - } else { - solidPath.reset(); - } - if (solidRectF == null) { - solidRectF = new RectF(); - } else { - solidRectF.setEmpty(); - } - solidRectF.set(strokeWidth, strokeWidth, width - strokeWidth, height - strokeWidth); - getCorners(corner - strokeWidth / 2); - solidPath.addRoundRect(solidRectF, corners, Path.Direction.CW); - - initPaint(); - paint.setStyle(Paint.Style.FILL); - paint.setColor(solid); - canvas.drawPath(solidPath, paint); - } - - private float[] getCorners(float corner) { - leftTopCorner[0] = 0; - leftTopCorner[1] = 0; - rightTopCorner[0] = 0; - rightTopCorner[1] = 0; - leftBottomCorner[0] = 0; - leftBottomCorner[1] = 0; - rightBottomCorner[0] = 0; - rightBottomCorner[1] = 0; - if (this.leftTopCornerEnable || this.rightTopCornerEnable || this.leftBottomCornerEnable - || this.rightBottomCornerEnable) { - if (this.leftTopCornerEnable) { - leftTopCorner[0] = corner; - leftTopCorner[1] = corner; - } - if (this.rightTopCornerEnable) { - rightTopCorner[0] = corner; - rightTopCorner[1] = corner; - } - if (this.leftBottomCornerEnable) { - leftBottomCorner[0] = corner; - leftBottomCorner[1] = corner; - } - if (this.rightBottomCornerEnable) { - rightBottomCorner[0] = corner; - rightBottomCorner[1] = corner; - } - } else { - leftTopCorner[0] = corner; - leftTopCorner[1] = corner; - rightTopCorner[0] = corner; - rightTopCorner[1] = corner; - leftBottomCorner[0] = corner; - leftBottomCorner[1] = corner; - rightBottomCorner[0] = corner; - rightBottomCorner[1] = corner; - } - corners[0] = leftTopCorner[0]; - corners[1] = leftTopCorner[1]; - corners[2] = rightTopCorner[0]; - corners[3] = rightTopCorner[1]; - corners[4] = rightBottomCorner[0]; - corners[5] = rightBottomCorner[1]; - corners[6] = leftBottomCorner[0]; - corners[7] = leftBottomCorner[1]; - return corners; - } - - private void drawStateDrawable(Canvas canvas) { - if (drawable != null && isShowState) { - getDrawableBounds(); - drawable.setBounds((int) drawableBounds[0], (int) drawableBounds[1], (int) drawableBounds[2], - (int) drawableBounds[3]); - drawable.draw(canvas); - } - } - - private float[] getDrawableBounds() { - for (int i = 0; i < drawableBounds.length; i++) { - drawableBounds[i] = 0; - } - drawableWidth = (drawableWidth == 0 ? width / 2f : drawableWidth); - drawableHeight = (drawableHeight == 0 ? height / 2f : drawableHeight); - switch (DrawableMode.valueOf(stateDrawableMode)) { - case LEFT: // left - drawableBounds[0] = 0 + drawablePaddingLeft; - drawableBounds[1] = height / 2f - drawableHeight / 2f + drawablePaddingTop; - drawableBounds[2] = drawableBounds[0] + drawableWidth; - drawableBounds[3] = drawableBounds[1] + drawableHeight; - break; - case TOP: // top - drawableBounds[0] = width / 2f - drawableWidth / 2f + drawablePaddingLeft; - drawableBounds[1] = 0 + drawablePaddingTop; - drawableBounds[2] = drawableBounds[0] + drawableWidth; - drawableBounds[3] = drawableBounds[1] + drawableHeight; - break; - case RIGHT: // right - drawableBounds[0] = width - drawableWidth + drawablePaddingLeft; - drawableBounds[1] = height / 2 - drawableHeight / 2 + drawablePaddingTop; - drawableBounds[2] = drawableBounds[0] + drawableWidth; - drawableBounds[3] = drawableBounds[1] + drawableHeight; - break; - case BOTTOM: // bottom - drawableBounds[0] = width / 2f - drawableWidth / 2f + drawablePaddingLeft; - drawableBounds[1] = height - drawableHeight + drawablePaddingTop; - drawableBounds[2] = drawableBounds[0] + drawableWidth; - drawableBounds[3] = drawableBounds[1] + drawableHeight; - break; - case CENTER: // center - drawableBounds[0] = width / 2f - drawableWidth / 2f + drawablePaddingLeft; - drawableBounds[1] = height / 2 - drawableHeight / 2 + drawablePaddingTop; - drawableBounds[2] = drawableBounds[0] + drawableWidth; - drawableBounds[3] = drawableBounds[1] + drawableHeight; - break; - case FILL: // fill - drawableBounds[0] = 0; - drawableBounds[1] = 0; - drawableBounds[2] = width; - drawableBounds[3] = height; - break; - case LEFT_TOP: // leftTop - drawableBounds[0] = 0 + drawablePaddingLeft; - drawableBounds[1] = 0 + drawablePaddingTop; - drawableBounds[2] = drawableBounds[0] + drawableWidth; - drawableBounds[3] = drawableBounds[1] + drawableHeight; - break; - case RIGHT_TOP: // rightTop - drawableBounds[0] = width - drawableWidth + drawablePaddingLeft; - drawableBounds[1] = 0 + drawablePaddingTop; - drawableBounds[2] = drawableBounds[0] + drawableWidth; - drawableBounds[3] = drawableBounds[1] + drawableHeight; - break; - case LEFT_BOTTOM: // leftBottom - drawableBounds[0] = 0 + drawablePaddingLeft; - drawableBounds[1] = height - drawableHeight + drawablePaddingTop; - drawableBounds[2] = drawableBounds[0] + drawableWidth; - drawableBounds[3] = drawableBounds[1] + drawableHeight; - break; - case RIGHT_BOTTOM: // rightBottom - drawableBounds[0] = width - drawableWidth + drawablePaddingLeft; - drawableBounds[1] = height - drawableHeight + drawablePaddingTop; - drawableBounds[2] = drawableBounds[0] + drawableWidth; - drawableBounds[3] = drawableBounds[1] + drawableHeight; - break; - } - - return drawableBounds; - } - - private void isNeedToAdjust(Canvas canvas, Adjuster.Opportunity currentOpportunity) { - if (autoAdjust) { - if (adjuster == null) { - setAdjuster(new DefaultAdjuster()); - } else { - if (currentOpportunity == adjuster.getOpportunity()) { - adjuster.adjust(this, canvas); + // Some Property Default Value + private static final float DEFAULT_CORNER = 0f; + private static final int DEFAULT_SOLID = Color.WHITE; + private static final float DEFAULT_STROKE_WIDTH = 0f; + private static final int DEFAULT_STROKE_COLOR = Color.BLACK; + private static final int DEFAULT_STATE_DRAWABLE_MODE = 4; + private static final int DEFAULT_TEXT_STROKE_COLOR = Color.BLACK; + private static final int DEFAULT_TEXT_FILL_COLOR = Color.BLACK; + private static final float DEFAULT_TEXT_STROKE_WIDTH = 0f; + + private float corner; + private boolean leftTopCornerEnable; + private boolean rightTopCornerEnable; + private boolean leftBottomCornerEnable; + private boolean rightBottomCornerEnable; + // private int solid; + private int bgColorNormal; + private int bgColorPressed; + private int bgColorDisable; + private int strokeColorNormal; + private int strokeColorPressed; + private int strokeColorDisable; + private float strokeWidth; + // private int strokeColor; + private int stateDrawableMode; + private boolean isShowState; + + private Paint paint; + private int width; + private int height; + private Drawable drawable; + private float density; + private boolean autoAdjust; + private Adjuster adjuster; + private boolean textStroke; + private int textStrokeColor; + private int textFillColor; + private float textStrokeWidth; + private boolean runnable = false; + private boolean needRun = false; + private Thread animThread; + private Path strokeWidthPath; + private Path solidPath; + private RectF strokeLineRectF; + private RectF solidRectF; + private float leftTopCorner[] = new float[2]; + private float rightTopCorner[] = new float[2]; + private float leftBottomCorner[] = new float[2]; + private float rightBottomCorner[] = new float[2]; + private float corners[] = new float[8]; + private float[] drawableBounds = new float[4]; + private float drawableWidth; + private float drawableHeight; + private float drawablePaddingLeft; + private float drawablePaddingTop; + private boolean cacheRunnableState; + private boolean cacheNeedRunState; + private int frameRate = 60; + private Runnable invalidate; + private boolean pressed = false; + + + public SuperTextView(Context context) { + super(context); + init(null); + } + + public SuperTextView(Context context, AttributeSet attrs) { + super(context, attrs); + init(attrs); + } + + public SuperTextView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + init(attrs); + } + + @TargetApi(Build.VERSION_CODES.LOLLIPOP) + public SuperTextView(Context context, AttributeSet attrs, int defStyleAttr, + int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + init(attrs); + } + + private void init(AttributeSet attrs) { + density = getContext().getResources().getDisplayMetrics().density; + initAttrs(attrs); + paint = new Paint(); + initPaint(); + } + + private void initAttrs(AttributeSet attrs) { + if (attrs != null) { + TypedArray typedArray = + getContext().obtainStyledAttributes(attrs, R.styleable.SuperTextView); + corner = typedArray.getDimension(R.styleable.SuperTextView_corner, DEFAULT_CORNER); + leftTopCornerEnable = + typedArray.getBoolean(R.styleable.SuperTextView_left_top_corner, false); + rightTopCornerEnable = + typedArray.getBoolean(R.styleable.SuperTextView_right_top_corner, false); + leftBottomCornerEnable = + typedArray.getBoolean(R.styleable.SuperTextView_left_bottom_corner, false); + rightBottomCornerEnable = + typedArray.getBoolean(R.styleable.SuperTextView_right_bottom_corner, false); + bgColorNormal = typedArray.getColor(R.styleable.SuperTextView_solid, DEFAULT_SOLID); + strokeWidth = typedArray.getDimension(R.styleable.SuperTextView_stroke_width, + DEFAULT_STROKE_WIDTH); + strokeColorNormal = + typedArray.getColor(R.styleable.SuperTextView_stroke_color, DEFAULT_STROKE_COLOR); + drawable = typedArray.getDrawable(R.styleable.SuperTextView_state_drawable); + drawableWidth = + typedArray.getDimension(R.styleable.SuperTextView_state_drawable_width, 0); + drawableHeight = + typedArray.getDimension(R.styleable.SuperTextView_state_drawable_height, 0); + drawablePaddingLeft = + typedArray.getDimension(R.styleable.SuperTextView_state_drawable_padding_left, 0); + drawablePaddingTop = + typedArray.getDimension(R.styleable.SuperTextView_state_drawable_padding_top, 0); + isShowState = typedArray.getBoolean(R.styleable.SuperTextView_isShowState, false); + stateDrawableMode = typedArray.getInteger(R.styleable.SuperTextView_state_drawable_mode, + DEFAULT_STATE_DRAWABLE_MODE); + textStroke = typedArray.getBoolean(R.styleable.SuperTextView_text_stroke, false); + textStrokeColor = typedArray.getColor(R.styleable.SuperTextView_text_stroke_color, + DEFAULT_TEXT_STROKE_COLOR); + textFillColor = typedArray.getColor(R.styleable.SuperTextView_text_fill_color, + DEFAULT_TEXT_FILL_COLOR); + textStrokeWidth = typedArray.getDimension(R.styleable.SuperTextView_text_stroke_width, + DEFAULT_TEXT_STROKE_WIDTH); + autoAdjust = typedArray.getBoolean(R.styleable.SuperTextView_autoAdjust, false); + + ColorStateList bgColors = typedArray.getColorStateList(R.styleable.SuperTextView_solid); + if (bgColors != null) { + bgColorNormal = bgColors.getColorForState(new int[]{android.R.attr.state_enabled}, 0); + bgColorPressed = bgColors.getColorForState(new int[]{android.R.attr.state_pressed}, bgColorNormal); + bgColorDisable = bgColors.getColorForState(new int[]{-android.R.attr.state_enabled}, bgColorNormal); + } else { +// bgColorNormal = Color.parseColor("#ffff0000"); + bgColorPressed = Color.parseColor("#0cff0000"); + bgColorDisable = Color.parseColor("#06ff0000"); + } + + ColorStateList strokeColors = typedArray.getColorStateList(R.styleable.SuperTextView_stroke_color); + if (strokeColors != null) { + strokeColorNormal = strokeColors.getColorForState(new int[]{android.R.attr.state_enabled}, 0); + strokeColorPressed = strokeColors.getColorForState(new int[]{android.R.attr.state_pressed}, strokeColorNormal); + strokeColorDisable = strokeColors.getColorForState(new int[]{-android.R.attr.state_enabled}, strokeColorNormal); + } else { +// strokeColorNormal = Color.parseColor("#00000000"); + strokeColorPressed = Color.parseColor("#00000000"); + strokeColorDisable = Color.parseColor("#00000000"); + } + + + typedArray.recycle(); } - } } - } - public float getCorner() { - return corner; - } + private void initPaint() { + paint.reset(); + paint.setAntiAlias(true); + paint.setDither(true); + } - public SuperTextView setCorner(float corner) { - this.corner = corner; - postInvalidate(); + @Override + protected void onSizeChanged(int w, int h, int oldw, int oldh) { + super.onSizeChanged(w, h, oldw, oldh); + } - return this; - } + @Override + protected void onDraw(Canvas canvas) { + width = getWidth(); + height = getHeight(); + drawStrokeLine(canvas); + drawSolid(canvas); + isNeedToAdjust(canvas, Adjuster.Opportunity.BEFORE_DRAWABLE); + drawStateDrawable(canvas); + isNeedToAdjust(canvas, Adjuster.Opportunity.BEFORE_TEXT); + if (textStroke) { + getPaint().setStyle(Paint.Style.STROKE); + setTextColor(textStrokeColor); + getPaint().setFakeBoldText(true); + getPaint().setStrokeWidth(textStrokeWidth); + super.onDraw(canvas); + getPaint().setStyle(Paint.Style.FILL); + getPaint().setFakeBoldText(false); + setTextColor(textFillColor); + } + super.onDraw(canvas); + isNeedToAdjust(canvas, Adjuster.Opportunity.AT_LAST); + } - public int getSolid() { - return solid; - } + private void drawStrokeLine(Canvas canvas) { + if (strokeWidth > 0) { + if (strokeWidthPath == null) { + strokeWidthPath = new Path(); + } else { + strokeWidthPath.reset(); + } + if (strokeLineRectF == null) { + strokeLineRectF = new RectF(); + } else { + strokeLineRectF.setEmpty(); + } + strokeLineRectF.set(strokeWidth / 2, strokeWidth / 2, width - strokeWidth / 2, + height - strokeWidth / 2); + getCorners(corner); + strokeWidthPath.addRoundRect(strokeLineRectF, corners, Path.Direction.CW); + initPaint(); + paint.setStyle(Paint.Style.STROKE); + if (isEnabled()) { + if (pressed) { + paint.setColor(strokeColorPressed); + } else { + paint.setColor(strokeColorNormal); + } + } else { + paint.setColor(strokeColorDisable); + } + paint.setStrokeWidth(strokeWidth); + canvas.drawPath(strokeWidthPath, paint); + } + } - public SuperTextView setSolid(int solid) { - this.solid = solid; - postInvalidate(); + private void drawSolid(Canvas canvas) { + if (solidPath == null) { + solidPath = new Path(); + } else { + solidPath.reset(); + } + if (solidRectF == null) { + solidRectF = new RectF(); + } else { + solidRectF.setEmpty(); + } + solidRectF.set(strokeWidth, strokeWidth, width - strokeWidth, height - strokeWidth); + getCorners(corner - strokeWidth / 2); + solidPath.addRoundRect(solidRectF, corners, Path.Direction.CW); + + initPaint(); + paint.setStyle(Paint.Style.FILL); + if (isEnabled()) { + if (pressed) { + paint.setColor(bgColorPressed); + } else { + paint.setColor(bgColorNormal); + } + } else { + paint.setColor(bgColorDisable); + } + canvas.drawPath(solidPath, paint); + } - return this; - } + private float[] getCorners(float corner) { + leftTopCorner[0] = 0; + leftTopCorner[1] = 0; + rightTopCorner[0] = 0; + rightTopCorner[1] = 0; + leftBottomCorner[0] = 0; + leftBottomCorner[1] = 0; + rightBottomCorner[0] = 0; + rightBottomCorner[1] = 0; + if (this.leftTopCornerEnable || this.rightTopCornerEnable || this.leftBottomCornerEnable + || this.rightBottomCornerEnable) { + if (this.leftTopCornerEnable) { + leftTopCorner[0] = corner; + leftTopCorner[1] = corner; + } + if (this.rightTopCornerEnable) { + rightTopCorner[0] = corner; + rightTopCorner[1] = corner; + } + if (this.leftBottomCornerEnable) { + leftBottomCorner[0] = corner; + leftBottomCorner[1] = corner; + } + if (this.rightBottomCornerEnable) { + rightBottomCorner[0] = corner; + rightBottomCorner[1] = corner; + } + } else { + leftTopCorner[0] = corner; + leftTopCorner[1] = corner; + rightTopCorner[0] = corner; + rightTopCorner[1] = corner; + leftBottomCorner[0] = corner; + leftBottomCorner[1] = corner; + rightBottomCorner[0] = corner; + rightBottomCorner[1] = corner; + } + corners[0] = leftTopCorner[0]; + corners[1] = leftTopCorner[1]; + corners[2] = rightTopCorner[0]; + corners[3] = rightTopCorner[1]; + corners[4] = rightBottomCorner[0]; + corners[5] = rightBottomCorner[1]; + corners[6] = leftBottomCorner[0]; + corners[7] = leftBottomCorner[1]; + return corners; + } - public float getStrokeWidth() { - return strokeWidth; - } + private void drawStateDrawable(Canvas canvas) { + if (drawable != null && isShowState) { + getDrawableBounds(); + drawable.setBounds((int) drawableBounds[0], (int) drawableBounds[1], (int) drawableBounds[2], + (int) drawableBounds[3]); + drawable.draw(canvas); + } + } - public SuperTextView setStrokeWidth(float strokeWidth) { - this.strokeWidth = strokeWidth; - postInvalidate(); + private float[] getDrawableBounds() { + for (int i = 0; i < drawableBounds.length; i++) { + drawableBounds[i] = 0; + } + drawableWidth = (drawableWidth == 0 ? width / 2f : drawableWidth); + drawableHeight = (drawableHeight == 0 ? height / 2f : drawableHeight); + switch (DrawableMode.valueOf(stateDrawableMode)) { + case LEFT: // left + drawableBounds[0] = 0 + drawablePaddingLeft; + drawableBounds[1] = height / 2f - drawableHeight / 2f + drawablePaddingTop; + drawableBounds[2] = drawableBounds[0] + drawableWidth; + drawableBounds[3] = drawableBounds[1] + drawableHeight; + break; + case TOP: // top + drawableBounds[0] = width / 2f - drawableWidth / 2f + drawablePaddingLeft; + drawableBounds[1] = 0 + drawablePaddingTop; + drawableBounds[2] = drawableBounds[0] + drawableWidth; + drawableBounds[3] = drawableBounds[1] + drawableHeight; + break; + case RIGHT: // right + drawableBounds[0] = width - drawableWidth + drawablePaddingLeft; + drawableBounds[1] = height / 2 - drawableHeight / 2 + drawablePaddingTop; + drawableBounds[2] = drawableBounds[0] + drawableWidth; + drawableBounds[3] = drawableBounds[1] + drawableHeight; + break; + case BOTTOM: // bottom + drawableBounds[0] = width / 2f - drawableWidth / 2f + drawablePaddingLeft; + drawableBounds[1] = height - drawableHeight + drawablePaddingTop; + drawableBounds[2] = drawableBounds[0] + drawableWidth; + drawableBounds[3] = drawableBounds[1] + drawableHeight; + break; + case CENTER: // center + drawableBounds[0] = width / 2f - drawableWidth / 2f + drawablePaddingLeft; + drawableBounds[1] = height / 2 - drawableHeight / 2 + drawablePaddingTop; + drawableBounds[2] = drawableBounds[0] + drawableWidth; + drawableBounds[3] = drawableBounds[1] + drawableHeight; + break; + case FILL: // fill + drawableBounds[0] = 0; + drawableBounds[1] = 0; + drawableBounds[2] = width; + drawableBounds[3] = height; + break; + case LEFT_TOP: // leftTop + drawableBounds[0] = 0 + drawablePaddingLeft; + drawableBounds[1] = 0 + drawablePaddingTop; + drawableBounds[2] = drawableBounds[0] + drawableWidth; + drawableBounds[3] = drawableBounds[1] + drawableHeight; + break; + case RIGHT_TOP: // rightTop + drawableBounds[0] = width - drawableWidth + drawablePaddingLeft; + drawableBounds[1] = 0 + drawablePaddingTop; + drawableBounds[2] = drawableBounds[0] + drawableWidth; + drawableBounds[3] = drawableBounds[1] + drawableHeight; + break; + case LEFT_BOTTOM: // leftBottom + drawableBounds[0] = 0 + drawablePaddingLeft; + drawableBounds[1] = height - drawableHeight + drawablePaddingTop; + drawableBounds[2] = drawableBounds[0] + drawableWidth; + drawableBounds[3] = drawableBounds[1] + drawableHeight; + break; + case RIGHT_BOTTOM: // rightBottom + drawableBounds[0] = width - drawableWidth + drawablePaddingLeft; + drawableBounds[1] = height - drawableHeight + drawablePaddingTop; + drawableBounds[2] = drawableBounds[0] + drawableWidth; + drawableBounds[3] = drawableBounds[1] + drawableHeight; + break; + } - return this; - } + return drawableBounds; + } - public int getStrokeColor() { - return strokeColor; - } + private void isNeedToAdjust(Canvas canvas, Adjuster.Opportunity currentOpportunity) { + if (autoAdjust) { + if (adjuster == null) { + setAdjuster(new DefaultAdjuster()); + } else { + if (currentOpportunity == adjuster.getOpportunity()) { + adjuster.adjust(this, canvas); + } + } + } + } - public SuperTextView setStrokeColor(int strokeColor) { - this.strokeColor = strokeColor; - postInvalidate(); + public float getCorner() { + return corner; + } - return this; - } + public SuperTextView setCorner(float corner) { + this.corner = corner; + postInvalidate(); - public Drawable getDrawable() { - return drawable; - } + return this; + } - public SuperTextView setDrawable(Drawable drawable) { - this.drawable = drawable; - postInvalidate(); + public int getSolid() { +// return solid; + return bgColorNormal; + } - return this; - } + public SuperTextView setSolid(int solid) { +// this.solid = solid; + this.bgColorNormal = solid; + postInvalidate(); + return this; + } - public boolean isShowState() { - return isShowState; - } + public float getStrokeWidth() { + return strokeWidth; + } - public SuperTextView setShowState(boolean showState) { - isShowState = showState; - postInvalidate(); + public SuperTextView setStrokeWidth(float strokeWidth) { + this.strokeWidth = strokeWidth; + postInvalidate(); - return this; - } + return this; + } - public int getStateDrawableMode() { - return stateDrawableMode; - } + public int getStrokeColor() { +// return strokeColor; + return strokeColorNormal; + } - public SuperTextView setStateDrawableMode(int stateDrawableMode) { - this.stateDrawableMode = stateDrawableMode; - postInvalidate(); + public SuperTextView setStrokeColor(int strokeColor) { +// this.strokeColor = strokeColor; + this.strokeColorNormal = strokeColor; + postInvalidate(); - return this; - } + return this; + } - public SuperTextView setAdjuster(Adjuster adjuster) { - this.adjuster = adjuster; - postInvalidate(); + public Drawable getDrawable() { + return drawable; + } - return this; - } + public SuperTextView setDrawable(Drawable drawable) { + this.drawable = drawable; + postInvalidate(); - public Adjuster getAdjuster() { - return adjuster; - } + return this; + } - public boolean isTextStroke() { - return textStroke; - } + public boolean isShowState() { + return isShowState; + } - public SuperTextView setTextStroke(boolean textStroke) { - this.textStroke = textStroke; - postInvalidate(); + public SuperTextView setShowState(boolean showState) { + isShowState = showState; + postInvalidate(); - return this; - } + return this; + } - public int getTextStrokeColor() { - return textStrokeColor; - } + public int getStateDrawableMode() { + return stateDrawableMode; + } - public SuperTextView setTextStrokeColor(int textStrokeColor) { - this.textStrokeColor = textStrokeColor; - postInvalidate(); + public SuperTextView setStateDrawableMode(int stateDrawableMode) { + this.stateDrawableMode = stateDrawableMode; + postInvalidate(); - return this; - } + return this; + } - public int getTextFillColor() { - return textFillColor; - } + public Adjuster getAdjuster() { + return adjuster; + } - public SuperTextView setTextFillColor(int textFillColor) { - this.textFillColor = textFillColor; - postInvalidate(); + public SuperTextView setAdjuster(Adjuster adjuster) { + this.adjuster = adjuster; + postInvalidate(); - return this; - } + return this; + } - public float getTextStrokeWidth() { - return textStrokeWidth; - } + public boolean isTextStroke() { + return textStroke; + } - public SuperTextView setTextStrokeWidth(float textStrokeWidth) { - this.textStrokeWidth = textStrokeWidth; - postInvalidate(); + public SuperTextView setTextStroke(boolean textStroke) { + this.textStroke = textStroke; + postInvalidate(); - return this; - } + return this; + } - public boolean isAutoAdjust() { - return autoAdjust; - } + public int getTextStrokeColor() { + return textStrokeColor; + } - public SuperTextView setAutoAdjust(boolean autoAdjust) { - this.autoAdjust = autoAdjust; - postInvalidate(); + public SuperTextView setTextStrokeColor(int textStrokeColor) { + this.textStrokeColor = textStrokeColor; + postInvalidate(); - return this; - } + return this; + } - public boolean isLeftTopCornerEnable() { - return leftTopCornerEnable; - } + public int getTextFillColor() { + return textFillColor; + } - public SuperTextView setLeftTopCornerEnable(boolean leftTopCornerEnable) { - this.leftTopCornerEnable = leftTopCornerEnable; - postInvalidate(); + public SuperTextView setTextFillColor(int textFillColor) { + this.textFillColor = textFillColor; + postInvalidate(); - return this; - } + return this; + } - public boolean isRightTopCornerEnable() { - return rightTopCornerEnable; - } + public float getTextStrokeWidth() { + return textStrokeWidth; + } - public SuperTextView setRightTopCornerEnable(boolean rightTopCornerEnable) { - this.rightTopCornerEnable = rightTopCornerEnable; - postInvalidate(); + public SuperTextView setTextStrokeWidth(float textStrokeWidth) { + this.textStrokeWidth = textStrokeWidth; + postInvalidate(); - return this; - } + return this; + } - public boolean isLeftBottomCornerEnable() { - return leftBottomCornerEnable; - } + public boolean isAutoAdjust() { + return autoAdjust; + } - public SuperTextView setLeftBottomCornerEnable(boolean leftBottomCornerEnable) { - this.leftBottomCornerEnable = leftBottomCornerEnable; - postInvalidate(); + public SuperTextView setAutoAdjust(boolean autoAdjust) { + this.autoAdjust = autoAdjust; + postInvalidate(); - return this; - } + return this; + } - public boolean isRightBottomCornerEnable() { - return rightBottomCornerEnable; - } + public boolean isLeftTopCornerEnable() { + return leftTopCornerEnable; + } - public SuperTextView setRightBottomCornerEnable(boolean rightBottomCornerEnable) { - this.rightBottomCornerEnable = rightBottomCornerEnable; - postInvalidate(); + public SuperTextView setLeftTopCornerEnable(boolean leftTopCornerEnable) { + this.leftTopCornerEnable = leftTopCornerEnable; + postInvalidate(); - return this; - } + return this; + } - public float getDrawableWidth() { - return drawableWidth; - } + public boolean isRightTopCornerEnable() { + return rightTopCornerEnable; + } - public SuperTextView setDrawableWidth(float drawableWidth) { - this.drawableWidth = drawableWidth; - postInvalidate(); + public SuperTextView setRightTopCornerEnable(boolean rightTopCornerEnable) { + this.rightTopCornerEnable = rightTopCornerEnable; + postInvalidate(); - return this; - } + return this; + } - public float getDrawableHeight() { - return drawableHeight; - } + public boolean isLeftBottomCornerEnable() { + return leftBottomCornerEnable; + } - public SuperTextView setDrawableHeight(float drawableHeight) { - this.drawableHeight = drawableHeight; - postInvalidate(); + public SuperTextView setLeftBottomCornerEnable(boolean leftBottomCornerEnable) { + this.leftBottomCornerEnable = leftBottomCornerEnable; + postInvalidate(); - return this; - } + return this; + } - public float getDrawablePaddingLeft() { - return drawablePaddingLeft; - } + public boolean isRightBottomCornerEnable() { + return rightBottomCornerEnable; + } - public SuperTextView setDrawablePaddingLeft(float drawablePaddingLeft) { - this.drawablePaddingLeft = drawablePaddingLeft; - postInvalidate(); + public SuperTextView setRightBottomCornerEnable(boolean rightBottomCornerEnable) { + this.rightBottomCornerEnable = rightBottomCornerEnable; + postInvalidate(); - return this; - } + return this; + } - public float getDrawablePaddingTop() { - return drawablePaddingTop; - } + public float getDrawableWidth() { + return drawableWidth; + } - public SuperTextView setDrawablePaddingTop(float drawablePaddingTop) { - this.drawablePaddingTop = drawablePaddingTop; - postInvalidate(); + public SuperTextView setDrawableWidth(float drawableWidth) { + this.drawableWidth = drawableWidth; + postInvalidate(); - return this; - } + return this; + } - public int getFrameRate() { - return frameRate; - } + public float getDrawableHeight() { + return drawableHeight; + } + + public SuperTextView setDrawableHeight(float drawableHeight) { + this.drawableHeight = drawableHeight; + postInvalidate(); - public SuperTextView setFrameRate(int frameRate) { - if (frameRate > 0) { - this.frameRate = frameRate; - } else { - this.frameRate = 60; + return this; } - return this; - } - public void startAnim() { - checkWhetherNeedInitInvalidate(); - needRun = true; - runnable = false; - if (animThread == null) { - needRun = true; - runnable = true; - animThread = new Thread(new Runnable() { - @Override - public void run() { - while (runnable) { - synchronized (invalidate){ - post(invalidate); - } - try { - Thread.sleep(1000 / frameRate); - } catch (InterruptedException e) { - e.printStackTrace(); - runnable = false; - } - // Log.e("SuperTextView", " -> startAnim: " + Thread.currentThread().getId() + "-> " - // + hashCode() + ": It's running!"); - } - animThread = null; - if (needRun) { - startAnim(); - } + public float getDrawablePaddingLeft() { + return drawablePaddingLeft; + } + + public SuperTextView setDrawablePaddingLeft(float drawablePaddingLeft) { + this.drawablePaddingLeft = drawablePaddingLeft; + postInvalidate(); + + return this; + } + + public float getDrawablePaddingTop() { + return drawablePaddingTop; + } + + public SuperTextView setDrawablePaddingTop(float drawablePaddingTop) { + this.drawablePaddingTop = drawablePaddingTop; + postInvalidate(); + + return this; + } + + public int getFrameRate() { + return frameRate; + } + + public SuperTextView setFrameRate(int frameRate) { + if (frameRate > 0) { + this.frameRate = frameRate; + } else { + this.frameRate = 60; } - }); - animThread.start(); + return this; } - } - private void checkWhetherNeedInitInvalidate() { - if (invalidate == null) { - invalidate = new Runnable() { - @Override - public void run() { - postInvalidate(); + public void startAnim() { + checkWhetherNeedInitInvalidate(); + needRun = true; + runnable = false; + if (animThread == null) { + needRun = true; + runnable = true; + animThread = new Thread(new Runnable() { + @Override + public void run() { + while (runnable) { + synchronized (invalidate) { + post(invalidate); + } + try { + Thread.sleep(1000 / frameRate); + } catch (InterruptedException e) { + e.printStackTrace(); + runnable = false; + } + // Log.e("SuperTextView", " -> startAnim: " + Thread.currentThread().getId() + "-> " + // + hashCode() + ": It's running!"); + } + animThread = null; + if (needRun) { + startAnim(); + } + } + }); + animThread.start(); } - }; } - } - public void stopAnim() { - runnable = false; - needRun = false; - } + private void checkWhetherNeedInitInvalidate() { + if (invalidate == null) { + invalidate = new Runnable() { + @Override + public void run() { + postInvalidate(); + } + }; + } + } - @Override - public boolean onTouchEvent(MotionEvent event) { - if (adjuster != null) { - if (adjuster.onTouch(this, event) && isAutoAdjust()) { - super.onTouchEvent(event); - return true; - } + public void stopAnim() { + runnable = false; + needRun = false; } - return super.onTouchEvent(event); - } - @Override - protected void onWindowVisibilityChanged(int visibility) { - super.onWindowVisibilityChanged(visibility); - if (visibility != VISIBLE) { - cacheRunnableState = runnable; - cacheNeedRunState = needRun; - stopAnim(); - } else if (cacheRunnableState && cacheNeedRunState) { - startAnim(); + @Override + public boolean onTouchEvent(MotionEvent event) { + if (adjuster != null) { + if (adjuster.onTouch(this, event) && isAutoAdjust()) { + super.onTouchEvent(event); + return true; + } + } else { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + pressed = true; + postInvalidate(); + break; + case MotionEvent.ACTION_UP: + case MotionEvent.ACTION_CANCEL: + pressed = false; + postInvalidate(); + break; + } + return true; + } + return super.onTouchEvent(event); } - } - @Override - protected void onDetachedFromWindow() { - stopAnim(); - super.onDetachedFromWindow(); - } + @Override + protected void onWindowVisibilityChanged(int visibility) { + super.onWindowVisibilityChanged(visibility); + if (visibility != VISIBLE) { + cacheRunnableState = runnable; + cacheNeedRunState = needRun; + stopAnim(); + } else if (cacheRunnableState && cacheNeedRunState) { + startAnim(); + } + } - public static abstract class Adjuster { - private Opportunity opportunity = Opportunity.BEFORE_TEXT; + @Override + protected void onDetachedFromWindow() { + stopAnim(); + super.onDetachedFromWindow(); + } - protected abstract void adjust(SuperTextView v, Canvas canvas); + public static enum DrawableMode { + LEFT(0), TOP(1), RIGHT(2), BOTTOM(3), CENTER(4), FILL(5), LEFT_TOP(6), RIGHT_TOP(7), + LEFT_BOTTOM(8), RIGHT_BOTTOM(9); + public int code; - public boolean onTouch(SuperTextView v, MotionEvent event) { - return false; - }; + DrawableMode(int code) { + this.code = code; + } - public Opportunity getOpportunity() { - return opportunity; + public static DrawableMode valueOf(int code) { + for (DrawableMode mode : DrawableMode.values()) { + if (mode.code == code) { + return mode; + } + } + return CENTER; + } } - public void setOpportunity(Opportunity opportunity) { - this.opportunity = opportunity; - } + public static abstract class Adjuster { + private Opportunity opportunity = Opportunity.BEFORE_TEXT; + + protected abstract void adjust(SuperTextView v, Canvas canvas); + + public boolean onTouch(SuperTextView v, MotionEvent event) { + return false; + } + + ; + + public Opportunity getOpportunity() { + return opportunity; + } + + public void setOpportunity(Opportunity opportunity) { + this.opportunity = opportunity; + } - public static enum Opportunity { - BEFORE_DRAWABLE, BEFORE_TEXT, AT_LAST + public static enum Opportunity { + BEFORE_DRAWABLE, BEFORE_TEXT, AT_LAST + } } - } - public static class DefaultAdjuster extends Adjuster { + public static class DefaultAdjuster extends Adjuster { - @Override - public void adjust(SuperTextView v, Canvas canvas) { - int length = v.length(); - float scale = v.getWidth() / (116.28f * v.getResources().getDisplayMetrics().density); - float[] textSizes = { - 37.21f, 37.21f, 24.81f, 27.9f, 24.81f, - 22.36f, 18.6f, - 18.6f - }; - switch (length) { - case 1: - v.setTextSize(textSizes[0] * scale); - break; - case 2: - v.setTextSize(textSizes[1] * scale); - break; - case 3: - v.setTextSize(textSizes[2] * scale); - break; - case 4: - v.setTextSize(textSizes[3] * scale); - break; - case 5: - case 6: - v.setTextSize(textSizes[4] * scale); - break; - case 7: - case 8: - case 9: - v.setTextSize(textSizes[5] * scale); - break; - case 10: - case 11: - case 12: - v.setTextSize(textSizes[6] * scale); - break; - case 13: - case 14: - case 15: - case 16: - v.setTextSize(textSizes[7] * scale); - break; - } - } - - } - - public static enum DrawableMode { - LEFT(0), TOP(1), RIGHT(2), BOTTOM(3), CENTER(4), FILL(5), LEFT_TOP(6), RIGHT_TOP(7), - LEFT_BOTTOM(8), RIGHT_BOTTOM(9); - public int code; - - DrawableMode(int code) { - this.code = code; - } - - public static DrawableMode valueOf(int code) { - for (DrawableMode mode : DrawableMode.values()) { - if (mode.code == code) { - return mode; + @Override + public void adjust(SuperTextView v, Canvas canvas) { + int length = v.length(); + float scale = v.getWidth() / (116.28f * v.getResources().getDisplayMetrics().density); + float[] textSizes = { + 37.21f, 37.21f, 24.81f, 27.9f, 24.81f, + 22.36f, 18.6f, + 18.6f + }; + switch (length) { + case 1: + v.setTextSize(textSizes[0] * scale); + break; + case 2: + v.setTextSize(textSizes[1] * scale); + break; + case 3: + v.setTextSize(textSizes[2] * scale); + break; + case 4: + v.setTextSize(textSizes[3] * scale); + break; + case 5: + case 6: + v.setTextSize(textSizes[4] * scale); + break; + case 7: + case 8: + case 9: + v.setTextSize(textSizes[5] * scale); + break; + case 10: + case 11: + case 12: + v.setTextSize(textSizes[6] * scale); + break; + case 13: + case 14: + case 15: + case 16: + v.setTextSize(textSizes[7] * scale); + break; + } } - } - return CENTER; + } - } } From 169e05ff910e23006bf02483190db278ed4c5fdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=BA=86=E5=B9=B4?= <1713923044@qq.com> Date: Fri, 2 Jun 2017 10:41:46 +0800 Subject: [PATCH 2/2] =?UTF-8?q?1=E3=80=81=E5=AE=8C=E5=96=84=E6=8C=89?= =?UTF-8?q?=E9=92=AE=E5=8A=9F=E8=83=BD=E3=80=82=E5=8F=AA=E9=9C=80setBgColo?= =?UTF-8?q?r=E6=88=96=E8=80=85setBgColorAttr=E6=96=B9=E6=B3=95=E5=B0=B1?= =?UTF-8?q?=E5=8F=AF=E4=BB=A5=E8=AE=BE=E7=BD=AE=E6=8C=89=E9=92=AE=E4=B8=8D?= =?UTF-8?q?=E5=90=8C=E7=8A=B6=E6=80=81=E4=B8=8B=E7=9A=84=E9=A2=9C=E8=89=B2?= =?UTF-8?q?=E5=80=BC=E4=BA=86=EF=BC=8CStroke=E4=B9=9F=E4=B8=80=E6=A0=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coorchice/supertextview/MainActivity.java | 112 ++- .../res/color/button_yellow_color_sel.xml | 25 + app/src/main/res/layout/activity_main.xml | 908 +++++++++--------- app/src/main/res/values/styles.xml | 6 + library/build.gradle | 2 + .../com/coorchice/library/SuperTextView.java | 137 ++- library/src/main/res/values/attrs.xml | 68 +- 7 files changed, 683 insertions(+), 575 deletions(-) create mode 100644 app/src/main/res/color/button_yellow_color_sel.xml diff --git a/app/src/main/java/com/coorchice/supertextview/MainActivity.java b/app/src/main/java/com/coorchice/supertextview/MainActivity.java index 06272cf..b831c43 100644 --- a/app/src/main/java/com/coorchice/supertextview/MainActivity.java +++ b/app/src/main/java/com/coorchice/supertextview/MainActivity.java @@ -1,64 +1,80 @@ package com.coorchice.supertextview; +import android.os.Bundle; +import android.support.v7.app.AppCompatActivity; +import android.view.View; +import android.widget.Toast; + import com.coorchice.library.SuperTextView; import com.coorchice.supertextview.SuperTextView.Adjuster.BtnAdjuster; import com.coorchice.supertextview.SuperTextView.Adjuster.MoveEffectAdjuster; import com.coorchice.supertextview.SuperTextView.Adjuster.OpportunityDemoAdjuster; import com.coorchice.supertextview.SuperTextView.Adjuster.RippleAdjuster; -import android.os.Bundle; -import android.support.v7.app.AppCompatActivity; - public class MainActivity extends AppCompatActivity { -// -private SuperTextView stv_0; - private SuperTextView stv_17; - private SuperTextView stv_18; - private SuperTextView stv_19; - private SuperTextView stv_20; - private SuperTextView stv_21; + // + private SuperTextView stv_0; + private SuperTextView stv_17; + private SuperTextView stv_18; + private SuperTextView stv_19; + private SuperTextView stv_20; + private SuperTextView stv_21; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + initView(); + } + + private void initView() { + findViews(); + getWindow().getDecorView().postDelayed(new Runnable() { + @Override + public void run() { +// stv_0.setEnabled(false); + stv_0.setBgColorAttr(R.attr.attr_part_translucent_black1); + stv_0.setStrokeColorAttr(R.attr.attr_part_translucent_black); + } + }, 4000); + + stv_0.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Toast.makeText(MainActivity.this, "ssssssss", Toast.LENGTH_SHORT).show(); + } + }); + + + stv_17.setAdjuster(new MoveEffectAdjuster()) + .setAutoAdjust(true) + .startAnim(); - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_main); - initView(); - } + stv_18.setAdjuster(new RippleAdjuster(getResources().getColor(R.color.opacity_5_a58fed))); - private void initView() { - findViews(); + OpportunityDemoAdjuster opportunityDemoAdjuster1 = new OpportunityDemoAdjuster(); + opportunityDemoAdjuster1.setOpportunity(SuperTextView.Adjuster.Opportunity.BEFORE_DRAWABLE); + stv_19.setAdjuster(opportunityDemoAdjuster1); + stv_19.setAutoAdjust(true); -// stv_0.setAdjuster(new BtnAdjuster(getResources().getColor(R.color.opacity_5_a58fed))); + OpportunityDemoAdjuster opportunityDemoAdjuster2 = new OpportunityDemoAdjuster(); + opportunityDemoAdjuster2.setOpportunity(SuperTextView.Adjuster.Opportunity.BEFORE_TEXT); + stv_20.setAdjuster(opportunityDemoAdjuster2); + stv_20.setAutoAdjust(true); -// stv_17.setAdjuster(new MoveEffectAdjuster()) -// .setAutoAdjust(true) -// .startAnim(); -// -// stv_18.setAdjuster(new RippleAdjuster(getResources().getColor(R.color.opacity_5_a58fed))); -// -// OpportunityDemoAdjuster opportunityDemoAdjuster1 = new OpportunityDemoAdjuster(); -// opportunityDemoAdjuster1.setOpportunity(SuperTextView.Adjuster.Opportunity.BEFORE_DRAWABLE); -// stv_19.setAdjuster(opportunityDemoAdjuster1); -// stv_19.setAutoAdjust(true); -// -// OpportunityDemoAdjuster opportunityDemoAdjuster2 = new OpportunityDemoAdjuster(); -// opportunityDemoAdjuster2.setOpportunity(SuperTextView.Adjuster.Opportunity.BEFORE_TEXT); -// stv_20.setAdjuster(opportunityDemoAdjuster2); -// stv_20.setAutoAdjust(true); -// -// OpportunityDemoAdjuster opportunityDemoAdjuster3 = new OpportunityDemoAdjuster(); -// opportunityDemoAdjuster3.setOpportunity(SuperTextView.Adjuster.Opportunity.AT_LAST); -// stv_21.setAdjuster(opportunityDemoAdjuster3); -// stv_21.setAutoAdjust(true); - } + OpportunityDemoAdjuster opportunityDemoAdjuster3 = new OpportunityDemoAdjuster(); + opportunityDemoAdjuster3.setOpportunity(SuperTextView.Adjuster.Opportunity.AT_LAST); + stv_21.setAdjuster(opportunityDemoAdjuster3); + stv_21.setAutoAdjust(true); + } - private void findViews() { - stv_0 = (SuperTextView) findViewById(R.id.stv_0); -// stv_17 = (SuperTextView) findViewById(R.id.stv_17); -// stv_18 = (SuperTextView) findViewById(R.id.stv_18); -// stv_19 = (SuperTextView) findViewById(R.id.stv_19); -// stv_20 = (SuperTextView) findViewById(R.id.stv_20); -// stv_21 = (SuperTextView) findViewById(R.id.stv_21); - } + private void findViews() { + stv_0 = (SuperTextView) findViewById(R.id.stv_0); + stv_17 = (SuperTextView) findViewById(R.id.stv_17); + stv_18 = (SuperTextView) findViewById(R.id.stv_18); + stv_19 = (SuperTextView) findViewById(R.id.stv_19); + stv_20 = (SuperTextView) findViewById(R.id.stv_20); + stv_21 = (SuperTextView) findViewById(R.id.stv_21); + } } diff --git a/app/src/main/res/color/button_yellow_color_sel.xml b/app/src/main/res/color/button_yellow_color_sel.xml new file mode 100644 index 0000000..662fcf7 --- /dev/null +++ b/app/src/main/res/color/button_yellow_color_sel.xml @@ -0,0 +1,25 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index c9ff154..c3722e3 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,475 +1,447 @@ - - - + android:layout_height="match_parent"> - - - - + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 2f564c1..08b8ed9 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -6,7 +6,13 @@ @color/colorPrimary @color/colorPrimaryDark @color/colorAccent + + @color/button_yellow_color_sel + @color/button_color_sel + + + diff --git a/library/build.gradle b/library/build.gradle index 94d87cc..6ecfa23 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -40,4 +40,6 @@ android { dependencies { compile fileTree(include: ['*.jar'], dir: 'libs') + compile 'com.android.support:support-annotations:25.1.0' + compile 'com.android.support:appcompat-v7:25.1.0' } diff --git a/library/src/main/java/com/coorchice/library/SuperTextView.java b/library/src/main/java/com/coorchice/library/SuperTextView.java index f84d196..27be37f 100644 --- a/library/src/main/java/com/coorchice/library/SuperTextView.java +++ b/library/src/main/java/com/coorchice/library/SuperTextView.java @@ -28,8 +28,14 @@ import android.graphics.RectF; import android.graphics.drawable.Drawable; import android.os.Build; +import android.os.SystemClock; +import android.support.annotation.AttrRes; +import android.support.annotation.ColorRes; +import android.support.v4.content.ContextCompat; import android.util.AttributeSet; +import android.util.TypedValue; import android.view.MotionEvent; +import android.view.ViewConfiguration; import android.widget.TextView; @@ -39,7 +45,7 @@ public class SuperTextView extends TextView { private static final float DEFAULT_CORNER = 0f; private static final int DEFAULT_SOLID = Color.WHITE; private static final float DEFAULT_STROKE_WIDTH = 0f; - private static final int DEFAULT_STROKE_COLOR = Color.BLACK; + private static final int DEFAULT_STROKE_COLOR = Color.WHITE; private static final int DEFAULT_STATE_DRAWABLE_MODE = 4; private static final int DEFAULT_TEXT_STROKE_COLOR = Color.BLACK; private static final int DEFAULT_TEXT_FILL_COLOR = Color.BLACK; @@ -95,6 +101,7 @@ public class SuperTextView extends TextView { private int frameRate = 60; private Runnable invalidate; private boolean pressed = false; + private int mTouchSlop; //控件边缘的溢出值,在溢出值范围内也可以看做是在控件区域里 public SuperTextView(Context context) { @@ -121,6 +128,7 @@ public SuperTextView(Context context, AttributeSet attrs, int defStyleAttr, private void init(AttributeSet attrs) { density = getContext().getResources().getDisplayMetrics().density; + mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop(); initAttrs(attrs); paint = new Paint(); initPaint(); @@ -139,11 +147,8 @@ private void initAttrs(AttributeSet attrs) { typedArray.getBoolean(R.styleable.SuperTextView_left_bottom_corner, false); rightBottomCornerEnable = typedArray.getBoolean(R.styleable.SuperTextView_right_bottom_corner, false); - bgColorNormal = typedArray.getColor(R.styleable.SuperTextView_solid, DEFAULT_SOLID); strokeWidth = typedArray.getDimension(R.styleable.SuperTextView_stroke_width, DEFAULT_STROKE_WIDTH); - strokeColorNormal = - typedArray.getColor(R.styleable.SuperTextView_stroke_color, DEFAULT_STROKE_COLOR); drawable = typedArray.getDrawable(R.styleable.SuperTextView_state_drawable); drawableWidth = typedArray.getDimension(R.styleable.SuperTextView_state_drawable_width, 0); @@ -167,31 +172,37 @@ private void initAttrs(AttributeSet attrs) { ColorStateList bgColors = typedArray.getColorStateList(R.styleable.SuperTextView_solid); if (bgColors != null) { - bgColorNormal = bgColors.getColorForState(new int[]{android.R.attr.state_enabled}, 0); - bgColorPressed = bgColors.getColorForState(new int[]{android.R.attr.state_pressed}, bgColorNormal); - bgColorDisable = bgColors.getColorForState(new int[]{-android.R.attr.state_enabled}, bgColorNormal); + setBgColorWithStateList(bgColors, DEFAULT_SOLID); } else { -// bgColorNormal = Color.parseColor("#ffff0000"); + bgColorNormal = DEFAULT_SOLID; bgColorPressed = Color.parseColor("#0cff0000"); bgColorDisable = Color.parseColor("#06ff0000"); } ColorStateList strokeColors = typedArray.getColorStateList(R.styleable.SuperTextView_stroke_color); if (strokeColors != null) { - strokeColorNormal = strokeColors.getColorForState(new int[]{android.R.attr.state_enabled}, 0); - strokeColorPressed = strokeColors.getColorForState(new int[]{android.R.attr.state_pressed}, strokeColorNormal); - strokeColorDisable = strokeColors.getColorForState(new int[]{-android.R.attr.state_enabled}, strokeColorNormal); + setStrokeColorWithStateList(strokeColors, DEFAULT_STROKE_COLOR); } else { -// strokeColorNormal = Color.parseColor("#00000000"); - strokeColorPressed = Color.parseColor("#00000000"); - strokeColorDisable = Color.parseColor("#00000000"); + strokeColorNormal = DEFAULT_STROKE_COLOR; + strokeColorPressed = Color.parseColor("#0cff0000"); + strokeColorDisable = Color.parseColor("#06ff0000"); } - - typedArray.recycle(); } } + private void setBgColorWithStateList(ColorStateList bgColors, int defaultColor) { + bgColorNormal = bgColors.getColorForState(new int[]{android.R.attr.state_enabled}, defaultColor); + bgColorPressed = bgColors.getColorForState(new int[]{android.R.attr.state_pressed}, bgColorNormal); + bgColorDisable = bgColors.getColorForState(new int[]{-android.R.attr.state_enabled}, bgColorNormal); + } + + private void setStrokeColorWithStateList(ColorStateList strokeColors, int defaultColor) { + strokeColorNormal = strokeColors.getColorForState(new int[]{android.R.attr.state_enabled}, defaultColor); + strokeColorPressed = strokeColors.getColorForState(new int[]{android.R.attr.state_pressed}, strokeColorNormal); + strokeColorDisable = strokeColors.getColorForState(new int[]{-android.R.attr.state_enabled}, strokeColorNormal); + } + private void initPaint() { paint.reset(); paint.setAntiAlias(true); @@ -440,13 +451,33 @@ public SuperTextView setCorner(float corner) { } public int getSolid() { -// return solid; return bgColorNormal; } - public SuperTextView setSolid(int solid) { -// this.solid = solid; - this.bgColorNormal = solid; + /** + * Sets bgColor attrId + * + * @param attrId the color attr id + * @return + */ + public SuperTextView setBgColorAttr(@AttrRes int attrId) { + TypedValue typedValue = new TypedValue(); + getContext().getTheme().resolveAttribute(attrId, typedValue, true); + setBgColor(typedValue.resourceId); + return this; + } + + /** + * Sets bgColor colorId + * + * @param colorId the color id + * @return + */ + public SuperTextView setBgColor(@ColorRes int colorId) { + ColorStateList colorStateList = ContextCompat.getColorStateList(getContext(), colorId); + if (colorStateList != null) { + setBgColorWithStateList(colorStateList, bgColorNormal); + } postInvalidate(); return this; } @@ -463,15 +494,34 @@ public SuperTextView setStrokeWidth(float strokeWidth) { } public int getStrokeColor() { -// return strokeColor; return strokeColorNormal; } - public SuperTextView setStrokeColor(int strokeColor) { -// this.strokeColor = strokeColor; - this.strokeColorNormal = strokeColor; + /** + * Sets StrokeColor colorId + * + * @param colorId the color id + * @return + */ + public SuperTextView setStrokeColor(@ColorRes int colorId) { + ColorStateList colorStateList = ContextCompat.getColorStateList(getContext(), colorId); + if (colorStateList != null) { + setStrokeColorWithStateList(colorStateList, strokeColorNormal); + } postInvalidate(); + return this; + } + /** + * Sets StrokeColor attrId + * + * @param attrId the color attr id + * @return + */ + public SuperTextView setStrokeColorAttr(@AttrRes int attrId) { + TypedValue typedValue = new TypedValue(); + getContext().getTheme().resolveAttribute(attrId, typedValue, true); + setStrokeColor(typedValue.resourceId); return this; } @@ -737,17 +787,54 @@ public boolean onTouchEvent(MotionEvent event) { pressed = true; postInvalidate(); break; + case MotionEvent.ACTION_MOVE: + if (pressed) { + if (!isInWidget(event)) { + pressed = false; + postInvalidate(); + } + } + break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: pressed = false; postInvalidate(); break; } - return true; } return super.onTouchEvent(event); } + /** + * 事件是否在控件里面 + * + * @param event 事件 + * @return + */ + private boolean isInWidget(MotionEvent event) { + if (event.getX() >= (-mTouchSlop) && event.getX() <= (getWidth() + mTouchSlop) + && event.getY() >= (-mTouchSlop) && event.getY() <= (getHeight() + mTouchSlop)) { + return true; + } + return false; + } + + /** + * 模拟发送Cancel事件 + * + * @param x + * @param y + */ + private void simulateTouch(float x, float y) { + + final long downTime = SystemClock.uptimeMillis(); + final MotionEvent downEvent = MotionEvent.obtain( + downTime, downTime, MotionEvent.ACTION_CANCEL, x, y, 0); + onTouchEvent(downEvent); + downEvent.recycle(); + } + + @Override protected void onWindowVisibilityChanged(int visibility) { super.onWindowVisibilityChanged(visibility); diff --git a/library/src/main/res/values/attrs.xml b/library/src/main/res/values/attrs.xml index e0571f4..2e877b3 100644 --- a/library/src/main/res/values/attrs.xml +++ b/library/src/main/res/values/attrs.xml @@ -1,38 +1,38 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file