Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
F
fastdevelop
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
高超
fastdevelop
Commits
d323f1ad
Commit
d323f1ad
authored
Jan 06, 2020
by
gao.chao
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
仿IOS 开关控件
parent
b8181690
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
287 additions
and
4 deletions
+287
-4
app/build.gradle
+1
-1
app/src/main/res/layout/test_layout.xml
+13
-0
fastDevelop/build.gradle
+1
-1
fastDevelop/src/main/java/com/mayi/fastdevelop/view/IOSSwitchView.java
+257
-0
fastDevelop/src/main/res/values/attrs.xml
+13
-0
map/build.gradle
+1
-1
web/build.gradle
+1
-1
No files found.
app/build.gradle
View file @
d323f1ad
...
...
@@ -4,7 +4,7 @@ android {
compileSdkVersion
28
defaultConfig
{
applicationId
"com.mayi.demo"
minSdkVersion
2
0
minSdkVersion
2
1
targetSdkVersion
28
versionCode
1
versionName
"1.0"
...
...
app/src/main/res/layout/test_layout.xml
View file @
d323f1ad
...
...
@@ -9,6 +9,19 @@
android:layout_height=
"match_parent"
android:orientation=
"vertical"
>
<TextView
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:text=
"仿IOS 开关控件"
android:textColor=
"@color/color_666666"
/>
<com.mayi.fastdevelop.view.IOSSwitchView
android:id=
"@+id/s"
android:layout_width=
"@dimen/size_36"
android:layout_height=
"@dimen/size_18"
android:layout_margin=
"@dimen/size_15"
/>
<Button
android:id=
"@+id/b1"
android:layout_width=
"wrap_content"
...
...
fastDevelop/build.gradle
View file @
d323f1ad
...
...
@@ -4,7 +4,7 @@ android {
compileSdkVersion
28
defaultConfig
{
minSdkVersion
2
0
minSdkVersion
2
1
targetSdkVersion
28
versionCode
3
versionName
"1.2"
...
...
fastDevelop/src/main/java/com/mayi/fastdevelop/view/IOSSwitchView.java
0 → 100644
View file @
d323f1ad
package
com
.
mayi
.
fastdevelop
.
view
;
import
android.animation.AnimatorSet
;
import
android.animation.ArgbEvaluator
;
import
android.animation.FloatEvaluator
;
import
android.animation.ObjectAnimator
;
import
android.animation.TypeEvaluator
;
import
android.animation.ValueAnimator
;
import
android.content.Context
;
import
android.content.res.TypedArray
;
import
android.graphics.Canvas
;
import
android.graphics.Color
;
import
android.graphics.Paint
;
import
android.graphics.Path
;
import
android.os.Build
;
import
android.util.AttributeSet
;
import
android.view.MotionEvent
;
import
android.view.View
;
import
android.view.animation.AccelerateDecelerateInterpolator
;
import
androidx.annotation.Nullable
;
import
androidx.annotation.RequiresApi
;
import
com.mayi.fastdevelop.R
;
import
com.mayi.fastdevelop.util.DisplayUtil
;
public
class
IOSSwitchView
extends
View
{
private
Context
mContext
;
private
int
mHeight
,
mWidth
;
private
Path
mPath
;
private
Paint
mStrokePaint
;
//边框画笔
private
Paint
mSolidPaint
;
//填充色画笔
private
Paint
mCirclePaint
;
//小圆球画笔
private
float
mMarginLeft
;
//小圆球到左边距离
private
boolean
mIsCheck
;
//是否被选中
private
int
CIRCLEPADDING
;
private
int
mCircleWidth
;
private
int
mDefaultSolidColor
,
mTargetSolidColor
;
private
int
mDefaultStrokeColor
,
mTargetStrokeColor
;
private
int
mDefaultCircleColor
,
mTargetCircleColor
;
private
int
mSolidColor_
;
private
int
mCircleColor_
;
private
int
mStrokeColor_
;
private
ObjectAnimator
mTranslateAnim
,
mSolidColorAnim
,
mCircleColorAnim
,
mStrokeColorAnim
;
private
int
mStrokeWidth
;
private
int
mRealWidth
;
private
int
mRealHeight
;
public
interface
OnCheckedChange
{
void
onCheckChange
(
boolean
isChecked
);
}
public
IOSSwitchView
(
Context
context
)
{
this
(
context
,
null
);
}
public
IOSSwitchView
(
Context
context
,
@Nullable
AttributeSet
attrs
)
{
this
(
context
,
attrs
,
0
);
}
public
IOSSwitchView
(
Context
context
,
@Nullable
AttributeSet
attrs
,
int
defStyleAttr
)
{
super
(
context
,
attrs
,
defStyleAttr
);
mContext
=
context
;
CIRCLEPADDING
=
DisplayUtil
.
dip2px
(
mContext
,
1
);
TypedArray
a
=
mContext
.
obtainStyledAttributes
(
attrs
,
R
.
styleable
.
IOSSwitchView
);
mDefaultStrokeColor
=
a
.
getColor
(
R
.
styleable
.
IOSSwitchView_default_stroke_color
,
Color
.
parseColor
(
"#707070"
));
mTargetStrokeColor
=
a
.
getColor
(
R
.
styleable
.
IOSSwitchView_target_stroke_color
,
Color
.
parseColor
(
"#E83C3C"
));
mTargetCircleColor
=
a
.
getColor
(
R
.
styleable
.
IOSSwitchView_target_circle_color
,
Color
.
parseColor
(
"#E83C3C"
));
mDefaultCircleColor
=
a
.
getColor
(
R
.
styleable
.
IOSSwitchView_default_circle_color
,
Color
.
parseColor
(
"#707070"
));
mDefaultSolidColor
=
a
.
getColor
(
R
.
styleable
.
IOSSwitchView_default_solid_color
,
Color
.
WHITE
);
mTargetSolidColor
=
a
.
getColor
(
R
.
styleable
.
IOSSwitchView_target_solid_color
,
Color
.
WHITE
);
mIsCheck
=
a
.
getBoolean
(
R
.
styleable
.
IOSSwitchView_checked
,
false
);
mSolidColor_
=
mIsCheck
?
mTargetSolidColor
:
mDefaultSolidColor
;
mCircleColor_
=
mIsCheck
?
mTargetCircleColor
:
mDefaultCircleColor
;
mStrokeColor_
=
mIsCheck
?
mTargetStrokeColor
:
mDefaultStrokeColor
;
mTranslateAnim
=
initAnim
(
"mMarginLeft"
,
new
FloatEvaluator
());
mSolidColorAnim
=
initAnim
(
"mSolidColor_"
,
new
ArgbEvaluator
());
mCircleColorAnim
=
initAnim
(
"mCircleColor_"
,
new
ArgbEvaluator
());
mStrokeColorAnim
=
initAnim
(
"mStrokeColor_"
,
new
ArgbEvaluator
());
mStrokeWidth
=
DisplayUtil
.
dip2px
(
mContext
,
2
f
);
mMarginLeft
=
0
;
mPath
=
new
Path
();
mCirclePaint
=
new
Paint
();
mStrokePaint
=
new
Paint
();
mSolidPaint
=
new
Paint
();
initPaint
(
mCirclePaint
,
mSolidPaint
,
mStrokePaint
);
mStrokePaint
.
setStyle
(
Paint
.
Style
.
STROKE
);
mTranslateAnim
.
addUpdateListener
(
new
ValueAnimator
.
AnimatorUpdateListener
()
{
@Override
public
void
onAnimationUpdate
(
ValueAnimator
animation
)
{
mMarginLeft
=
(
float
)
(
animation
.
getAnimatedValue
());
postInvalidate
();
}
});
mCircleColorAnim
.
addUpdateListener
(
new
ValueAnimator
.
AnimatorUpdateListener
()
{
@Override
public
void
onAnimationUpdate
(
ValueAnimator
animation
)
{
mCircleColor_
=
(
int
)
animation
.
getAnimatedValue
();
postInvalidate
();
}
});
mSolidColorAnim
.
addUpdateListener
(
new
ValueAnimator
.
AnimatorUpdateListener
()
{
@Override
public
void
onAnimationUpdate
(
ValueAnimator
animation
)
{
mSolidColor_
=
(
int
)
animation
.
getAnimatedValue
();
postInvalidate
();
}
});
mStrokeColorAnim
.
addUpdateListener
(
new
ValueAnimator
.
AnimatorUpdateListener
()
{
@Override
public
void
onAnimationUpdate
(
ValueAnimator
animation
)
{
mStrokeColor_
=
(
int
)
animation
.
getAnimatedValue
();
postInvalidate
();
}
});
}
private
ObjectAnimator
initAnim
(
String
propertyName
,
TypeEvaluator
evaluator
)
{
ObjectAnimator
anim
=
new
ObjectAnimator
();
anim
.
setTarget
(
this
);
//这里千万记住别写错,楼主因为写成了setObjectValue被坑了好几个小时
anim
.
setPropertyName
(
propertyName
);
anim
.
setEvaluator
(
evaluator
);
return
anim
;
}
public
void
initPaint
(
Paint
...
paints
)
{
for
(
int
i
=
0
;
i
<
paints
.
length
;
i
++)
{
paints
[
i
].
setAntiAlias
(
true
);
paints
[
i
].
setStrokeWidth
(
mStrokeWidth
);
}
}
public
void
startAnim
(
boolean
isCheck
)
{
if
(
isCheck
)
{
mCircleColorAnim
.
setIntValues
(
mDefaultCircleColor
,
mTargetCircleColor
);
mTranslateAnim
.
setFloatValues
(
0
,
mWidth
-
mHeight
);
mSolidColorAnim
.
setIntValues
(
mDefaultSolidColor
,
mTargetSolidColor
);
mStrokeColorAnim
.
setIntValues
(
mDefaultStrokeColor
,
mTargetStrokeColor
);
}
else
{
mCircleColorAnim
.
setIntValues
(
mTargetCircleColor
,
mDefaultCircleColor
);
mTranslateAnim
.
setFloatValues
(
mWidth
-
mHeight
,
0
);
mSolidColorAnim
.
setIntValues
(
mTargetSolidColor
,
mDefaultSolidColor
);
mStrokeColorAnim
.
setIntValues
(
mTargetStrokeColor
,
mDefaultStrokeColor
);
}
AnimatorSet
set
=
new
AnimatorSet
();
set
.
setDuration
(
200
);
set
.
setInterpolator
(
new
AccelerateDecelerateInterpolator
());
set
.
playTogether
(
mTranslateAnim
,
mCircleColorAnim
,
mSolidColorAnim
,
mStrokeColorAnim
);
set
.
start
();
}
@Override
protected
void
onDraw
(
Canvas
canvas
)
{
super
.
onDraw
(
canvas
);
if
(
mWidth
==
0
)
{
mWidth
=
getWidth
();
mHeight
=
getHeight
();
mRealWidth
=
mWidth
-
mStrokeWidth
*
2
;
mRealHeight
=
mHeight
-
mStrokeWidth
*
2
;
mMarginLeft
=
mIsCheck
?
mWidth
-
mHeight
:
0
;
mCircleWidth
=
mHeight
-
CIRCLEPADDING
*
2
-
mStrokeWidth
*
2
;
}
if
(
mWidth
<=
0
||
mHeight
<=
0
)
return
;
mPath
.
reset
();
mSolidPaint
.
setColor
(
mSolidColor_
);
mStrokePaint
.
setColor
(
mStrokeColor_
);
mCirclePaint
.
setColor
(
mCircleColor_
);
mPath
.
addRoundRect
(
mStrokeWidth
,
mStrokeWidth
,
mRealWidth
+
mStrokeWidth
,
mRealHeight
+
mStrokeWidth
,
mRealHeight
/
2
,
mRealHeight
/
2
,
Path
.
Direction
.
CW
);
canvas
.
drawPath
(
mPath
,
mStrokePaint
);
canvas
.
drawPath
(
mPath
,
mSolidPaint
);
canvas
.
drawCircle
(
mHeight
/
2.0f
+
mMarginLeft
,
mHeight
/
2
f
,
mCircleWidth
/
2
,
mCirclePaint
);
}
public
void
setCheck
(
boolean
checked
)
{
this
.
setCheck
(
checked
,
true
);
}
private
void
setCheck
(
boolean
checked
,
boolean
fromOut
)
{
boolean
flag
=
mIsCheck
==
checked
;
mIsCheck
=
checked
;
if
(
mListener
!=
null
&&
!
flag
)
{
mListener
.
onCheckChange
(
mIsCheck
);
}
if
(!
fromOut
)
{
startAnim
(
mIsCheck
);
}
else
{
mSolidColor_
=
mIsCheck
?
mTargetSolidColor
:
mDefaultSolidColor
;
mCircleColor_
=
mIsCheck
?
mTargetCircleColor
:
mDefaultCircleColor
;
mStrokeColor_
=
mIsCheck
?
mTargetStrokeColor
:
mDefaultStrokeColor
;
mMarginLeft
=
mIsCheck
?
mWidth
-
mHeight
:
0
;
postInvalidate
();
}
}
public
float
getMarginLeft
()
{
return
mMarginLeft
;
}
private
OnCheckedChange
mListener
;
public
void
setOnCheckedChangeListener
(
OnCheckedChange
listener
)
{
mListener
=
listener
;
}
public
void
setMarginLeft
(
float
marginLeft
)
{
mMarginLeft
=
marginLeft
;
}
public
int
getSolidColor_
()
{
return
mSolidColor_
;
}
public
void
setSolidColor_
(
int
solidColor_
)
{
mSolidColor_
=
solidColor_
;
}
public
int
getCircleColor_
()
{
return
mCircleColor_
;
}
public
void
setCircleColor_
(
int
circleColor_
)
{
mCircleColor_
=
circleColor_
;
}
public
int
getStrokeColor_
()
{
return
mStrokeColor_
;
}
public
void
setStrokeColor_
(
int
strokeColor_
)
{
mStrokeColor_
=
strokeColor_
;
}
@Override
public
boolean
onTouchEvent
(
MotionEvent
event
)
{
switch
(
event
.
getAction
())
{
case
MotionEvent
.
ACTION_DOWN
:
if
(
mTranslateAnim
.
isRunning
())
{
return
false
;
}
return
true
;
case
MotionEvent
.
ACTION_CANCEL
:
return
false
;
case
MotionEvent
.
ACTION_UP
:
setCheck
(!
mIsCheck
,
false
);
return
true
;
}
return
true
;
}
public
boolean
isCheck
()
{
return
mIsCheck
;
}
}
\ No newline at end of file
fastDevelop/src/main/res/values/attrs.xml
View file @
d323f1ad
...
...
@@ -17,4 +17,16 @@
<attr
name=
"label_text"
format=
"string"
/>
<attr
name=
"label_text_size"
format=
"float"
/>
</declare-styleable>
<declare-styleable
name=
"IOSSwitchView"
>
<attr
name=
"default_stroke_color"
format=
"color"
/>
<attr
name=
"target_stroke_color"
format=
"color"
/>
<attr
name=
"default_circle_color"
format=
"color"
/>
<attr
name=
"default_solid_color"
format=
"color"
/>
<attr
name=
"target_circle_color"
format=
"color"
/>
<attr
name=
"target_solid_color"
format=
"color"
/>
<attr
name=
"checked"
format=
"boolean"
/>
</declare-styleable>
</resources>
\ No newline at end of file
map/build.gradle
View file @
d323f1ad
...
...
@@ -3,7 +3,7 @@ apply plugin: 'com.android.library'
android
{
compileSdkVersion
28
defaultConfig
{
minSdkVersion
2
0
minSdkVersion
2
1
targetSdkVersion
28
versionCode
1
versionName
"1.0"
...
...
web/build.gradle
View file @
d323f1ad
...
...
@@ -3,7 +3,7 @@ apply plugin: 'com.android.library'
android
{
compileSdkVersion
28
defaultConfig
{
minSdkVersion
2
0
minSdkVersion
2
1
targetSdkVersion
28
versionCode
2
versionName
"1.1"
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment