Commit 82410f7f by EthanXiang

Initial commit

parents
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
android {
compileSdkVersion rootProject.ext.compileSdkVersion
buildToolsVersion rootProject.ext.buildToolsVersion
defaultConfig {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.3.1'
testCompile 'junit:junit:4.12'
compile "org.jetbrains.kotlin:kotlin-stdlib:$rootProject.ext.kotlin_version"
}
repositories {
mavenCentral()
}
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in D:\Android\sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
package com.x.leo.circles;
import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumentation test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() throws Exception {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getTargetContext();
assertEquals("com.x.leo.circles.test", appContext.getPackageName());
}
}
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.x.leo.circles">
<application android:allowBackup="true" android:label="@string/app_name"
android:supportsRtl="true">
</application>
</manifest>
package com.x.leo.circles;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
/**
* @作者:XJY
* @创建日期: 2017/3/16 17:46
* @描述:原型头像
* @更新者:${Author}$
* @更新时间:${Date}$
* @更新描述:${TODO}
*/
public class CircleImage extends android.support.v7.widget.AppCompatImageView{
private Paint paint;
public CircleImage(Context context) {
this(context,null);
}
public CircleImage(Context context, AttributeSet attrs) {
super(context, attrs);
paint = new Paint();
}
public CircleImage(Context context, AttributeSet attrs, int defStyleAttr) {
this(context, attrs);
}
private Rect rectSrc = new Rect();
private Rect rectDest = new Rect();
@Override
protected void onDraw(Canvas canvas) {
Drawable drawable = getDrawable();
if (drawable == null) {
super.onDraw(canvas);
}else{
Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
Bitmap b = getCircleBitmap(bitmap, 14);
rectSrc.set(0, 0, b.getWidth(), b.getHeight());
rectDest.set(0,0,getWidth(),getHeight());
paint.reset();
canvas.drawBitmap(b, rectSrc, rectDest, paint);
}
}
private Bitmap getCircleBitmap(Bitmap bitmap, int pixels) {
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xff424242;
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
int x = bitmap.getWidth();
canvas.drawCircle(x / 2, x / 2, x / 2, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return output;
}
}
package com.x.leo.circles;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;
/**
* @作者:My
* @创建日期: 2017/4/11 17:37
* @描述:${TODO}
* @更新者:${Author}$
* @更新时间:${Date}$
* @更新描述:${TODO}
*/
public class CircleProgressBarView extends View {
private int mProgress;
private int mMeasuredHeight;
private int mMeasuredWidth;
private int mStrokeWidth;
private int mRadius;
private int mStrokeBackgroundColor;
private int mProgressColor;
private Paint mPaint;
private BitmapDrawable mCircle;
private boolean mHideSmallCircle = false;
public CircleProgressBarView(Context context) {
this(context, null);
}
public CircleProgressBarView(Context context, AttributeSet attrs) {
super(context, attrs);
initView(context, attrs);
}
public CircleProgressBarView(Context context, AttributeSet attrs, int defStyleAttr) {
this(context, attrs);
}
public CircleProgressBarView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
this(context, attrs, defStyleAttr);
}
private void initView(Context context, AttributeSet attrs) {
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CircleProgressBarView);
mProgressColor = typedArray.getColor(R.styleable.CircleProgressBarView_progresscolor, Color.parseColor("#53c792"));
mStrokeBackgroundColor = typedArray.getColor(R.styleable.CircleProgressBarView_backgroundcolor, Color.parseColor("#C5DbD0"));
mRadius = typedArray.getDimensionPixelSize(R.styleable.CircleProgressBarView_radius, 0);
mStrokeWidth = typedArray.getDimensionPixelSize(R.styleable.CircleProgressBarView_strokewidth, DensityUtils.dp2px(getContext(), 5));
typedArray.recycle();
mCircle = (BitmapDrawable) getContext().getResources().getDrawable(R.drawable.cir_inactive);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);
mMeasuredHeight = getMeasuredHeight();
mMeasuredWidth = getMeasuredWidth();
}
private RectF oval = new RectF();
@Override
protected void onDraw(Canvas canvas) {
if (mPaint == null) {
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setStyle(Paint.Style.STROKE);
if (mStrokeWidth == 0) {
return;
}
mPaint.setStrokeWidth(mStrokeWidth);
}
if (mRadius == 0) {
mRadius = mMeasuredWidth / 2 - mStrokeWidth / 2 - mStrokeWidth / 2 - 20;
}
mPaint.setColor(mStrokeBackgroundColor);
canvas.drawCircle(mMeasuredWidth / 2, mMeasuredHeight / 2, mRadius, mPaint);
oval.set(mMeasuredWidth / 2 - mRadius, mMeasuredWidth / 2 - mRadius, mMeasuredWidth / 2 + mRadius, mMeasuredWidth / 2 + mRadius);
mPaint.setColor(mProgressColor);
canvas.drawArc(oval, 0, mProgress * 360 / 100, false, mPaint);
if (!mHideSmallCircle) {
float x = getWidth() / 2 + mRadius - mCircle.getIntrinsicWidth() / 2;
float y = getHeight() / 2 - mCircle.getIntrinsicHeight() / 2;
canvas.drawBitmap(mCircle.getBitmap(), x, y, mPaint);
}
}
public int getStrokeWidth() {
return mStrokeWidth;
}
public void setStrokeWidth(int strokeWidth) {
mStrokeWidth = strokeWidth;
}
public int getRadius() {
return mRadius;
}
public void setRadius(int radius) {
mRadius = radius;
}
public int getStrokeBackgroundColor() {
return mStrokeBackgroundColor;
}
public void setStrokeBackgroundColor(int backgroundColor) {
mStrokeBackgroundColor = backgroundColor;
}
public int getProgressColor() {
return mProgressColor;
}
public void setProgressColor(int progressColor) {
mProgressColor = progressColor;
}
public void setProgress(int progress) {
mProgress = progress;
invalidate();
}
public int getProgress() {
return mProgress;
}
public void hideSmallCircle(boolean hide) {
mHideSmallCircle = hide;
}
}
package com.x.leo.circles
import android.animation.Animator
import android.animation.ValueAnimator
import android.content.Context
import android.content.res.ColorStateList
import android.graphics.*
import android.text.TextUtils
import android.util.AttributeSet
import android.view.View
import android.widget.Button
/**
* @作者:XLEO
* @创建日期: 2017/8/18 10:04
* @描述:${TODO}
*
* @更新者:${Author}$
* @更新时间:${Date}$
* @更新描述:${TODO}
* @下一步:
*/
class CircleProgressButton(ctx: Context, attrs: AttributeSet?, defStyleAttr: Int) : Button(ctx, attrs, defStyleAttr) {
private lateinit var circleCenter: PointF
private var innerRadius: Float = 0f
private var outterRadius: Float = 0f
private var outterStrokeWidth: Float = 10f
private var outterInnerSpace: Float = 10f
private var duration: Int = 0
private var mPaint: Paint
private var colorlist: ColorStateList
private var progressBackgroundColor: Int = Color.GRAY
private var progressColor: Int = Color.RED
private var animator: ValueAnimator? = null
private var animatedValue: Int = 0
private var animatorListener: Animator.AnimatorListener? = null
private lateinit var outRect: RectF
private val startAngle: Float = 0f
private var circleAlpha:Float = 1f
init {
val attributes = ctx.obtainStyledAttributes(attrs, R.styleable.CircleProgressButton)
outterInnerSpace = attributes.getDimension(R.styleable.CircleProgressButton_innerOuterSpace, 10f)
outterStrokeWidth = attributes.getDimension(R.styleable.CircleProgressButton_outerStrokeWidth, 10f)
progressBackgroundColor = attributes.getColor(R.styleable.CircleProgressButton_progressBackground, Color.GRAY)
progressColor = attributes.getColor(R.styleable.CircleProgressButton_progressColor, Color.RED)
colorlist = attributes.getColorStateList(R.styleable.CircleProgressButton_circleColorList)
duration = attributes.getInt(R.styleable.CircleProgressButton_duration, 0)
attributes.recycle()
mPaint = Paint(Paint.ANTI_ALIAS_FLAG)
}
constructor(ctx: Context, attrs: AttributeSet?) : this(ctx, attrs, 0)
constructor(ctx: Context) : this(ctx, null)
fun setDuration(duration: Int) {
this.duration = duration
}
override fun setAlpha(alpha: Float) {
circleAlpha = alpha
}
override fun getAlpha(): Float {
return circleAlpha
}
fun setOnAnimatedEnd() {}
fun stopAnimation(){
if(animator != null){
animator!!.end()
animator = null
}
}
override fun setOnClickListener(l: OnClickListener?) {
super.setOnClickListener(object : OnCircleButtonClickListener(l) {
override fun onButtonClick(v: View?) {
}
})
}
fun setAnimationListener(listener: Animator.AnimatorListener) {
animatorListener = listener
}
fun startProgressAnimation() {
if (animator != null) {
animator!!.cancel()
}
animator = ValueAnimator.ofInt(0, duration)
animator!!.duration = duration.toLong()
animator!!.addUpdateListener {
animation ->
animatedValue = animation.animatedValue as Int
invalidate()
}
if (animatorListener != null) {
animator!!.addListener(animatorListener)
}
animator!!.start()
}
fun cancelAnimation(){
if (animator != null && animator!!.isRunning) {
animator!!.cancel()
animator = null
}
}
fun resetProgress(){
animatedValue = 0
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
cancelAnimation()
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
setMeasuredDimension(widthMeasureSpec, heightMeasureSpec)
circleCenter = PointF(measuredWidth / 2.toFloat(), measuredHeight / 2.toFloat())
outterRadius = if (measuredHeight > measuredWidth) {
measuredWidth / 2 - outterStrokeWidth / 2
} else {
measuredHeight / 2 - outterStrokeWidth / 2
}
innerRadius = outterRadius - outterStrokeWidth / 2 - outterInnerSpace
outRect = RectF(circleCenter.x - outterRadius,
circleCenter.y - outterRadius,
circleCenter.x + outterRadius,
circleCenter.y + outterRadius)
}
override fun onDraw(canvas: Canvas?) {
if (canvas == null) {
return
}
mPaint.style = Paint.Style.STROKE
mPaint.color = progressBackgroundColor
mPaint.strokeWidth = outterStrokeWidth
canvas.drawCircle(circleCenter.x, circleCenter.y, outterRadius, mPaint)
drawProgress(canvas)
mPaint.color = colorlist.getColorForState(drawableState, colorlist.defaultColor)
mPaint.style = Paint.Style.FILL
mPaint.strokeWidth = 0f
mPaint.alpha = (circleAlpha * 255).toInt()
canvas.drawCircle(circleCenter.x, circleCenter.y, innerRadius, mPaint)
if (!TextUtils.isEmpty(text)) {
val textLength = paint.measureText(text.toString())
paint.color = textColors.getColorForState(drawableState,textColors.defaultColor)
paint.textSize = textSize
val rect = Rect()
paint.getTextBounds(text.toString(),0,text.length,rect)
val y = circleCenter.y - rect.top/2
canvas.drawText(text,0,text.length,circleCenter.x - textLength / 2, y,paint)
}
}
private fun drawProgress(canvas: Canvas) {
if (duration == 0) {
return
}
mPaint.color = progressColor
val sweepAngle = animatedValue / duration.toFloat() * 360
canvas.drawArc(outRect, startAngle, sweepAngle, false, mPaint)
}
}
abstract class OnCircleButtonClickListener : View.OnClickListener {
private var listener: View.OnClickListener? = null
constructor(l: View.OnClickListener?) {
listener = l
}
override fun onClick(v: View?) {
onButtonClick(v)
listener?.onClick(v)
}
abstract fun onButtonClick(v: View?)
}
package com.x.leo.circles;
import android.content.Context;
/**
* @作者:My
* @创建日期: 2017/3/27 14:00
* @描述:${TODO}
* @更新者:${Author}$
* @更新时间:${Date}$
* @更新描述:${TODO}
*/
public class DensityUtils {
public static int dp2px(Context context,int size){
float density = context.getResources().getDisplayMetrics().density;
return (int) (size * density + 0.5f);
}
public static int px2dp(Context context,int size){
float density = context.getResources().getDisplayMetrics().density;
return (int) (size / density + 0.5f);
}
public static int px2sp(Context context, float textSize) {
float density = context.getResources().getDisplayMetrics().scaledDensity;
return (int) (textSize / density + 0.5f);
}
public static int sp2px(Context context,int size){
float density = context.getResources().getDisplayMetrics().scaledDensity;
return (int) (size * density + 0.5f);
}
}
package com.x.leo.circles
import android.animation.ValueAnimator
import android.content.Context
import android.content.pm.PackageManager
import android.graphics.*
import android.graphics.drawable.Drawable
import android.util.AttributeSet
import android.util.Log
import android.view.View
/**
* @作者:XLEO
* @创建日期: 2017/9/30 10:18
* @描述:${TODO}
*
* @更新者:${Author}$
* @更新时间:${Date}$
* @更新描述:${TODO}
* @下一步:
*/
class LoadIngView(ctx: Context, attrs: AttributeSet?) : View(ctx, attrs) {
private val NORES: Int = -1
var baseRes: Int = NORES
var duration: Int = 300
var outCircleWidth: Int = 200
var animateStyle: AnimateStyle = AnimateStyle.CIRCLE_STYLE
private var baseDrawable: Drawable? = null
private val animte: ValueAnimator by lazy {
ValueAnimator.ofInt(0, 360)
}
private val centerPoint: Point by lazy {
Point(measuredWidth / 2, measuredHeight / 2)
}
var outerInnerSpanFaction: Float = 0.2f
private val TAG = "LoadingView"
private val outerInnerSpan: Int by lazy {
logd("==outerInnnerSpan==outCircleWidth:" + outCircleWidth)
when (animateStyle) {
AnimateStyle.CIRCLE_STYLE -> {
(outCircleWidth * outerInnerSpanFaction).toInt()
}
AnimateStyle.CIRCLE_STYLE_2 -> {
(outCircleWidth * outerInnerSpanFaction).toInt()
}
AnimateStyle.CIRCLE_STYLE_3 -> {
(outCircleWidth * outerInnerSpanFaction).toInt() / 4
}
else -> {
throw IllegalArgumentException("wrong animate style")
}
}
}
private val ovalRadius: Int by lazy {
logd("==ovalRadius==" + "outCircleWidth:" + outCircleWidth + "\n outInnerSpan:" + outerInnerSpan)
when (animateStyle) {
AnimateStyle.CIRCLE_STYLE -> {
(outCircleWidth - outerInnerSpan) / 2
}
AnimateStyle.CIRCLE_STYLE_2 -> {
(outCircleWidth - outerInnerSpan) / 2
}
AnimateStyle.CIRCLE_STYLE_3 -> {
(outCircleWidth - outerInnerSpan * 4) / 2
}
else -> {
(outCircleWidth - outerInnerSpan) / 2
}
}
}
private val outCircleRadius: Int by lazy {
logd("==outCircleRadius==" + "ovalRadius:" + ovalRadius + "\nouterINnerSpan:" + outerInnerSpan)
// if (baseHeight > baseWidth) baseHeight / 2 else baseWidth / 2 + outerInnerSpan + ovalRadius
if (measuredHeight > measuredWidth) measuredWidth / 2 else measuredHeight / 2 - outCircleWidth + outerInnerSpan + ovalRadius
}
private var mAnimatedValue: Int = 0
private var baseWidth: Int = 0
private var baseHeight: Int = 0
var openAngle: Int = 90
private var ovalSpanAngle: Int = 10
private val angleDiff: Int by lazy {
Math.toDegrees(Math.asin(ovalRadius.toDouble() / outCircleRadius) * 2).toInt() + ovalSpanAngle
}
private val mPaint: Paint by lazy {
Paint(Paint.ANTI_ALIAS_FLAG)
}
var ovalColor: Int = Color.BLACK
init {
if (attrs != null) {
val oAttr = ctx.obtainStyledAttributes(attrs, R.styleable.LoadIngView)
baseRes = oAttr.getResourceId(R.styleable.LoadIngView_baseRes, NORES)
baseDrawable = if (baseRes == NORES) {
null
} else {
resources.getDrawable(baseRes)
}
baseWidth = if (baseDrawable == null) {
0
} else {
baseDrawable!!.intrinsicWidth
}
baseHeight = if (baseDrawable == null) {
0
} else {
baseDrawable!!.intrinsicHeight
}
animateStyle = AnimateStyle.getStyleByOrder(oAttr.getInt(R.styleable.LoadIngView_animateStyle, 0))
duration = oAttr.getInt(R.styleable.LoadIngView_animateDuration, 300)
outCircleWidth = oAttr.getDimensionPixelSize(R.styleable.LoadIngView_outCircleWidth, 100)
ovalSpanAngle = oAttr.getInt(R.styleable.LoadIngView_ovalSpanAngle, 10)
openAngle = oAttr.getInt(R.styleable.LoadIngView_openAngle, 90)
outerInnerSpanFaction = oAttr.getFraction(R.styleable.LoadIngView_outInnerMargin, 1, 1, 0.2f)
ovalColor = oAttr.getColor(R.styleable.LoadIngView_ovalColor, Color.parseColor("#fffd9236"))
oAttr.recycle()
logd("==init==")
}
}
private val doLog: Boolean = false
private fun logd(s: String) {
if (doLog) {
Log.d(TAG, s)
}
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
startAnimate()
}
private fun startAnimate() {
if (animte.isRunning) {
endAnimate()
}
animte.apply {
duration = this@LoadIngView.duration.toLong()
repeatCount = ValueAnimator.INFINITE
repeatMode = ValueAnimator.RESTART
addUpdateListener { animation ->
val animatedValue = animation.getAnimatedValue() as Int
when (animateStyle) {
AnimateStyle.CIRCLE_STYLE -> {
mAnimatedValue = animatedValue
}
else -> {
mAnimatedValue = animatedValue
}
}
invalidate()
}
start()
}
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
endAnimate()
}
private fun endAnimate() {
if (animte.isRunning) {
animte.removeAllUpdateListeners()
animte.cancel()
}
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
val widthMode = MeasureSpec.getMode(widthMeasureSpec)
val widthMeasured = MeasureSpec.getSize(widthMeasureSpec)
val heightMode = MeasureSpec.getMode(heightMeasureSpec)
val heightMeasured = MeasureSpec.getSize(heightMeasureSpec)
var resultWidth = baseWidth + outCircleWidth * 2
var resultHeight = baseHeight + outCircleWidth * 2
if (widthMode == MeasureSpec.EXACTLY) {
if (widthMeasured == 0) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
} else if (widthMeasured < resultWidth) {
// throw IllegalArgumentException("width is not big enough")
resultWidth = widthMeasured
} else {
resultWidth = widthMeasured
}
}
if (heightMode == MeasureSpec.EXACTLY) {
if (heightMeasured == 0) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
} else if (heightMeasured < resultHeight) {
resultHeight = heightMeasured
// throw IllegalArgumentException("height is not big enough")
} else {
resultHeight = heightMeasured
}
}
setMeasuredDimension(resultWidth, resultHeight)
}
override fun onDraw(canvas: Canvas?) {
if (canvas == null) {
return
}
// logd("measuredWidth:" + measuredWidth + "\nmeasuredHeight:" + measuredHeight
// + "\noutCicleWidth" + outCircleWidth + "\n baseWidth" + baseWidth + "\n baseHeight:" + baseHeight
// + "\noutCicleRadius" + outCircleRadius + "\novalRadius" + ovalRadius + "\noutInerSpan" + outerInnerSpan)
background?.draw(canvas)
mPaint.alpha = 100
drawBasDrawable(canvas!!)
mPaint.color = ovalColor
mPaint.style = Paint.Style.FILL
when (animateStyle) {
AnimateStyle.CIRCLE_STYLE -> {
drawOutCircles(canvas)
}
AnimateStyle.CIRCLE_STYLE_2 -> {
drawCircleShandow(canvas)
}
AnimateStyle.CIRCLE_STYLE_3 -> {
drawShakeCircles(canvas)
}
else -> {
throw IllegalArgumentException("error animate style")
}
}
}
private fun drawShakeCircles(canvas: Canvas) {
var temp = mAnimatedValue
val centerDiff = outerInnerSpan * 3 * if (mAnimatedValue.toFloat() / 180 >= 1) 2 - mAnimatedValue.toFloat() / 180 else mAnimatedValue.toFloat() / 180
while (temp - mAnimatedValue < 360 - openAngle) {
val currAlpha = (temp - mAnimatedValue).toFloat() / (360 - openAngle) * 70 + 30
if (temp + angleDiff - mAnimatedValue <= 360 - openAngle) {
drawCircle(temp, currAlpha.toInt(), canvas, centerDiff.toInt())
}
temp += angleDiff
}
}
private fun drawCircleShandow(canvas: Canvas) {
var temp = 0
while (temp < mAnimatedValue) {
val currAlpha = temp.toFloat() / mAnimatedValue * 100
drawCircle(temp, currAlpha.toInt(), canvas, 0)
temp += angleDiff
}
}
private fun drawOutCircles(canvas: Canvas) {
var temp = mAnimatedValue
while (temp - mAnimatedValue < 360 - openAngle) {
val currAlpha = (temp - mAnimatedValue).toFloat() / (360 - openAngle) * 70 + 30
if (temp + angleDiff - mAnimatedValue <= 360 - openAngle)
drawCircle(temp, currAlpha.toInt(), canvas, 0)
temp += angleDiff
}
}
private fun drawCircle(angle: Int, currAlpha: Int, canvas: Canvas, centerDiff: Int) {
val xCenter = centerPoint.x + (outCircleRadius + centerDiff) * Math.cos(Math.toRadians(angle.toDouble()))
val yCenter = centerPoint.y - (outCircleRadius + centerDiff) * Math.sin(Math.toRadians(angle.toDouble()))
mPaint.alpha = currAlpha
canvas.drawCircle(xCenter.toFloat(), yCenter.toFloat(), ovalRadius.toFloat(), mPaint)
}
private fun drawBasDrawable(canvas: Canvas) {
if (baseDrawable != null) {
val resultSize = ((if (measuredHeight > measuredWidth)
measuredWidth - outCircleWidth * 2
else
measuredHeight - outCircleWidth * 2) * Math.cos(Math.toRadians(45.0))).toInt()
baseDrawable!!.bounds = Rect(centerPoint.x - resultSize / 2, centerPoint.y - resultSize / 2, centerPoint.x + resultSize / 2, centerPoint.y + resultSize / 2)
baseDrawable!!.draw(canvas)
}
}
}
enum class AnimateStyle {
CIRCLE_STYLE, CIRCLE_STYLE_2, CIRCLE_STYLE_3;
companion object {
fun getStyleByOrder(order: Int): AnimateStyle {
return when (order) {
0 -> {
CIRCLE_STYLE
}
1 -> {
CIRCLE_STYLE_2
}
2 -> {
CIRCLE_STYLE_3
}
else -> {
CIRCLE_STYLE
}
}
}
}
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CircleProgressBarView">
<attr name="backgroundcolor" format="color"/>
<attr name="progresscolor" format="color"/>
<attr name="progress" format="integer"/>
<attr name="radius" format="dimension"/>
<attr name="strokewidth" format="dimension"/>
</declare-styleable>
<declare-styleable name="CircleProgressButton">
<attr name="innerOuterSpace" format="dimension"/>
<attr name="outerStrokeWidth" format="dimension"/>
<attr name="duration" format="integer"/>
<attr name="circleColorList" format="color"/>
<attr name="progressBackground" format="color"/>
<attr name="progressColor" format="color"/>
</declare-styleable>
<declare-styleable name="LoadIngView">
<attr name="baseRes" format="reference"/>
<attr name="animateStyle" format="enum">
<enum name="CIRCLE_ANIMATE" value="0"/>
<enum name="CIRCLE_SHANDOW" value="1"/>
<enum name="CIRCLE_SHAKE" value="2"/>
</attr>
<attr name="animateDuration" format="integer"/>
<attr name="outCircleWidth" format="dimension"/>
<attr name="ovalSpanAngle" format="integer"/>
<attr name="openAngle" format="integer"/>
<attr name="outInnerMargin" format="fraction"/>
<attr name="ovalColor" format="color"/>
</declare-styleable>
</resources>
<resources>
<string name="app_name">Circles</string>
</resources>
package com.x.leo.circles;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* Example local unit test, which will execute on the development machine (host).
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
public class ExampleUnitTest {
@Test
public void addition_isCorrect() throws Exception {
assertEquals(4, 2 + 2);
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment