Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
Y
YDL-Component-Medical
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
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
杨凯
YDL-Component-Medical
Commits
59834452
Commit
59834452
authored
Jul 20, 2022
by
霍志良
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat:rangeSeekbar引入
parent
d78fbf45
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
2392 additions
and
14 deletions
+2392
-14
FilterPopupWindow.kt
m-consultant/src/main/java/com/yidianling/consultant/ui/view/FilterPopupWindow.kt
+0
-1
OnRangeChangedListener.java
m-consultant/src/main/java/com/yidianling/consultant/ui/view/rangeseekbar/OnRangeChangedListener.java
+17
-0
RangeSeekBar.java
m-consultant/src/main/java/com/yidianling/consultant/ui/view/rangeseekbar/RangeSeekBar.java
+1238
-0
SavedState.java
m-consultant/src/main/java/com/yidianling/consultant/ui/view/rangeseekbar/SavedState.java
+56
-0
SeekBar.java
m-consultant/src/main/java/com/yidianling/consultant/ui/view/rangeseekbar/SeekBar.java
+685
-0
SeekBarState.java
m-consultant/src/main/java/com/yidianling/consultant/ui/view/rangeseekbar/SeekBarState.java
+21
-0
Utils.java
m-consultant/src/main/java/com/yidianling/consultant/ui/view/rangeseekbar/Utils.java
+185
-0
rsb_default_thumb.xml
m-consultant/src/main/res/drawable/rsb_default_thumb.xml
+9
-0
thumb_yellow_stroke.xml
m-consultant/src/main/res/drawable/thumb_yellow_stroke.xml
+9
-0
consultant_ui_filter_popup.xml
m-consultant/src/main/res/layout/consultant_ui_filter_popup.xml
+20
-8
arrays.xml
m-consultant/src/main/res/values/arrays.xml
+12
-0
attrs.xml
m-consultant/src/main/res/values/attrs.xml
+140
-0
styles.xml
m-consultant/src/main/res/values/styles.xml
+0
-5
No files found.
m-consultant/src/main/java/com/yidianling/consultant/ui/view/FilterPopupWindow.kt
View file @
59834452
...
@@ -107,7 +107,6 @@ class FilterPopupWindow(
...
@@ -107,7 +107,6 @@ class FilterPopupWindow(
view
.
btnReset
.
setOnClickListener
{
view
.
btnReset
.
setOnClickListener
{
reset
()
reset
()
}
}
view
.
rangeSliderPrice
.
labelBehavior
=
LabelFormatter
.
LABEL_WITHIN_BOUNDS
view
.
btnConfirm
.
setOnClickListener
{
view
.
btnConfirm
.
setOnClickListener
{
if
(
tempFilter
.
priceRanges
?.
key1
==
"avg_price"
&&
filterData
.
priceRanges
.
isNotEmpty
())
{
if
(
tempFilter
.
priceRanges
?.
key1
==
"avg_price"
&&
filterData
.
priceRanges
.
isNotEmpty
())
{
tempFilter
.
priceRanges
?.
key1
=
filterData
.
priceRanges
[
0
].
key1
tempFilter
.
priceRanges
?.
key1
=
filterData
.
priceRanges
[
0
].
key1
...
...
m-consultant/src/main/java/com/yidianling/consultant/ui/view/rangeseekbar/OnRangeChangedListener.java
0 → 100644
View file @
59834452
package
com
.
yidianling
.
consultant
.
ui
.
view
.
rangeseekbar
;
/**
* ================================================
* 作 者:JayGoo
* 版 本:
* 创建日期:2018/5/8
* 描 述:
* ================================================
*/
public
interface
OnRangeChangedListener
{
void
onRangeChanged
(
RangeSeekBar
view
,
float
leftValue
,
float
rightValue
,
boolean
isFromUser
);
void
onStartTrackingTouch
(
RangeSeekBar
view
,
boolean
isLeft
);
void
onStopTrackingTouch
(
RangeSeekBar
view
,
boolean
isLeft
);
}
m-consultant/src/main/java/com/yidianling/consultant/ui/view/rangeseekbar/RangeSeekBar.java
0 → 100755
View file @
59834452
package
com
.
yidianling
.
consultant
.
ui
.
view
.
rangeseekbar
;
import
android.content.Context
;
import
android.content.res.TypedArray
;
import
android.graphics.Bitmap
;
import
android.graphics.Canvas
;
import
android.graphics.Paint
;
import
android.graphics.Rect
;
import
android.graphics.RectF
;
import
android.graphics.Typeface
;
import
android.os.Parcelable
;
import
android.text.TextUtils
;
import
android.util.AttributeSet
;
import
android.util.Log
;
import
android.view.MotionEvent
;
import
android.view.View
;
import
android.view.ViewGroup
;
import
androidx.annotation.ColorInt
;
import
androidx.annotation.DrawableRes
;
import
androidx.annotation.IntDef
;
import
com.yidianling.consultant.R
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.math.BigDecimal
;
import
java.math.RoundingMode
;
import
java.util.ArrayList
;
import
java.util.List
;
import
static
com
.
yidianling
.
consultant
.
ui
.
view
.
rangeseekbar
.
SeekBar
.
INDICATOR_ALWAYS_HIDE
;
import
static
com
.
yidianling
.
consultant
.
ui
.
view
.
rangeseekbar
.
SeekBar
.
INDICATOR_ALWAYS_SHOW
;
public
class
RangeSeekBar
extends
View
{
//normal seekBar mode
public
final
static
int
SEEKBAR_MODE_SINGLE
=
1
;
//RangeSeekBar
public
final
static
int
SEEKBAR_MODE_RANGE
=
2
;
//number according to the actual proportion of the number of arranged;
public
final
static
int
TRICK_MARK_MODE_NUMBER
=
0
;
//other equally arranged
public
final
static
int
TRICK_MARK_MODE_OTHER
=
1
;
//tick mark text gravity
public
final
static
int
TICK_MARK_GRAVITY_LEFT
=
0
;
public
final
static
int
TICK_MARK_GRAVITY_CENTER
=
1
;
public
final
static
int
TICK_MARK_GRAVITY_RIGHT
=
2
;
private
final
static
int
MIN_INTERCEPT_DISTANCE
=
100
;
float
touchDownX
,
touchDownY
;
//剩余最小间隔的进度
float
reservePercent
;
boolean
isScaleThumb
=
false
;
Paint
paint
=
new
Paint
();
RectF
progressDefaultDstRect
=
new
RectF
();
RectF
progressDstRect
=
new
RectF
();
Rect
progressSrcRect
=
new
Rect
();
RectF
stepDivRect
=
new
RectF
();
Rect
tickMarkTextRect
=
new
Rect
();
SeekBar
leftSB
;
SeekBar
rightSB
;
SeekBar
currTouchSB
;
Bitmap
progressBitmap
;
Bitmap
progressDefaultBitmap
;
List
<
Bitmap
>
stepsBitmaps
=
new
ArrayList
<>();
private
int
progressTop
,
progressBottom
,
progressLeft
,
progressRight
;
private
int
seekBarMode
;
//刻度模式:number根据数字实际比例排列;other 均分排列
private
int
tickMarkMode
;
//刻度与进度条间的间距
//The spacing between the tick mark and the progress bar
private
int
tickMarkTextMargin
;
//刻度文字与提示文字的大小
//tick mark text and prompt text size
private
int
tickMarkTextSize
;
private
int
tickMarkGravity
;
private
int
tickMarkLayoutGravity
;
private
int
tickMarkTextColor
;
private
int
tickMarkInRangeTextColor
;
//刻度上显示的文字
//The texts displayed on the scale
private
CharSequence
[]
tickMarkTextArray
;
//进度条圆角
//radius of progress bar
private
float
progressRadius
;
//进度中进度条的颜色
//the color of seekBar in progress
private
int
progressColor
;
//默认进度条颜色
//the default color of the progress bar
private
int
progressDefaultColor
;
//the drawable of seekBar in progress
private
int
progressDrawableId
;
//the default Drawable of the progress bar
private
int
progressDefaultDrawableId
;
//the progress height
private
int
progressHeight
;
// the progress width
private
int
progressWidth
;
//the range interval of RangeSeekBar
private
float
minInterval
;
private
int
gravity
;
//****************** the above is attr value ******************//
//enable RangeSeekBar two thumb Overlap
private
boolean
enableThumbOverlap
;
//the color of step divs
private
int
stepsColor
;
//the width of each step
private
float
stepsWidth
;
//the height of each step
private
float
stepsHeight
;
//the radius of step divs
private
float
stepsRadius
;
//steps is 0 will disable StepSeekBar
private
int
steps
;
//the thumb will automatic bonding close to its value
private
boolean
stepsAutoBonding
;
private
int
stepsDrawableId
;
//True values set by the user
private
float
minProgress
,
maxProgress
;
private
boolean
isEnable
=
true
;
private
int
progressPaddingRight
;
private
OnRangeChangedListener
callback
;
public
RangeSeekBar
(
Context
context
)
{
this
(
context
,
null
);
}
public
RangeSeekBar
(
Context
context
,
AttributeSet
attrs
)
{
super
(
context
,
attrs
);
initAttrs
(
attrs
);
initPaint
();
initSeekBar
(
attrs
);
initStepsBitmap
();
}
private
void
initProgressBitmap
()
{
if
(
progressBitmap
==
null
)
{
progressBitmap
=
Utils
.
drawableToBitmap
(
getContext
(),
progressWidth
,
progressHeight
,
progressDrawableId
);
}
if
(
progressDefaultBitmap
==
null
)
{
progressDefaultBitmap
=
Utils
.
drawableToBitmap
(
getContext
(),
progressWidth
,
progressHeight
,
progressDefaultDrawableId
);
}
}
private
boolean
verifyStepsMode
()
{
if
(
steps
<
1
||
stepsHeight
<=
0
||
stepsWidth
<=
0
)
return
false
;
return
true
;
}
private
void
initStepsBitmap
()
{
if
(!
verifyStepsMode
()
||
stepsDrawableId
==
0
)
return
;
if
(
stepsBitmaps
.
isEmpty
())
{
Bitmap
bitmap
=
Utils
.
drawableToBitmap
(
getContext
(),
(
int
)
stepsWidth
,
(
int
)
stepsHeight
,
stepsDrawableId
);
for
(
int
i
=
0
;
i
<=
steps
;
i
++)
{
stepsBitmaps
.
add
(
bitmap
);
}
}
}
private
void
initSeekBar
(
AttributeSet
attrs
)
{
leftSB
=
new
SeekBar
(
this
,
attrs
,
true
);
rightSB
=
new
SeekBar
(
this
,
attrs
,
false
);
rightSB
.
setVisible
(
seekBarMode
!=
SEEKBAR_MODE_SINGLE
);
}
private
void
initAttrs
(
AttributeSet
attrs
)
{
try
{
TypedArray
t
=
getContext
().
obtainStyledAttributes
(
attrs
,
R
.
styleable
.
RangeSeekBar
);
seekBarMode
=
t
.
getInt
(
R
.
styleable
.
RangeSeekBar_rsb_mode
,
SEEKBAR_MODE_RANGE
);
minProgress
=
t
.
getFloat
(
R
.
styleable
.
RangeSeekBar_rsb_min
,
0
);
maxProgress
=
t
.
getFloat
(
R
.
styleable
.
RangeSeekBar_rsb_max
,
100
);
minInterval
=
t
.
getFloat
(
R
.
styleable
.
RangeSeekBar_rsb_min_interval
,
0
);
gravity
=
t
.
getInt
(
R
.
styleable
.
RangeSeekBar_rsb_gravity
,
Gravity
.
TOP
);
progressColor
=
t
.
getColor
(
R
.
styleable
.
RangeSeekBar_rsb_progress_color
,
0xFF4BD962
);
progressRadius
=
(
int
)
t
.
getDimension
(
R
.
styleable
.
RangeSeekBar_rsb_progress_radius
,
-
1
);
progressDefaultColor
=
t
.
getColor
(
R
.
styleable
.
RangeSeekBar_rsb_progress_default_color
,
0xFFD7D7D7
);
progressDrawableId
=
t
.
getResourceId
(
R
.
styleable
.
RangeSeekBar_rsb_progress_drawable
,
0
);
progressDefaultDrawableId
=
t
.
getResourceId
(
R
.
styleable
.
RangeSeekBar_rsb_progress_drawable_default
,
0
);
progressHeight
=
(
int
)
t
.
getDimension
(
R
.
styleable
.
RangeSeekBar_rsb_progress_height
,
Utils
.
dp2px
(
getContext
(),
2
));
tickMarkMode
=
t
.
getInt
(
R
.
styleable
.
RangeSeekBar_rsb_tick_mark_mode
,
TRICK_MARK_MODE_NUMBER
);
tickMarkGravity
=
t
.
getInt
(
R
.
styleable
.
RangeSeekBar_rsb_tick_mark_gravity
,
TICK_MARK_GRAVITY_CENTER
);
tickMarkLayoutGravity
=
t
.
getInt
(
R
.
styleable
.
RangeSeekBar_rsb_tick_mark_layout_gravity
,
Gravity
.
TOP
);
tickMarkTextArray
=
t
.
getTextArray
(
R
.
styleable
.
RangeSeekBar_rsb_tick_mark_text_array
);
tickMarkTextMargin
=
(
int
)
t
.
getDimension
(
R
.
styleable
.
RangeSeekBar_rsb_tick_mark_text_margin
,
Utils
.
dp2px
(
getContext
(),
7
));
tickMarkTextSize
=
(
int
)
t
.
getDimension
(
R
.
styleable
.
RangeSeekBar_rsb_tick_mark_text_size
,
Utils
.
dp2px
(
getContext
(),
12
));
tickMarkTextColor
=
t
.
getColor
(
R
.
styleable
.
RangeSeekBar_rsb_tick_mark_text_color
,
progressDefaultColor
);
tickMarkInRangeTextColor
=
t
.
getColor
(
R
.
styleable
.
RangeSeekBar_rsb_tick_mark_in_range_text_color
,
progressColor
);
steps
=
t
.
getInt
(
R
.
styleable
.
RangeSeekBar_rsb_steps
,
0
);
stepsColor
=
t
.
getColor
(
R
.
styleable
.
RangeSeekBar_rsb_step_color
,
0xFF9d9d9d
);
stepsRadius
=
t
.
getDimension
(
R
.
styleable
.
RangeSeekBar_rsb_step_radius
,
0
);
stepsWidth
=
t
.
getDimension
(
R
.
styleable
.
RangeSeekBar_rsb_step_width
,
0
);
stepsHeight
=
t
.
getDimension
(
R
.
styleable
.
RangeSeekBar_rsb_step_height
,
0
);
stepsDrawableId
=
t
.
getResourceId
(
R
.
styleable
.
RangeSeekBar_rsb_step_drawable
,
0
);
stepsAutoBonding
=
t
.
getBoolean
(
R
.
styleable
.
RangeSeekBar_rsb_step_auto_bonding
,
true
);
t
.
recycle
();
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
}
/**
* measure progress bar position
*/
protected
void
onMeasureProgress
(
int
w
,
int
h
)
{
int
viewHeight
=
h
-
getPaddingBottom
()
-
getPaddingTop
();
if
(
h
<=
0
)
return
;
if
(
gravity
==
Gravity
.
TOP
)
{
//calculate the height of indicator and thumb exceeds the part of the progress
float
maxIndicatorHeight
=
0
;
if
(
leftSB
.
getIndicatorShowMode
()
!=
INDICATOR_ALWAYS_HIDE
||
rightSB
.
getIndicatorShowMode
()
!=
INDICATOR_ALWAYS_HIDE
)
{
maxIndicatorHeight
=
Math
.
max
(
leftSB
.
getIndicatorRawHeight
(),
rightSB
.
getIndicatorRawHeight
());
}
float
thumbHeight
=
Math
.
max
(
leftSB
.
getThumbScaleHeight
(),
rightSB
.
getThumbScaleHeight
());
thumbHeight
-=
progressHeight
/
2
f
;
//default height is indicator + thumb exceeds the part of the progress bar
//if tickMark height is greater than (indicator + thumb exceeds the part of the progress)
progressTop
=
(
int
)
(
maxIndicatorHeight
+
(
thumbHeight
-
progressHeight
)
/
2
f
);
if
(
tickMarkTextArray
!=
null
&&
tickMarkLayoutGravity
==
Gravity
.
TOP
)
{
progressTop
=
(
int
)
Math
.
max
(
getTickMarkRawHeight
(),
maxIndicatorHeight
+
(
thumbHeight
-
progressHeight
)
/
2
f
);
}
progressBottom
=
progressTop
+
progressHeight
;
}
else
if
(
gravity
==
Gravity
.
BOTTOM
)
{
if
(
tickMarkTextArray
!=
null
&&
tickMarkLayoutGravity
==
Gravity
.
BOTTOM
)
{
progressBottom
=
viewHeight
-
getTickMarkRawHeight
();
}
else
{
progressBottom
=
(
int
)
(
viewHeight
-
Math
.
max
(
leftSB
.
getThumbScaleHeight
(),
rightSB
.
getThumbScaleHeight
())
/
2
f
+
progressHeight
/
2
f
);
}
progressTop
=
progressBottom
-
progressHeight
;
}
else
{
progressTop
=
(
viewHeight
-
progressHeight
)
/
2
;
progressBottom
=
progressTop
+
progressHeight
;
}
int
maxThumbWidth
=
(
int
)
Math
.
max
(
leftSB
.
getThumbScaleWidth
(),
rightSB
.
getThumbScaleWidth
());
progressLeft
=
maxThumbWidth
/
2
+
getPaddingLeft
();
progressRight
=
w
-
maxThumbWidth
/
2
-
getPaddingRight
();
progressWidth
=
progressRight
-
progressLeft
;
progressDefaultDstRect
.
set
(
getProgressLeft
(),
getProgressTop
(),
getProgressRight
(),
getProgressBottom
());
progressPaddingRight
=
w
-
progressRight
;
//default value
if
(
progressRadius
<=
0
)
{
progressRadius
=
(
int
)
((
getProgressBottom
()
-
getProgressTop
())
*
0.45f
);
}
initProgressBitmap
();
}
//Android 7.0以后,优化了View的绘制,onMeasure和onSizeChanged调用顺序有所变化
//Android7.0以下:onMeasure--->onSizeChanged--->onMeasure
//Android7.0以上:onMeasure--->onSizeChanged
@Override
protected
void
onMeasure
(
int
widthMeasureSpec
,
int
heightMeasureSpec
)
{
int
heightSize
=
MeasureSpec
.
getSize
(
heightMeasureSpec
);
int
heightMode
=
MeasureSpec
.
getMode
(
heightMeasureSpec
);
/*
* onMeasure传入的widthMeasureSpec和heightMeasureSpec不是一般的尺寸数值,而是将模式和尺寸组合在一起的数值
* MeasureSpec.EXACTLY 是精确尺寸
* MeasureSpec.AT_MOST 是最大尺寸
* MeasureSpec.UNSPECIFIED 是未指定尺寸
*/
if
(
heightMode
==
MeasureSpec
.
EXACTLY
)
{
heightSize
=
MeasureSpec
.
makeMeasureSpec
(
heightSize
,
MeasureSpec
.
EXACTLY
);
}
else
if
(
heightMode
==
MeasureSpec
.
AT_MOST
&&
getParent
()
instanceof
ViewGroup
&&
heightSize
==
ViewGroup
.
LayoutParams
.
MATCH_PARENT
)
{
heightSize
=
MeasureSpec
.
makeMeasureSpec
(((
ViewGroup
)
getParent
()).
getMeasuredHeight
(),
MeasureSpec
.
AT_MOST
);
}
else
{
int
heightNeeded
;
if
(
gravity
==
Gravity
.
CENTER
)
{
if
(
tickMarkTextArray
!=
null
&&
tickMarkLayoutGravity
==
Gravity
.
BOTTOM
)
{
heightNeeded
=
(
int
)
(
2
*
(
getRawHeight
()
-
getTickMarkRawHeight
()));
}
else
{
heightNeeded
=
(
int
)
(
2
*
(
getRawHeight
()
-
Math
.
max
(
leftSB
.
getThumbScaleHeight
(),
rightSB
.
getThumbScaleHeight
())
/
2
));
}
}
else
{
heightNeeded
=
(
int
)
getRawHeight
();
}
heightSize
=
MeasureSpec
.
makeMeasureSpec
(
heightNeeded
,
MeasureSpec
.
EXACTLY
);
}
super
.
onMeasure
(
widthMeasureSpec
,
heightSize
);
}
protected
int
getTickMarkRawHeight
()
{
if
(
tickMarkTextArray
!=
null
&&
tickMarkTextArray
.
length
>
0
)
{
return
tickMarkTextMargin
+
Utils
.
measureText
(
String
.
valueOf
(
tickMarkTextArray
[
0
]),
tickMarkTextSize
).
height
()
+
3
;
}
return
0
;
}
protected
float
getRawHeight
()
{
float
rawHeight
;
if
(
seekBarMode
==
SEEKBAR_MODE_SINGLE
)
{
rawHeight
=
leftSB
.
getRawHeight
();
if
(
tickMarkLayoutGravity
==
Gravity
.
BOTTOM
&&
tickMarkTextArray
!=
null
)
{
float
h
=
Math
.
max
((
leftSB
.
getThumbScaleHeight
()
-
progressHeight
)
/
2
,
getTickMarkRawHeight
());
rawHeight
=
rawHeight
-
leftSB
.
getThumbScaleHeight
()
/
2
+
progressHeight
/
2
f
+
h
;
}
}
else
{
rawHeight
=
Math
.
max
(
leftSB
.
getRawHeight
(),
rightSB
.
getRawHeight
());
if
(
tickMarkLayoutGravity
==
Gravity
.
BOTTOM
&&
tickMarkTextArray
!=
null
)
{
float
thumbHeight
=
Math
.
max
(
leftSB
.
getThumbScaleHeight
(),
rightSB
.
getThumbScaleHeight
());
float
h
=
Math
.
max
((
thumbHeight
-
progressHeight
)
/
2
,
getTickMarkRawHeight
());
rawHeight
=
rawHeight
-
thumbHeight
/
2
+
progressHeight
/
2
f
+
h
;
}
}
return
rawHeight
;
}
@Override
protected
void
onSizeChanged
(
int
w
,
int
h
,
int
oldw
,
int
oldh
)
{
super
.
onSizeChanged
(
w
,
h
,
oldw
,
oldh
);
onMeasureProgress
(
w
,
h
);
//set default value
setRange
(
minProgress
,
maxProgress
,
minInterval
);
// initializes the positions of the two thumbs
int
lineCenterY
=
(
getProgressBottom
()
+
getProgressTop
())
/
2
;
leftSB
.
onSizeChanged
(
getProgressLeft
(),
lineCenterY
);
if
(
seekBarMode
==
SEEKBAR_MODE_RANGE
)
{
rightSB
.
onSizeChanged
(
getProgressLeft
(),
lineCenterY
);
}
}
@Override
protected
void
onDraw
(
Canvas
canvas
)
{
super
.
onDraw
(
canvas
);
onDrawTickMark
(
canvas
,
paint
);
onDrawProgressBar
(
canvas
,
paint
,
true
);
onDrawSteps
(
canvas
,
paint
);
onDrawSeekBar
(
canvas
);
}
//绘制刻度,并且根据当前位置是否在刻度范围内设置不同的颜色显示
// Draw the scales, and according to the current position is set within
// the scale range of different color display
protected
void
onDrawTickMark
(
Canvas
canvas
,
Paint
paint
)
{
if
(
tickMarkTextArray
!=
null
)
{
int
trickPartWidth
=
progressWidth
/
(
tickMarkTextArray
.
length
-
1
);
for
(
int
i
=
0
;
i
<
tickMarkTextArray
.
length
;
i
++)
{
final
String
text2Draw
=
tickMarkTextArray
[
i
].
toString
();
if
(
TextUtils
.
isEmpty
(
text2Draw
))
continue
;
paint
.
getTextBounds
(
text2Draw
,
0
,
text2Draw
.
length
(),
tickMarkTextRect
);
paint
.
setColor
(
tickMarkTextColor
);
//平分显示
float
x
;
if
(
tickMarkMode
==
TRICK_MARK_MODE_OTHER
)
{
Log
.
e
(
"aaaa"
,
"tickMarkGravity"
+
tickMarkGravity
);
if
(
tickMarkGravity
==
TICK_MARK_GRAVITY_RIGHT
)
{
x
=
getProgressLeft
()
+
i
*
trickPartWidth
-
tickMarkTextRect
.
width
();
}
else
if
(
tickMarkGravity
==
TICK_MARK_GRAVITY_CENTER
)
{
if
(
i
==
tickMarkTextArray
.
length
-
1
)
{
x
=
getProgressLeft
()
+
i
*
trickPartWidth
-
tickMarkTextRect
.
width
()
/
2
f
-
20
;
}
else
{
x
=
getProgressLeft
()
+
i
*
trickPartWidth
-
tickMarkTextRect
.
width
()
/
2
f
;
}
}
else
{
x
=
getProgressLeft
()
+
i
*
trickPartWidth
;
}
}
else
{
float
num
=
Utils
.
parseFloat
(
text2Draw
);
SeekBarState
[]
states
=
getRangeSeekBarState
();
if
(
Utils
.
compareFloat
(
num
,
states
[
0
].
value
)
!=
-
1
&&
Utils
.
compareFloat
(
num
,
states
[
1
].
value
)
!=
1
&&
(
seekBarMode
==
SEEKBAR_MODE_RANGE
))
{
paint
.
setColor
(
tickMarkInRangeTextColor
);
}
//按实际比例显示
x
=
getProgressLeft
()
+
progressWidth
*
(
num
-
minProgress
)
/
(
maxProgress
-
minProgress
)
-
tickMarkTextRect
.
width
()
/
2
f
;
}
float
y
;
if
(
tickMarkLayoutGravity
==
Gravity
.
TOP
)
{
y
=
getProgressTop
()
-
tickMarkTextMargin
;
}
else
{
y
=
getProgressBottom
()
+
tickMarkTextMargin
+
tickMarkTextRect
.
height
()
-
10
;
}
canvas
.
drawText
(
text2Draw
,
x
,
y
,
paint
);
}
}
}
//绘制进度条 另外在收尾两端绘制2个实心点
// draw the progress bar
protected
void
onDrawProgressBar
(
Canvas
canvas
,
Paint
paint
,
Boolean
isNeedStartEnd
)
{
//draw default progress
if
(
Utils
.
verifyBitmap
(
progressDefaultBitmap
))
{
canvas
.
drawBitmap
(
progressDefaultBitmap
,
null
,
progressDefaultDstRect
,
paint
);
}
else
{
paint
.
setColor
(
progressDefaultColor
);
canvas
.
drawRoundRect
(
progressDefaultDstRect
,
progressRadius
,
progressRadius
,
paint
);
}
//draw progress
if
(
seekBarMode
==
SEEKBAR_MODE_RANGE
)
{
progressDstRect
.
top
=
getProgressTop
();
progressDstRect
.
left
=
leftSB
.
left
+
leftSB
.
getThumbScaleWidth
()
/
2
f
+
progressWidth
*
leftSB
.
currPercent
;
progressDstRect
.
right
=
rightSB
.
left
+
rightSB
.
getThumbScaleWidth
()
/
2
f
+
progressWidth
*
rightSB
.
currPercent
;
progressDstRect
.
bottom
=
getProgressBottom
();
}
else
{
progressDstRect
.
top
=
getProgressTop
();
progressDstRect
.
left
=
leftSB
.
left
+
leftSB
.
getThumbScaleWidth
()
/
2
f
;
progressDstRect
.
right
=
leftSB
.
left
+
leftSB
.
getThumbScaleWidth
()
/
2
f
+
progressWidth
*
leftSB
.
currPercent
;
progressDstRect
.
bottom
=
getProgressBottom
();
}
if
(
Utils
.
verifyBitmap
(
progressBitmap
))
{
progressSrcRect
.
top
=
0
;
progressSrcRect
.
bottom
=
progressBitmap
.
getHeight
();
int
bitmapWidth
=
progressBitmap
.
getWidth
();
if
(
seekBarMode
==
SEEKBAR_MODE_RANGE
)
{
progressSrcRect
.
left
=
(
int
)
(
bitmapWidth
*
leftSB
.
currPercent
);
progressSrcRect
.
right
=
(
int
)
(
bitmapWidth
*
rightSB
.
currPercent
);
}
else
{
progressSrcRect
.
left
=
0
;
progressSrcRect
.
right
=
(
int
)
(
bitmapWidth
*
leftSB
.
currPercent
);
}
canvas
.
drawBitmap
(
progressBitmap
,
progressSrcRect
,
progressDstRect
,
null
);
}
else
{
paint
.
setColor
(
progressColor
);
canvas
.
drawRoundRect
(
progressDstRect
,
progressRadius
,
progressRadius
,
paint
);
}
//如果需要绘制start和end的实心圆
if
(
isNeedStartEnd
)
{
paint
.
setColor
(
progressDefaultColor
);
//画左边固定实心圆形
canvas
.
drawCircle
(
leftSB
.
left
+
leftSB
.
getThumbScaleWidth
()
/
2
f
,
leftSB
.
top
+
leftSB
.
getThumbScaleWidth
()
/
2
f
,
10
f
,
paint
);
//画右边固定实心圆
canvas
.
drawCircle
(
progressWidth
+
rightSB
.
getThumbScaleWidth
()
/
2
f
,
rightSB
.
top
+
rightSB
.
getThumbScaleWidth
()
/
2
f
,
10
f
,
paint
);
}
}
//draw steps
protected
void
onDrawSteps
(
Canvas
canvas
,
Paint
paint
)
{
if
(!
verifyStepsMode
())
return
;
int
stepMarks
=
getProgressWidth
()
/
(
steps
);
float
extHeight
=
(
stepsHeight
-
getProgressHeight
())
/
2
f
;
for
(
int
k
=
1
;
k
<=
steps
-
1
;
k
++)
{
float
x
=
getProgressLeft
()
+
k
*
stepMarks
-
stepsWidth
/
2
f
;
stepDivRect
.
set
(
x
,
getProgressTop
()
+
stepsHeight
,
x
+
stepsWidth
,
getProgressBottom
()
+
3
*
stepsHeight
);
if
(
stepsBitmaps
.
isEmpty
()
||
stepsBitmaps
.
size
()
<=
k
)
{
paint
.
setColor
(
stepsColor
);
canvas
.
drawRoundRect
(
stepDivRect
,
stepsRadius
,
stepsRadius
,
paint
);
}
else
{
canvas
.
drawBitmap
(
stepsBitmaps
.
get
(
k
),
null
,
stepDivRect
,
paint
);
}
}
}
//绘制SeekBar相关
protected
void
onDrawSeekBar
(
Canvas
canvas
)
{
//draw left SeekBar
if
(
leftSB
.
getIndicatorShowMode
()
==
INDICATOR_ALWAYS_SHOW
)
{
leftSB
.
setShowIndicatorEnable
(
true
);
}
leftSB
.
draw
(
canvas
);
//draw right SeekBar
if
(
seekBarMode
==
SEEKBAR_MODE_RANGE
)
{
if
(
rightSB
.
getIndicatorShowMode
()
==
INDICATOR_ALWAYS_SHOW
)
{
rightSB
.
setShowIndicatorEnable
(
true
);
}
rightSB
.
draw
(
canvas
);
}
}
//初始化画笔
private
void
initPaint
()
{
paint
.
setStyle
(
Paint
.
Style
.
FILL
);
paint
.
setColor
(
progressDefaultColor
);
paint
.
setTextSize
(
tickMarkTextSize
);
}
private
void
changeThumbActivateState
(
boolean
hasActivate
)
{
if
(
hasActivate
&&
currTouchSB
!=
null
)
{
boolean
state
=
currTouchSB
==
leftSB
;
leftSB
.
setActivate
(
state
);
if
(
seekBarMode
==
SEEKBAR_MODE_RANGE
)
rightSB
.
setActivate
(!
state
);
}
else
{
leftSB
.
setActivate
(
false
);
if
(
seekBarMode
==
SEEKBAR_MODE_RANGE
)
rightSB
.
setActivate
(
false
);
}
}
protected
float
getEventX
(
MotionEvent
event
)
{
return
event
.
getX
();
}
protected
float
getEventY
(
MotionEvent
event
)
{
return
event
.
getY
();
}
/**
* scale the touch seekBar thumb
*/
private
void
scaleCurrentSeekBarThumb
()
{
if
(
currTouchSB
!=
null
&&
currTouchSB
.
getThumbScaleRatio
()
>
1
f
&&
!
isScaleThumb
)
{
isScaleThumb
=
true
;
currTouchSB
.
scaleThumb
();
}
}
/**
* reset the touch seekBar thumb
*/
private
void
resetCurrentSeekBarThumb
()
{
if
(
currTouchSB
!=
null
&&
currTouchSB
.
getThumbScaleRatio
()
>
1
f
&&
isScaleThumb
)
{
isScaleThumb
=
false
;
currTouchSB
.
resetThumb
();
}
}
//calculate currTouchSB percent by MotionEvent
protected
float
calculateCurrentSeekBarPercent
(
float
touchDownX
)
{
if
(
currTouchSB
==
null
)
return
0
;
float
percent
=
(
touchDownX
-
getProgressLeft
())
*
1
f
/
(
progressWidth
);
if
(
touchDownX
<
getProgressLeft
())
{
percent
=
0
;
}
else
if
(
touchDownX
>
getProgressRight
())
{
percent
=
1
;
}
//RangeMode minimum interval
if
(
seekBarMode
==
SEEKBAR_MODE_RANGE
)
{
if
(
currTouchSB
==
leftSB
)
{
if
(
percent
>
rightSB
.
currPercent
-
reservePercent
)
{
percent
=
rightSB
.
currPercent
-
reservePercent
;
}
}
else
if
(
currTouchSB
==
rightSB
)
{
if
(
percent
<
leftSB
.
currPercent
+
reservePercent
)
{
percent
=
leftSB
.
currPercent
+
reservePercent
;
}
}
}
return
percent
;
}
@Override
public
boolean
onTouchEvent
(
MotionEvent
event
)
{
if
(!
isEnable
)
return
true
;
switch
(
event
.
getAction
())
{
case
MotionEvent
.
ACTION_DOWN
:
touchDownX
=
getEventX
(
event
);
touchDownY
=
getEventY
(
event
);
if
(
seekBarMode
==
SEEKBAR_MODE_RANGE
)
{
if
(
rightSB
.
currPercent
>=
1
&&
leftSB
.
collide
(
getEventX
(
event
),
getEventY
(
event
)))
{
currTouchSB
=
leftSB
;
scaleCurrentSeekBarThumb
();
}
else
if
(
rightSB
.
collide
(
getEventX
(
event
),
getEventY
(
event
)))
{
currTouchSB
=
rightSB
;
scaleCurrentSeekBarThumb
();
}
else
{
float
performClick
=
(
touchDownX
-
getProgressLeft
())
*
1
f
/
(
progressWidth
);
float
distanceLeft
=
Math
.
abs
(
leftSB
.
currPercent
-
performClick
);
float
distanceRight
=
Math
.
abs
(
rightSB
.
currPercent
-
performClick
);
if
(
distanceLeft
<
distanceRight
)
{
currTouchSB
=
leftSB
;
}
else
{
currTouchSB
=
rightSB
;
}
performClick
=
calculateCurrentSeekBarPercent
(
touchDownX
);
currTouchSB
.
slide
(
performClick
);
}
}
else
{
currTouchSB
=
leftSB
;
scaleCurrentSeekBarThumb
();
}
//Intercept parent TouchEvent
if
(
getParent
()
!=
null
)
{
getParent
().
requestDisallowInterceptTouchEvent
(
true
);
}
if
(
callback
!=
null
)
{
callback
.
onStartTrackingTouch
(
this
,
currTouchSB
==
leftSB
);
}
changeThumbActivateState
(
true
);
return
true
;
case
MotionEvent
.
ACTION_MOVE
:
float
x
=
getEventX
(
event
);
if
((
seekBarMode
==
SEEKBAR_MODE_RANGE
)
&&
leftSB
.
currPercent
==
rightSB
.
currPercent
)
{
currTouchSB
.
materialRestore
();
if
(
callback
!=
null
)
{
callback
.
onStopTrackingTouch
(
this
,
currTouchSB
==
leftSB
);
}
if
(
x
-
touchDownX
>
0
)
{
//method to move right
if
(
currTouchSB
!=
rightSB
)
{
currTouchSB
.
setShowIndicatorEnable
(
false
);
resetCurrentSeekBarThumb
();
currTouchSB
=
rightSB
;
}
}
else
{
//method to move left
if
(
currTouchSB
!=
leftSB
)
{
currTouchSB
.
setShowIndicatorEnable
(
false
);
resetCurrentSeekBarThumb
();
currTouchSB
=
leftSB
;
}
}
if
(
callback
!=
null
)
{
callback
.
onStartTrackingTouch
(
this
,
currTouchSB
==
leftSB
);
}
}
scaleCurrentSeekBarThumb
();
currTouchSB
.
material
=
currTouchSB
.
material
>=
1
?
1
:
currTouchSB
.
material
+
0.1f
;
touchDownX
=
x
;
currTouchSB
.
slide
(
calculateCurrentSeekBarPercent
(
touchDownX
));
currTouchSB
.
setShowIndicatorEnable
(
true
);
if
(
callback
!=
null
)
{
SeekBarState
[]
states
=
getRangeSeekBarState
();
callback
.
onRangeChanged
(
this
,
states
[
0
].
value
,
states
[
1
].
value
,
true
);
}
invalidate
();
//Intercept parent TouchEvent
if
(
getParent
()
!=
null
)
{
getParent
().
requestDisallowInterceptTouchEvent
(
true
);
}
changeThumbActivateState
(
true
);
break
;
case
MotionEvent
.
ACTION_CANCEL
:
if
(
seekBarMode
==
SEEKBAR_MODE_RANGE
)
{
rightSB
.
setShowIndicatorEnable
(
false
);
}
if
(
currTouchSB
==
leftSB
)
{
resetCurrentSeekBarThumb
();
}
else
if
(
currTouchSB
==
rightSB
)
{
resetCurrentSeekBarThumb
();
}
leftSB
.
setShowIndicatorEnable
(
false
);
if
(
callback
!=
null
)
{
SeekBarState
[]
states
=
getRangeSeekBarState
();
callback
.
onRangeChanged
(
this
,
states
[
0
].
value
,
states
[
1
].
value
,
false
);
}
//Intercept parent TouchEvent
if
(
getParent
()
!=
null
)
{
getParent
().
requestDisallowInterceptTouchEvent
(
true
);
}
changeThumbActivateState
(
false
);
break
;
case
MotionEvent
.
ACTION_UP
:
if
(
verifyStepsMode
()
&&
stepsAutoBonding
)
{
float
percent
=
calculateCurrentSeekBarPercent
(
getEventX
(
event
));
float
stepPercent
=
1.0f
/
steps
;
int
stepSelected
=
new
BigDecimal
(
percent
/
stepPercent
).
setScale
(
0
,
RoundingMode
.
HALF_UP
).
intValue
();
currTouchSB
.
slide
(
stepSelected
*
stepPercent
);
}
if
(
seekBarMode
==
SEEKBAR_MODE_RANGE
)
{
rightSB
.
setShowIndicatorEnable
(
false
);
}
leftSB
.
setShowIndicatorEnable
(
false
);
currTouchSB
.
materialRestore
();
resetCurrentSeekBarThumb
();
if
(
callback
!=
null
)
{
SeekBarState
[]
states
=
getRangeSeekBarState
();
callback
.
onRangeChanged
(
this
,
states
[
0
].
value
,
states
[
1
].
value
,
false
);
}
//Intercept parent TouchEvent
if
(
getParent
()
!=
null
)
{
getParent
().
requestDisallowInterceptTouchEvent
(
true
);
}
if
(
callback
!=
null
)
{
callback
.
onStopTrackingTouch
(
this
,
currTouchSB
==
leftSB
);
}
changeThumbActivateState
(
false
);
break
;
}
return
super
.
onTouchEvent
(
event
);
}
@Override
public
Parcelable
onSaveInstanceState
()
{
Parcelable
superState
=
super
.
onSaveInstanceState
();
SavedState
ss
=
new
SavedState
(
superState
);
ss
.
minValue
=
minProgress
;
ss
.
maxValue
=
maxProgress
;
ss
.
rangeInterval
=
minInterval
;
SeekBarState
[]
results
=
getRangeSeekBarState
();
ss
.
currSelectedMin
=
results
[
0
].
value
;
ss
.
currSelectedMax
=
results
[
1
].
value
;
return
ss
;
}
@Override
public
void
onRestoreInstanceState
(
Parcelable
state
)
{
try
{
SavedState
ss
=
(
SavedState
)
state
;
super
.
onRestoreInstanceState
(
ss
.
getSuperState
());
float
min
=
ss
.
minValue
;
float
max
=
ss
.
maxValue
;
float
rangeInterval
=
ss
.
rangeInterval
;
setRange
(
min
,
max
,
rangeInterval
);
float
currSelectedMin
=
ss
.
currSelectedMin
;
float
currSelectedMax
=
ss
.
currSelectedMax
;
setProgress
(
currSelectedMin
,
currSelectedMax
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
}
public
void
setOnRangeChangedListener
(
OnRangeChangedListener
listener
)
{
callback
=
listener
;
}
public
void
setProgress
(
float
value
)
{
setProgress
(
value
,
maxProgress
);
}
public
void
setProgress
(
float
leftValue
,
float
rightValue
)
{
leftValue
=
Math
.
min
(
leftValue
,
rightValue
);
rightValue
=
Math
.
max
(
leftValue
,
rightValue
);
if
(
rightValue
-
leftValue
<
minInterval
)
{
if
(
leftValue
-
minProgress
>
maxProgress
-
rightValue
)
{
leftValue
=
rightValue
-
minInterval
;
}
else
{
rightValue
=
leftValue
+
minInterval
;
}
}
if
(
leftValue
<
minProgress
)
{
throw
new
IllegalArgumentException
(
"setProgress() min < (preset min - offsetValue) . #min:"
+
leftValue
+
" #preset min:"
+
rightValue
);
}
if
(
rightValue
>
maxProgress
)
{
throw
new
IllegalArgumentException
(
"setProgress() max > (preset max - offsetValue) . #max:"
+
rightValue
+
" #preset max:"
+
rightValue
);
}
float
range
=
maxProgress
-
minProgress
;
leftSB
.
currPercent
=
Math
.
abs
(
leftValue
-
minProgress
)
/
range
;
if
(
seekBarMode
==
SEEKBAR_MODE_RANGE
)
{
rightSB
.
currPercent
=
Math
.
abs
(
rightValue
-
minProgress
)
/
range
;
}
if
(
callback
!=
null
)
{
callback
.
onRangeChanged
(
this
,
leftValue
,
rightValue
,
false
);
}
invalidate
();
}
/**
* 设置范围
*
* @param min 最小值
* @param max 最大值
*/
public
void
setRange
(
float
min
,
float
max
)
{
setRange
(
min
,
max
,
minInterval
);
}
/**
* 设置范围
*
* @param min 最小值
* @param max 最大值
* @param minInterval 最小间隔
*/
public
void
setRange
(
float
min
,
float
max
,
float
minInterval
)
{
if
(
max
<=
min
)
{
throw
new
IllegalArgumentException
(
"setRange() max must be greater than min ! #max:"
+
max
+
" #min:"
+
min
);
}
if
(
minInterval
<
0
)
{
throw
new
IllegalArgumentException
(
"setRange() interval must be greater than zero ! #minInterval:"
+
minInterval
);
}
if
(
minInterval
>=
max
-
min
)
{
throw
new
IllegalArgumentException
(
"setRange() interval must be less than (max - min) ! #minInterval:"
+
minInterval
+
" #max - min:"
+
(
max
-
min
));
}
maxProgress
=
max
;
minProgress
=
min
;
this
.
minInterval
=
minInterval
;
reservePercent
=
minInterval
/
(
max
-
min
);
//set default value
if
(
seekBarMode
==
SEEKBAR_MODE_RANGE
)
{
if
(
leftSB
.
currPercent
+
reservePercent
<=
1
&&
leftSB
.
currPercent
+
reservePercent
>
rightSB
.
currPercent
)
{
rightSB
.
currPercent
=
leftSB
.
currPercent
+
reservePercent
;
}
else
if
(
rightSB
.
currPercent
-
reservePercent
>=
0
&&
rightSB
.
currPercent
-
reservePercent
<
leftSB
.
currPercent
)
{
leftSB
.
currPercent
=
rightSB
.
currPercent
-
reservePercent
;
}
}
invalidate
();
}
/**
* @return the two seekBar state , see {@link }
*/
public
SeekBarState
[]
getRangeSeekBarState
()
{
SeekBarState
leftSeekBarState
=
new
SeekBarState
();
leftSeekBarState
.
value
=
leftSB
.
getProgress
();
leftSeekBarState
.
indicatorText
=
String
.
valueOf
(
leftSeekBarState
.
value
);
if
(
Utils
.
compareFloat
(
leftSeekBarState
.
value
,
minProgress
)
==
0
)
{
leftSeekBarState
.
isMin
=
true
;
}
else
if
(
Utils
.
compareFloat
(
leftSeekBarState
.
value
,
maxProgress
)
==
0
)
{
leftSeekBarState
.
isMax
=
true
;
}
SeekBarState
rightSeekBarState
=
new
SeekBarState
();
if
(
seekBarMode
==
SEEKBAR_MODE_RANGE
)
{
rightSeekBarState
.
value
=
rightSB
.
getProgress
();
rightSeekBarState
.
indicatorText
=
String
.
valueOf
(
rightSeekBarState
.
value
);
if
(
Utils
.
compareFloat
(
rightSB
.
currPercent
,
minProgress
)
==
0
)
{
rightSeekBarState
.
isMin
=
true
;
}
else
if
(
Utils
.
compareFloat
(
rightSB
.
currPercent
,
maxProgress
)
==
0
)
{
rightSeekBarState
.
isMax
=
true
;
}
}
return
new
SeekBarState
[]{
leftSeekBarState
,
rightSeekBarState
};
}
//******************* Attributes getter and setter *******************//
@Override
public
void
setEnabled
(
boolean
enabled
)
{
super
.
setEnabled
(
enabled
);
this
.
isEnable
=
enabled
;
}
public
void
setIndicatorText
(
String
progress
)
{
leftSB
.
setIndicatorText
(
progress
);
if
(
seekBarMode
==
SEEKBAR_MODE_RANGE
)
{
rightSB
.
setIndicatorText
(
progress
);
}
}
/**
* format number indicator text
*
* @param formatPattern format rules
*/
public
void
setIndicatorTextDecimalFormat
(
String
formatPattern
)
{
leftSB
.
setIndicatorTextDecimalFormat
(
formatPattern
);
if
(
seekBarMode
==
SEEKBAR_MODE_RANGE
)
{
rightSB
.
setIndicatorTextDecimalFormat
(
formatPattern
);
}
}
/**
* format string indicator text
*
* @param formatPattern format rules
*/
public
void
setIndicatorTextStringFormat
(
String
formatPattern
)
{
leftSB
.
setIndicatorTextStringFormat
(
formatPattern
);
if
(
seekBarMode
==
SEEKBAR_MODE_RANGE
)
{
rightSB
.
setIndicatorTextStringFormat
(
formatPattern
);
}
}
/**
* if is single mode, please use it to get the SeekBar
*
* @return left seek bar
*/
public
SeekBar
getLeftSeekBar
()
{
return
leftSB
;
}
public
SeekBar
getRightSeekBar
()
{
return
rightSB
;
}
public
int
getProgressTop
()
{
return
progressTop
;
}
public
void
setProgressTop
(
int
progressTop
)
{
this
.
progressTop
=
progressTop
;
}
public
int
getProgressBottom
()
{
return
progressBottom
;
}
public
void
setProgressBottom
(
int
progressBottom
)
{
this
.
progressBottom
=
progressBottom
;
}
public
int
getProgressLeft
()
{
return
progressLeft
;
}
public
void
setProgressLeft
(
int
progressLeft
)
{
this
.
progressLeft
=
progressLeft
;
}
public
int
getProgressRight
()
{
return
progressRight
;
}
public
void
setProgressRight
(
int
progressRight
)
{
this
.
progressRight
=
progressRight
;
}
public
int
getProgressPaddingRight
()
{
return
progressPaddingRight
;
}
public
int
getProgressHeight
()
{
return
progressHeight
;
}
public
void
setProgressHeight
(
int
progressHeight
)
{
this
.
progressHeight
=
progressHeight
;
}
public
float
getMinProgress
()
{
return
minProgress
;
}
public
float
getMaxProgress
()
{
return
maxProgress
;
}
public
void
setProgressColor
(
@ColorInt
int
progressDefaultColor
,
@ColorInt
int
progressColor
)
{
this
.
progressDefaultColor
=
progressDefaultColor
;
this
.
progressColor
=
progressColor
;
}
public
int
getTickMarkTextColor
()
{
return
tickMarkTextColor
;
}
public
void
setTickMarkTextColor
(
@ColorInt
int
tickMarkTextColor
)
{
this
.
tickMarkTextColor
=
tickMarkTextColor
;
}
public
int
getTickMarkInRangeTextColor
()
{
return
tickMarkInRangeTextColor
;
}
public
void
setTickMarkInRangeTextColor
(
@ColorInt
int
tickMarkInRangeTextColor
)
{
this
.
tickMarkInRangeTextColor
=
tickMarkInRangeTextColor
;
}
public
int
getSeekBarMode
()
{
return
seekBarMode
;
}
/**
* {@link #SEEKBAR_MODE_SINGLE} is single SeekBar
* {@link #SEEKBAR_MODE_RANGE} is range SeekBar
*
* @param seekBarMode
*/
public
void
setSeekBarMode
(
@SeekBarModeDef
int
seekBarMode
)
{
this
.
seekBarMode
=
seekBarMode
;
rightSB
.
setVisible
(
seekBarMode
!=
SEEKBAR_MODE_SINGLE
);
}
public
int
getTickMarkMode
()
{
return
tickMarkMode
;
}
/**
* {@link #TICK_MARK_GRAVITY_LEFT} is number tick mark, it will locate the position according to the value.
* {@link #TICK_MARK_GRAVITY_RIGHT} is text tick mark, it will be equally positioned.
*
* @param tickMarkMode
*/
public
void
setTickMarkMode
(
@TickMarkModeDef
int
tickMarkMode
)
{
this
.
tickMarkMode
=
tickMarkMode
;
}
public
int
getTickMarkTextMargin
()
{
return
tickMarkTextMargin
;
}
public
void
setTickMarkTextMargin
(
int
tickMarkTextMargin
)
{
this
.
tickMarkTextMargin
=
tickMarkTextMargin
;
}
public
int
getTickMarkTextSize
()
{
return
tickMarkTextSize
;
}
public
void
setTickMarkTextSize
(
int
tickMarkTextSize
)
{
this
.
tickMarkTextSize
=
tickMarkTextSize
;
}
public
int
getTickMarkGravity
()
{
return
tickMarkGravity
;
}
/**
* the tick mark text gravity
* {@link #TICK_MARK_GRAVITY_LEFT}
* {@link #TICK_MARK_GRAVITY_RIGHT}
* {@link #TICK_MARK_GRAVITY_CENTER}
*
* @param tickMarkGravity
*/
public
void
setTickMarkGravity
(
@TickMarkGravityDef
int
tickMarkGravity
)
{
this
.
tickMarkGravity
=
tickMarkGravity
;
}
public
CharSequence
[]
getTickMarkTextArray
()
{
return
tickMarkTextArray
;
}
public
void
setTickMarkTextArray
(
CharSequence
[]
tickMarkTextArray
)
{
this
.
tickMarkTextArray
=
tickMarkTextArray
;
}
public
float
getMinInterval
()
{
return
minInterval
;
}
public
float
getProgressRadius
()
{
return
progressRadius
;
}
public
void
setProgressRadius
(
float
progressRadius
)
{
this
.
progressRadius
=
progressRadius
;
}
public
int
getProgressColor
()
{
return
progressColor
;
}
public
void
setProgressColor
(
@ColorInt
int
progressColor
)
{
this
.
progressColor
=
progressColor
;
}
public
int
getProgressDefaultColor
()
{
return
progressDefaultColor
;
}
public
void
setProgressDefaultColor
(
@ColorInt
int
progressDefaultColor
)
{
this
.
progressDefaultColor
=
progressDefaultColor
;
}
public
int
getProgressDrawableId
()
{
return
progressDrawableId
;
}
public
void
setProgressDrawableId
(
@DrawableRes
int
progressDrawableId
)
{
this
.
progressDrawableId
=
progressDrawableId
;
progressBitmap
=
null
;
initProgressBitmap
();
}
public
int
getProgressDefaultDrawableId
()
{
return
progressDefaultDrawableId
;
}
public
void
setProgressDefaultDrawableId
(
@DrawableRes
int
progressDefaultDrawableId
)
{
this
.
progressDefaultDrawableId
=
progressDefaultDrawableId
;
progressDefaultBitmap
=
null
;
initProgressBitmap
();
}
public
int
getProgressWidth
()
{
return
progressWidth
;
}
public
void
setProgressWidth
(
int
progressWidth
)
{
this
.
progressWidth
=
progressWidth
;
}
public
void
setTypeface
(
Typeface
typeFace
)
{
paint
.
setTypeface
(
typeFace
);
}
public
boolean
isEnableThumbOverlap
()
{
return
enableThumbOverlap
;
}
public
void
setEnableThumbOverlap
(
boolean
enableThumbOverlap
)
{
this
.
enableThumbOverlap
=
enableThumbOverlap
;
}
public
int
getSteps
()
{
return
steps
;
}
public
void
setSteps
(
int
steps
)
{
this
.
steps
=
steps
;
}
public
int
getStepsColor
()
{
return
stepsColor
;
}
public
void
setStepsColor
(
@ColorInt
int
stepsColor
)
{
this
.
stepsColor
=
stepsColor
;
}
public
float
getStepsWidth
()
{
return
stepsWidth
;
}
public
void
setStepsWidth
(
float
stepsWidth
)
{
this
.
stepsWidth
=
stepsWidth
;
}
public
float
getStepsHeight
()
{
return
stepsHeight
;
}
public
void
setStepsHeight
(
float
stepsHeight
)
{
this
.
stepsHeight
=
stepsHeight
;
}
public
float
getStepsRadius
()
{
return
stepsRadius
;
}
public
void
setStepsRadius
(
float
stepsRadius
)
{
this
.
stepsRadius
=
stepsRadius
;
}
public
int
getTickMarkLayoutGravity
()
{
return
tickMarkLayoutGravity
;
}
/**
* the tick mark layout gravity
* Gravity.TOP and Gravity.BOTTOM
*
* @param tickMarkLayoutGravity
*/
public
void
setTickMarkLayoutGravity
(
@TickMarkLayoutGravityDef
int
tickMarkLayoutGravity
)
{
this
.
tickMarkLayoutGravity
=
tickMarkLayoutGravity
;
}
public
int
getGravity
()
{
return
gravity
;
}
/**
* the RangeSeekBar gravity
* Gravity.TOP and Gravity.BOTTOM
*
* @param gravity
*/
public
void
setGravity
(
@GravityDef
int
gravity
)
{
this
.
gravity
=
gravity
;
}
public
boolean
isStepsAutoBonding
()
{
return
stepsAutoBonding
;
}
public
void
setStepsAutoBonding
(
boolean
stepsAutoBonding
)
{
this
.
stepsAutoBonding
=
stepsAutoBonding
;
}
public
int
getStepsDrawableId
()
{
return
stepsDrawableId
;
}
public
void
setStepsDrawableId
(
@DrawableRes
int
stepsDrawableId
)
{
this
.
stepsBitmaps
.
clear
();
this
.
stepsDrawableId
=
stepsDrawableId
;
initStepsBitmap
();
}
public
List
<
Bitmap
>
getStepsBitmaps
()
{
return
stepsBitmaps
;
}
public
void
setStepsBitmaps
(
List
<
Bitmap
>
stepsBitmaps
)
{
if
(
stepsBitmaps
==
null
||
stepsBitmaps
.
isEmpty
()
||
stepsBitmaps
.
size
()
<=
steps
)
{
throw
new
IllegalArgumentException
(
"stepsBitmaps must > steps !"
);
}
this
.
stepsBitmaps
.
clear
();
this
.
stepsBitmaps
.
addAll
(
stepsBitmaps
);
}
public
void
setStepsDrawable
(
List
<
Integer
>
stepsDrawableIds
)
{
if
(
stepsDrawableIds
==
null
||
stepsDrawableIds
.
isEmpty
()
||
stepsDrawableIds
.
size
()
<=
steps
)
{
throw
new
IllegalArgumentException
(
"stepsDrawableIds must > steps !"
);
}
if
(!
verifyStepsMode
())
{
throw
new
IllegalArgumentException
(
"stepsWidth must > 0, stepsHeight must > 0,steps must > 0 First!!"
);
}
List
<
Bitmap
>
stepsBitmaps
=
new
ArrayList
<>();
for
(
int
i
=
0
;
i
<
stepsDrawableIds
.
size
();
i
++)
{
stepsBitmaps
.
add
(
Utils
.
drawableToBitmap
(
getContext
(),
(
int
)
stepsWidth
,
(
int
)
stepsHeight
,
stepsDrawableIds
.
get
(
i
)));
}
setStepsBitmaps
(
stepsBitmaps
);
}
/**
* @hide
*/
@IntDef
({
SEEKBAR_MODE_SINGLE
,
SEEKBAR_MODE_RANGE
})
@Retention
(
RetentionPolicy
.
SOURCE
)
public
@interface
SeekBarModeDef
{
}
/**
* @hide
*/
@IntDef
({
TRICK_MARK_MODE_NUMBER
,
TRICK_MARK_MODE_OTHER
})
@Retention
(
RetentionPolicy
.
SOURCE
)
public
@interface
TickMarkModeDef
{
}
/**
* @hide
*/
@IntDef
({
TICK_MARK_GRAVITY_LEFT
,
TICK_MARK_GRAVITY_CENTER
,
TICK_MARK_GRAVITY_RIGHT
})
@Retention
(
RetentionPolicy
.
SOURCE
)
public
@interface
TickMarkGravityDef
{
}
/**
* @hide
*/
@IntDef
({
Gravity
.
TOP
,
Gravity
.
BOTTOM
})
@Retention
(
RetentionPolicy
.
SOURCE
)
public
@interface
TickMarkLayoutGravityDef
{
}
/**
* @hide
*/
@IntDef
({
Gravity
.
TOP
,
Gravity
.
CENTER
,
Gravity
.
BOTTOM
})
@Retention
(
RetentionPolicy
.
SOURCE
)
public
@interface
GravityDef
{
}
public
static
class
Gravity
{
public
final
static
int
TOP
=
0
;
public
final
static
int
BOTTOM
=
1
;
public
final
static
int
CENTER
=
2
;
}
}
m-consultant/src/main/java/com/yidianling/consultant/ui/view/rangeseekbar/SavedState.java
0 → 100644
View file @
59834452
package
com
.
yidianling
.
consultant
.
ui
.
view
.
rangeseekbar
;
import
android.os.Parcel
;
import
android.os.Parcelable
;
import
android.view.View
;
/**
* ================================================
* 作 者:JayGoo
* 版 本:
* 创建日期:2018/5/8
* 描 述:
* ================================================
*/
public
class
SavedState
extends
View
.
BaseSavedState
{
public
static
final
Creator
<
SavedState
>
CREATOR
=
new
Creator
<
SavedState
>()
{
public
SavedState
createFromParcel
(
Parcel
in
)
{
return
new
SavedState
(
in
);
}
public
SavedState
[]
newArray
(
int
size
)
{
return
new
SavedState
[
size
];
}
};
public
float
minValue
;
public
float
maxValue
;
public
float
rangeInterval
;
public
int
tickNumber
;
public
float
currSelectedMin
;
public
float
currSelectedMax
;
public
SavedState
(
Parcelable
superState
)
{
super
(
superState
);
}
private
SavedState
(
Parcel
in
)
{
super
(
in
);
minValue
=
in
.
readFloat
();
maxValue
=
in
.
readFloat
();
rangeInterval
=
in
.
readFloat
();
tickNumber
=
in
.
readInt
();
currSelectedMin
=
in
.
readFloat
();
currSelectedMax
=
in
.
readFloat
();
}
@Override
public
void
writeToParcel
(
Parcel
out
,
int
flags
)
{
super
.
writeToParcel
(
out
,
flags
);
out
.
writeFloat
(
minValue
);
out
.
writeFloat
(
maxValue
);
out
.
writeFloat
(
rangeInterval
);
out
.
writeInt
(
tickNumber
);
out
.
writeFloat
(
currSelectedMin
);
out
.
writeFloat
(
currSelectedMax
);
}
}
m-consultant/src/main/java/com/yidianling/consultant/ui/view/rangeseekbar/SeekBar.java
0 → 100644
View file @
59834452
package
com
.
yidianling
.
consultant
.
ui
.
view
.
rangeseekbar
;
import
android.animation.Animator
;
import
android.animation.AnimatorListenerAdapter
;
import
android.animation.ValueAnimator
;
import
android.content.Context
;
import
android.content.res.Resources
;
import
android.content.res.TypedArray
;
import
android.graphics.Bitmap
;
import
android.graphics.BitmapFactory
;
import
android.graphics.Canvas
;
import
android.graphics.Color
;
import
android.graphics.Paint
;
import
android.graphics.Path
;
import
android.graphics.Rect
;
import
android.graphics.RectF
;
import
android.graphics.Typeface
;
import
android.os.Build
;
import
android.text.TextUtils
;
import
android.util.AttributeSet
;
import
androidx.annotation.ColorInt
;
import
androidx.annotation.DrawableRes
;
import
androidx.annotation.IntDef
;
import
androidx.core.content.ContextCompat
;
import
com.yidianling.consultant.R
;
import
java.text.DecimalFormat
;
/**
* ================================================
* 作 者:JayGoo
* 版 本:
* 创建日期:2018/5/8
* 描 述:
* ================================================
*/
public
class
SeekBar
{
//the indicator show mode
public
static
final
int
INDICATOR_SHOW_WHEN_TOUCH
=
0
;
public
static
final
int
INDICATOR_ALWAYS_HIDE
=
1
;
public
static
final
int
INDICATOR_ALWAYS_SHOW_AFTER_TOUCH
=
2
;
public
static
final
int
INDICATOR_ALWAYS_SHOW
=
3
;
public
static
final
int
WRAP_CONTENT
=
-
1
;
public
static
final
int
MATCH_PARENT
=
-
2
;
//when you touch or move, the thumb will scale, default not scale
float
thumbScaleRatio
;
int
left
,
right
,
top
,
bottom
;
float
currPercent
;
float
material
=
0
;
boolean
isLeft
;
Bitmap
thumbBitmap
;
Bitmap
thumbInactivatedBitmap
;
Bitmap
indicatorBitmap
;
ValueAnimator
anim
;
String
userText2Draw
;
boolean
isActivate
=
false
;
boolean
isVisible
=
true
;
RangeSeekBar
rangeSeekBar
;
String
indicatorTextStringFormat
;
Path
indicatorArrowPath
=
new
Path
();
Rect
indicatorTextRect
=
new
Rect
();
Rect
indicatorRect
=
new
Rect
();
//****************** the above is attr value ******************//
Paint
paint
=
new
Paint
(
Paint
.
ANTI_ALIAS_FLAG
);
DecimalFormat
indicatorTextDecimalFormat
;
int
scaleThumbWidth
;
int
scaleThumbHeight
;
private
int
indicatorShowMode
;
//进度提示背景的高度,宽度如果是0的话会自适应调整
//Progress prompted the background height, width,
private
int
indicatorHeight
;
private
int
indicatorWidth
;
//进度提示背景与按钮之间的距离
//The progress indicates the distance between the background and the button
private
int
indicatorMargin
;
private
int
indicatorDrawableId
;
private
int
indicatorArrowSize
;
private
int
indicatorTextSize
;
private
int
indicatorTextColor
;
private
float
indicatorRadius
;
private
int
indicatorBackgroundColor
;
private
int
indicatorPaddingLeft
,
indicatorPaddingRight
,
indicatorPaddingTop
,
indicatorPaddingBottom
;
private
int
thumbDrawableId
;
private
int
thumbInactivatedDrawableId
;
private
int
thumbWidth
;
private
int
thumbHeight
;
private
boolean
isShowIndicator
;
public
SeekBar
(
RangeSeekBar
rangeSeekBar
,
AttributeSet
attrs
,
boolean
isLeft
)
{
this
.
rangeSeekBar
=
rangeSeekBar
;
this
.
isLeft
=
isLeft
;
initAttrs
(
attrs
);
initBitmap
();
initVariables
();
}
private
void
initAttrs
(
AttributeSet
attrs
)
{
TypedArray
t
=
getContext
().
obtainStyledAttributes
(
attrs
,
R
.
styleable
.
RangeSeekBar
);
if
(
t
==
null
)
return
;
indicatorMargin
=
(
int
)
t
.
getDimension
(
R
.
styleable
.
RangeSeekBar_rsb_indicator_margin
,
0
);
indicatorDrawableId
=
t
.
getResourceId
(
R
.
styleable
.
RangeSeekBar_rsb_indicator_drawable
,
0
);
indicatorShowMode
=
t
.
getInt
(
R
.
styleable
.
RangeSeekBar_rsb_indicator_show_mode
,
INDICATOR_ALWAYS_HIDE
);
indicatorHeight
=
t
.
getLayoutDimension
(
R
.
styleable
.
RangeSeekBar_rsb_indicator_height
,
WRAP_CONTENT
);
indicatorWidth
=
t
.
getLayoutDimension
(
R
.
styleable
.
RangeSeekBar_rsb_indicator_width
,
WRAP_CONTENT
);
indicatorTextSize
=
(
int
)
t
.
getDimension
(
R
.
styleable
.
RangeSeekBar_rsb_indicator_text_size
,
Utils
.
dp2px
(
getContext
(),
14
));
indicatorTextColor
=
t
.
getColor
(
R
.
styleable
.
RangeSeekBar_rsb_indicator_text_color
,
Color
.
WHITE
);
indicatorBackgroundColor
=
t
.
getColor
(
R
.
styleable
.
RangeSeekBar_rsb_indicator_background_color
,
ContextCompat
.
getColor
(
getContext
(),
R
.
color
.
colorAccent
));
indicatorPaddingLeft
=
(
int
)
t
.
getDimension
(
R
.
styleable
.
RangeSeekBar_rsb_indicator_padding_left
,
0
);
indicatorPaddingRight
=
(
int
)
t
.
getDimension
(
R
.
styleable
.
RangeSeekBar_rsb_indicator_padding_right
,
0
);
indicatorPaddingTop
=
(
int
)
t
.
getDimension
(
R
.
styleable
.
RangeSeekBar_rsb_indicator_padding_top
,
0
);
indicatorPaddingBottom
=
(
int
)
t
.
getDimension
(
R
.
styleable
.
RangeSeekBar_rsb_indicator_padding_bottom
,
0
);
indicatorArrowSize
=
(
int
)
t
.
getDimension
(
R
.
styleable
.
RangeSeekBar_rsb_indicator_arrow_size
,
0
);
thumbDrawableId
=
t
.
getResourceId
(
R
.
styleable
.
RangeSeekBar_rsb_thumb_drawable
,
R
.
drawable
.
rsb_default_thumb
);
thumbInactivatedDrawableId
=
t
.
getResourceId
(
R
.
styleable
.
RangeSeekBar_rsb_thumb_inactivated_drawable
,
0
);
thumbWidth
=
(
int
)
t
.
getDimension
(
R
.
styleable
.
RangeSeekBar_rsb_thumb_width
,
Utils
.
dp2px
(
getContext
(),
26
));
thumbHeight
=
(
int
)
t
.
getDimension
(
R
.
styleable
.
RangeSeekBar_rsb_thumb_height
,
Utils
.
dp2px
(
getContext
(),
26
));
thumbScaleRatio
=
t
.
getFloat
(
R
.
styleable
.
RangeSeekBar_rsb_thumb_scale_ratio
,
1
f
);
indicatorRadius
=
t
.
getDimension
(
R
.
styleable
.
RangeSeekBar_rsb_indicator_radius
,
0
f
);
t
.
recycle
();
}
protected
void
initVariables
()
{
scaleThumbWidth
=
thumbWidth
;
scaleThumbHeight
=
thumbHeight
;
if
(
indicatorHeight
==
WRAP_CONTENT
)
{
indicatorHeight
=
Utils
.
measureText
(
"8"
,
indicatorTextSize
).
height
()
+
indicatorPaddingTop
+
indicatorPaddingBottom
;
}
if
(
indicatorArrowSize
<=
0
)
{
indicatorArrowSize
=
(
int
)
(
thumbWidth
/
4
);
}
}
public
Context
getContext
()
{
return
rangeSeekBar
.
getContext
();
}
public
Resources
getResources
()
{
if
(
getContext
()
!=
null
)
return
getContext
().
getResources
();
return
null
;
}
/**
* 初始化进度提示的背景
*/
private
void
initBitmap
()
{
setIndicatorDrawableId
(
indicatorDrawableId
);
setThumbDrawableId
(
thumbDrawableId
,
thumbWidth
,
thumbHeight
);
setThumbInactivatedDrawableId
(
thumbInactivatedDrawableId
,
thumbWidth
,
thumbHeight
);
}
/**
* 计算每个按钮的位置和尺寸
* Calculates the position and size of each button
*
* @param x position x
* @param y position y
*/
protected
void
onSizeChanged
(
int
x
,
int
y
)
{
initVariables
();
initBitmap
();
left
=
(
int
)
(
x
-
getThumbScaleWidth
()
/
2
);
right
=
(
int
)
(
x
+
getThumbScaleWidth
()
/
2
);
top
=
y
-
getThumbHeight
()
/
2
;
bottom
=
y
+
getThumbHeight
()
/
2
;
}
public
void
scaleThumb
()
{
scaleThumbWidth
=
(
int
)
getThumbScaleWidth
();
scaleThumbHeight
=
(
int
)
getThumbScaleHeight
();
int
y
=
rangeSeekBar
.
getProgressBottom
();
top
=
y
-
scaleThumbHeight
/
2
;
bottom
=
y
+
scaleThumbHeight
/
2
;
setThumbDrawableId
(
thumbDrawableId
,
scaleThumbWidth
,
scaleThumbHeight
);
}
public
void
resetThumb
()
{
scaleThumbWidth
=
getThumbWidth
();
scaleThumbHeight
=
getThumbHeight
();
int
y
=
rangeSeekBar
.
getProgressBottom
();
top
=
y
-
scaleThumbHeight
/
2
;
bottom
=
y
+
scaleThumbHeight
/
2
;
setThumbDrawableId
(
thumbDrawableId
,
scaleThumbWidth
,
scaleThumbHeight
);
}
public
float
getRawHeight
()
{
return
getIndicatorHeight
()
+
getIndicatorArrowSize
()
+
getIndicatorMargin
()
+
getThumbScaleHeight
();
}
/**
* 绘制按钮和提示背景和文字
* Draw buttons and tips for background and text
*
* @param canvas Canvas
*/
protected
void
draw
(
Canvas
canvas
)
{
if
(!
isVisible
)
{
return
;
}
int
offset
=
(
int
)
(
rangeSeekBar
.
getProgressWidth
()
*
currPercent
);
canvas
.
save
();
canvas
.
translate
(
offset
,
0
);
// translate canvas, then don't care left
canvas
.
translate
(
left
,
0
);
if
(
isShowIndicator
)
{
onDrawIndicator
(
canvas
,
paint
,
formatCurrentIndicatorText
(
userText2Draw
));
}
onDrawThumb
(
canvas
);
canvas
.
restore
();
}
/**
* 绘制按钮
* 如果没有图片资源,则绘制默认按钮
* <p>
* draw the thumb button
* If there is no image resource, draw the default button
*
* @param canvas canvas
*/
protected
void
onDrawThumb
(
Canvas
canvas
)
{
if
(
thumbInactivatedBitmap
!=
null
&&
!
isActivate
)
{
canvas
.
drawBitmap
(
thumbInactivatedBitmap
,
0
,
rangeSeekBar
.
getProgressTop
()
+
(
rangeSeekBar
.
getProgressHeight
()
-
scaleThumbHeight
)
/
2
f
,
null
);
}
else
if
(
thumbBitmap
!=
null
)
{
canvas
.
drawBitmap
(
thumbBitmap
,
0
,
rangeSeekBar
.
getProgressTop
()
+
(
rangeSeekBar
.
getProgressHeight
()
-
scaleThumbHeight
)
/
2
f
,
null
);
}
}
/**
* 格式化提示文字
* format the indicator text
*
* @param text2Draw
* @return
*/
protected
String
formatCurrentIndicatorText
(
String
text2Draw
)
{
SeekBarState
[]
states
=
rangeSeekBar
.
getRangeSeekBarState
();
if
(
TextUtils
.
isEmpty
(
text2Draw
))
{
if
(
isLeft
)
{
if
(
indicatorTextDecimalFormat
!=
null
)
{
text2Draw
=
indicatorTextDecimalFormat
.
format
(
states
[
0
].
value
);
}
else
{
text2Draw
=
states
[
0
].
indicatorText
;
}
}
else
{
if
(
indicatorTextDecimalFormat
!=
null
)
{
text2Draw
=
indicatorTextDecimalFormat
.
format
(
states
[
1
].
value
);
}
else
{
text2Draw
=
states
[
1
].
indicatorText
;
}
}
}
if
(
indicatorTextStringFormat
!=
null
)
{
text2Draw
=
String
.
format
(
indicatorTextStringFormat
,
text2Draw
);
}
return
text2Draw
;
}
/**
* This method will draw the indicator background dynamically according to the text.
* you can use to set padding
*
* @param canvas Canvas
* @param text2Draw Indicator text
*/
protected
void
onDrawIndicator
(
Canvas
canvas
,
Paint
paint
,
String
text2Draw
)
{
if
(
text2Draw
==
null
)
return
;
paint
.
setTextSize
(
indicatorTextSize
);
paint
.
setStyle
(
Paint
.
Style
.
FILL
);
paint
.
setColor
(
indicatorBackgroundColor
);
paint
.
getTextBounds
(
text2Draw
,
0
,
text2Draw
.
length
(),
indicatorTextRect
);
int
realIndicatorWidth
=
indicatorTextRect
.
width
()
+
indicatorPaddingLeft
+
indicatorPaddingRight
;
if
(
indicatorWidth
>
realIndicatorWidth
)
{
realIndicatorWidth
=
indicatorWidth
;
}
int
realIndicatorHeight
=
indicatorTextRect
.
height
()
+
indicatorPaddingTop
+
indicatorPaddingBottom
;
if
(
indicatorHeight
>
realIndicatorHeight
)
{
realIndicatorHeight
=
indicatorHeight
;
}
indicatorRect
.
left
=
(
int
)
(
scaleThumbWidth
/
2
f
-
realIndicatorWidth
/
2
f
);
indicatorRect
.
top
=
bottom
-
realIndicatorHeight
-
scaleThumbHeight
-
indicatorMargin
;
indicatorRect
.
right
=
indicatorRect
.
left
+
realIndicatorWidth
;
indicatorRect
.
bottom
=
indicatorRect
.
top
+
realIndicatorHeight
;
//draw default indicator arrow
if
(
indicatorBitmap
==
null
)
{
//arrow three point
// b c
// a
int
ax
=
scaleThumbWidth
/
2
;
int
ay
=
indicatorRect
.
bottom
;
int
bx
=
ax
-
indicatorArrowSize
;
int
by
=
ay
-
indicatorArrowSize
;
int
cx
=
ax
+
indicatorArrowSize
;
indicatorArrowPath
.
reset
();
indicatorArrowPath
.
moveTo
(
ax
,
ay
);
indicatorArrowPath
.
lineTo
(
bx
,
by
);
indicatorArrowPath
.
lineTo
(
cx
,
by
);
indicatorArrowPath
.
close
();
canvas
.
drawPath
(
indicatorArrowPath
,
paint
);
indicatorRect
.
bottom
-=
indicatorArrowSize
;
indicatorRect
.
top
-=
indicatorArrowSize
;
}
//indicator background edge processing
int
defaultPaddingOffset
=
Utils
.
dp2px
(
getContext
(),
1
);
int
leftOffset
=
indicatorRect
.
width
()
/
2
-
(
int
)
(
rangeSeekBar
.
getProgressWidth
()
*
currPercent
)
-
rangeSeekBar
.
getProgressLeft
()
+
defaultPaddingOffset
;
int
rightOffset
=
indicatorRect
.
width
()
/
2
-
(
int
)
(
rangeSeekBar
.
getProgressWidth
()
*
(
1
-
currPercent
))
-
rangeSeekBar
.
getProgressPaddingRight
()
+
defaultPaddingOffset
;
if
(
leftOffset
>
0
)
{
indicatorRect
.
left
+=
leftOffset
;
indicatorRect
.
right
+=
leftOffset
;
}
else
if
(
rightOffset
>
0
)
{
indicatorRect
.
left
-=
rightOffset
;
indicatorRect
.
right
-=
rightOffset
;
}
//draw indicator background
if
(
indicatorBitmap
!=
null
)
{
Utils
.
drawBitmap
(
canvas
,
paint
,
indicatorBitmap
,
indicatorRect
);
}
else
if
(
indicatorRadius
>
0
f
)
{
canvas
.
drawRoundRect
(
new
RectF
(
indicatorRect
),
indicatorRadius
,
indicatorRadius
,
paint
);
}
else
{
canvas
.
drawRect
(
indicatorRect
,
paint
);
}
//draw indicator content text
int
tx
,
ty
;
if
(
indicatorPaddingLeft
>
0
)
{
tx
=
indicatorRect
.
left
+
indicatorPaddingLeft
;
}
else
if
(
indicatorPaddingRight
>
0
)
{
tx
=
indicatorRect
.
right
-
indicatorPaddingRight
-
indicatorTextRect
.
width
();
}
else
{
tx
=
indicatorRect
.
left
+
(
realIndicatorWidth
-
indicatorTextRect
.
width
())
/
2
;
}
if
(
indicatorPaddingTop
>
0
)
{
ty
=
indicatorRect
.
top
+
indicatorTextRect
.
height
()
+
indicatorPaddingTop
;
}
else
if
(
indicatorPaddingBottom
>
0
)
{
ty
=
indicatorRect
.
bottom
-
indicatorTextRect
.
height
()
-
indicatorPaddingBottom
;
}
else
{
ty
=
indicatorRect
.
bottom
-
(
realIndicatorHeight
-
indicatorTextRect
.
height
())
/
2
+
1
;
}
//draw indicator text
paint
.
setColor
(
indicatorTextColor
);
canvas
.
drawText
(
text2Draw
,
tx
,
ty
,
paint
);
}
/**
* 拖动检测
*
* @return is collide
*/
protected
boolean
collide
(
float
x
,
float
y
)
{
int
offset
=
(
int
)
(
rangeSeekBar
.
getProgressWidth
()
*
currPercent
);
return
x
>
left
+
offset
&&
x
<
right
+
offset
&&
y
>
top
&&
y
<
bottom
;
}
protected
void
slide
(
float
percent
)
{
if
(
percent
<
0
)
percent
=
0
;
else
if
(
percent
>
1
)
percent
=
1
;
currPercent
=
percent
;
}
protected
void
setShowIndicatorEnable
(
boolean
isEnable
)
{
switch
(
indicatorShowMode
)
{
case
INDICATOR_SHOW_WHEN_TOUCH:
isShowIndicator
=
isEnable
;
break
;
case
INDICATOR_ALWAYS_SHOW:
case
INDICATOR_ALWAYS_SHOW_AFTER_TOUCH:
isShowIndicator
=
true
;
break
;
case
INDICATOR_ALWAYS_HIDE:
isShowIndicator
=
false
;
break
;
}
}
public
void
materialRestore
()
{
if
(
anim
!=
null
)
anim
.
cancel
();
anim
=
ValueAnimator
.
ofFloat
(
material
,
0
);
anim
.
addUpdateListener
(
new
ValueAnimator
.
AnimatorUpdateListener
()
{
@Override
public
void
onAnimationUpdate
(
ValueAnimator
animation
)
{
material
=
(
float
)
animation
.
getAnimatedValue
();
if
(
rangeSeekBar
!=
null
)
rangeSeekBar
.
invalidate
();
}
});
anim
.
addListener
(
new
AnimatorListenerAdapter
()
{
@Override
public
void
onAnimationEnd
(
Animator
animation
)
{
material
=
0
;
if
(
rangeSeekBar
!=
null
)
rangeSeekBar
.
invalidate
();
}
});
anim
.
start
();
}
public
void
setIndicatorText
(
String
text
)
{
userText2Draw
=
text
;
}
public
DecimalFormat
getIndicatorTextDecimalFormat
()
{
return
indicatorTextDecimalFormat
;
}
public
void
setIndicatorTextDecimalFormat
(
String
formatPattern
)
{
indicatorTextDecimalFormat
=
new
DecimalFormat
(
formatPattern
);
}
public
void
setIndicatorTextStringFormat
(
String
formatPattern
)
{
indicatorTextStringFormat
=
formatPattern
;
}
public
int
getIndicatorDrawableId
()
{
return
indicatorDrawableId
;
}
public
void
setIndicatorDrawableId
(
@DrawableRes
int
indicatorDrawableId
)
{
if
(
indicatorDrawableId
!=
0
)
{
this
.
indicatorDrawableId
=
indicatorDrawableId
;
indicatorBitmap
=
BitmapFactory
.
decodeResource
(
getResources
(),
indicatorDrawableId
);
}
}
public
int
getIndicatorArrowSize
()
{
return
indicatorArrowSize
;
}
public
void
setIndicatorArrowSize
(
int
indicatorArrowSize
)
{
this
.
indicatorArrowSize
=
indicatorArrowSize
;
}
public
int
getIndicatorPaddingLeft
()
{
return
indicatorPaddingLeft
;
}
public
void
setIndicatorPaddingLeft
(
int
indicatorPaddingLeft
)
{
this
.
indicatorPaddingLeft
=
indicatorPaddingLeft
;
}
public
int
getIndicatorPaddingRight
()
{
return
indicatorPaddingRight
;
}
public
void
setIndicatorPaddingRight
(
int
indicatorPaddingRight
)
{
this
.
indicatorPaddingRight
=
indicatorPaddingRight
;
}
public
int
getIndicatorPaddingTop
()
{
return
indicatorPaddingTop
;
}
public
void
setIndicatorPaddingTop
(
int
indicatorPaddingTop
)
{
this
.
indicatorPaddingTop
=
indicatorPaddingTop
;
}
public
int
getIndicatorPaddingBottom
()
{
return
indicatorPaddingBottom
;
}
public
void
setIndicatorPaddingBottom
(
int
indicatorPaddingBottom
)
{
this
.
indicatorPaddingBottom
=
indicatorPaddingBottom
;
}
public
int
getIndicatorMargin
()
{
return
indicatorMargin
;
}
public
void
setIndicatorMargin
(
int
indicatorMargin
)
{
this
.
indicatorMargin
=
indicatorMargin
;
}
public
int
getIndicatorShowMode
()
{
return
indicatorShowMode
;
}
/**
* the indicator show mode
* {@link #INDICATOR_SHOW_WHEN_TOUCH}
* {@link #INDICATOR_ALWAYS_SHOW}
* {@link #INDICATOR_ALWAYS_SHOW_AFTER_TOUCH}
* {@link #INDICATOR_ALWAYS_SHOW}
*
* @param indicatorShowMode
*/
public
void
setIndicatorShowMode
(
@IndicatorModeDef
int
indicatorShowMode
)
{
this
.
indicatorShowMode
=
indicatorShowMode
;
}
public
void
showIndicator
(
boolean
isShown
)
{
isShowIndicator
=
isShown
;
}
public
boolean
isShowIndicator
()
{
return
isShowIndicator
;
}
/**
* include indicator text Height、padding、margin
*
* @return The actual occupation height of indicator
*/
public
int
getIndicatorRawHeight
()
{
if
(
indicatorHeight
>
0
)
{
if
(
indicatorBitmap
!=
null
)
{
return
indicatorHeight
+
indicatorMargin
;
}
else
{
return
indicatorHeight
+
indicatorArrowSize
+
indicatorMargin
;
}
}
else
{
if
(
indicatorBitmap
!=
null
)
{
return
Utils
.
measureText
(
"8"
,
indicatorTextSize
).
height
()
+
indicatorPaddingTop
+
indicatorPaddingBottom
+
indicatorMargin
;
}
else
{
return
Utils
.
measureText
(
"8"
,
indicatorTextSize
).
height
()
+
indicatorPaddingTop
+
indicatorPaddingBottom
+
indicatorMargin
+
indicatorArrowSize
;
}
}
}
public
int
getIndicatorHeight
()
{
return
indicatorHeight
;
}
public
void
setIndicatorHeight
(
int
indicatorHeight
)
{
this
.
indicatorHeight
=
indicatorHeight
;
}
public
int
getIndicatorWidth
()
{
return
indicatorWidth
;
}
public
void
setIndicatorWidth
(
int
indicatorWidth
)
{
this
.
indicatorWidth
=
indicatorWidth
;
}
public
int
getIndicatorTextSize
()
{
return
indicatorTextSize
;
}
public
void
setIndicatorTextSize
(
int
indicatorTextSize
)
{
this
.
indicatorTextSize
=
indicatorTextSize
;
}
public
int
getIndicatorTextColor
()
{
return
indicatorTextColor
;
}
public
void
setIndicatorTextColor
(
@ColorInt
int
indicatorTextColor
)
{
this
.
indicatorTextColor
=
indicatorTextColor
;
}
public
int
getIndicatorBackgroundColor
()
{
return
indicatorBackgroundColor
;
}
public
void
setIndicatorBackgroundColor
(
@ColorInt
int
indicatorBackgroundColor
)
{
this
.
indicatorBackgroundColor
=
indicatorBackgroundColor
;
}
public
int
getThumbInactivatedDrawableId
()
{
return
thumbInactivatedDrawableId
;
}
public
void
setThumbInactivatedDrawableId
(
@DrawableRes
int
thumbInactivatedDrawableId
,
int
width
,
int
height
)
{
if
(
thumbInactivatedDrawableId
!=
0
&&
getResources
()
!=
null
)
{
this
.
thumbInactivatedDrawableId
=
thumbInactivatedDrawableId
;
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
LOLLIPOP
)
{
thumbInactivatedBitmap
=
Utils
.
drawableToBitmap
(
width
,
height
,
getResources
().
getDrawable
(
thumbInactivatedDrawableId
,
null
));
}
else
{
thumbInactivatedBitmap
=
Utils
.
drawableToBitmap
(
width
,
height
,
getResources
().
getDrawable
(
thumbInactivatedDrawableId
));
}
}
}
public
int
getThumbDrawableId
()
{
return
thumbDrawableId
;
}
public
void
setThumbDrawableId
(
@DrawableRes
int
thumbDrawableId
)
{
if
(
thumbWidth
<=
0
||
thumbHeight
<=
0
)
{
throw
new
IllegalArgumentException
(
"please set thumbWidth and thumbHeight first!"
);
}
if
(
thumbDrawableId
!=
0
&&
getResources
()
!=
null
)
{
this
.
thumbDrawableId
=
thumbDrawableId
;
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
LOLLIPOP
)
{
thumbBitmap
=
Utils
.
drawableToBitmap
(
thumbWidth
,
thumbHeight
,
getResources
().
getDrawable
(
thumbDrawableId
,
null
));
}
else
{
thumbBitmap
=
Utils
.
drawableToBitmap
(
thumbWidth
,
thumbHeight
,
getResources
().
getDrawable
(
thumbDrawableId
));
}
}
}
public
void
setThumbDrawableId
(
@DrawableRes
int
thumbDrawableId
,
int
width
,
int
height
)
{
if
(
thumbDrawableId
!=
0
&&
getResources
()
!=
null
&&
width
>
0
&&
height
>
0
)
{
this
.
thumbDrawableId
=
thumbDrawableId
;
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
LOLLIPOP
)
{
thumbBitmap
=
Utils
.
drawableToBitmap
(
width
,
height
,
getResources
().
getDrawable
(
thumbDrawableId
,
null
));
}
else
{
thumbBitmap
=
Utils
.
drawableToBitmap
(
width
,
height
,
getResources
().
getDrawable
(
thumbDrawableId
));
}
}
}
public
int
getThumbWidth
()
{
return
thumbWidth
;
}
public
void
setThumbWidth
(
int
thumbWidth
)
{
this
.
thumbWidth
=
thumbWidth
;
}
public
float
getThumbScaleHeight
()
{
return
thumbHeight
*
thumbScaleRatio
;
}
public
float
getThumbScaleWidth
()
{
return
thumbWidth
*
thumbScaleRatio
;
}
public
int
getThumbHeight
()
{
return
thumbHeight
;
}
public
void
setThumbHeight
(
int
thumbHeight
)
{
this
.
thumbHeight
=
thumbHeight
;
}
public
float
getIndicatorRadius
()
{
return
indicatorRadius
;
}
public
void
setIndicatorRadius
(
float
indicatorRadius
)
{
this
.
indicatorRadius
=
indicatorRadius
;
}
protected
boolean
getActivate
()
{
return
isActivate
;
}
protected
void
setActivate
(
boolean
activate
)
{
isActivate
=
activate
;
}
public
void
setTypeface
(
Typeface
typeFace
)
{
paint
.
setTypeface
(
typeFace
);
}
/**
* when you touch or move, the thumb will scale, default not scale
*
* @return default 1.0f
*/
public
float
getThumbScaleRatio
()
{
return
thumbScaleRatio
;
}
public
boolean
isVisible
()
{
return
isVisible
;
}
/**
* if visble is false, will clear the Canvas
*
* @param visible
*/
public
void
setVisible
(
boolean
visible
)
{
isVisible
=
visible
;
}
public
float
getProgress
()
{
float
range
=
rangeSeekBar
.
getMaxProgress
()
-
rangeSeekBar
.
getMinProgress
();
return
rangeSeekBar
.
getMinProgress
()
+
range
*
currPercent
;
}
@IntDef
({
INDICATOR_SHOW_WHEN_TOUCH
,
INDICATOR_ALWAYS_HIDE
,
INDICATOR_ALWAYS_SHOW_AFTER_TOUCH
,
INDICATOR_ALWAYS_SHOW
})
public
@interface
IndicatorModeDef
{
}
}
m-consultant/src/main/java/com/yidianling/consultant/ui/view/rangeseekbar/SeekBarState.java
0 → 100644
View file @
59834452
package
com
.
yidianling
.
consultant
.
ui
.
view
.
rangeseekbar
;
/**
* ================================================
* 作 者:JayGoo
* 版 本:
* 创建日期:2018/5/9
* 描 述: it works for draw indicator text
* ================================================
*/
public
class
SeekBarState
{
public
String
indicatorText
;
public
float
value
;
//now progress value
public
boolean
isMin
;
public
boolean
isMax
;
@Override
public
String
toString
()
{
return
"indicatorText: "
+
indicatorText
+
" ,isMin: "
+
isMin
+
" ,isMax: "
+
isMax
;
}
}
m-consultant/src/main/java/com/yidianling/consultant/ui/view/rangeseekbar/Utils.java
0 → 100644
View file @
59834452
package
com
.
yidianling
.
consultant
.
ui
.
view
.
rangeseekbar
;
import
android.content.Context
;
import
android.graphics.Bitmap
;
import
android.graphics.Canvas
;
import
android.graphics.Color
;
import
android.graphics.Matrix
;
import
android.graphics.NinePatch
;
import
android.graphics.Paint
;
import
android.graphics.Rect
;
import
android.graphics.drawable.BitmapDrawable
;
import
android.graphics.drawable.Drawable
;
import
android.os.Build
;
import
android.util.Log
;
import
androidx.annotation.ColorRes
;
import
androidx.core.content.ContextCompat
;
/**
* ================================================
* 作 者:JayGoo
* 版 本:
* 创建日期:2018/5/8
* 描 述:
* ================================================
*/
public
class
Utils
{
private
static
final
String
TAG
=
"RangeSeekBar"
;
public
static
void
print
(
String
log
)
{
Log
.
d
(
TAG
,
log
);
}
public
static
void
print
(
Object
...
logs
)
{
StringBuilder
stringBuilder
=
new
StringBuilder
();
for
(
Object
log
:
logs
)
{
stringBuilder
.
append
(
log
);
}
Log
.
d
(
TAG
,
stringBuilder
.
toString
());
}
public
static
Bitmap
drawableToBitmap
(
Context
context
,
int
width
,
int
height
,
int
drawableId
)
{
if
(
context
==
null
||
width
<=
0
||
height
<=
0
||
drawableId
==
0
)
return
null
;
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
LOLLIPOP
)
{
return
Utils
.
drawableToBitmap
(
width
,
height
,
context
.
getResources
().
getDrawable
(
drawableId
,
null
));
}
else
{
return
Utils
.
drawableToBitmap
(
width
,
height
,
context
.
getResources
().
getDrawable
(
drawableId
));
}
}
/**
* make a drawable to a bitmap
*
* @param drawable drawable you want convert
* @return converted bitmap
*/
public
static
Bitmap
drawableToBitmap
(
int
width
,
int
height
,
Drawable
drawable
)
{
Bitmap
bitmap
=
null
;
try
{
if
(
drawable
instanceof
BitmapDrawable
)
{
BitmapDrawable
bitmapDrawable
=
(
BitmapDrawable
)
drawable
;
bitmap
=
bitmapDrawable
.
getBitmap
();
if
(
bitmap
!=
null
&&
bitmap
.
getHeight
()
>
0
)
{
Matrix
matrix
=
new
Matrix
();
float
scaleWidth
=
width
*
1.0f
/
bitmap
.
getWidth
();
float
scaleHeight
=
height
*
1.0f
/
bitmap
.
getHeight
();
matrix
.
postScale
(
scaleWidth
,
scaleHeight
);
bitmap
=
Bitmap
.
createBitmap
(
bitmap
,
0
,
0
,
bitmap
.
getWidth
(),
bitmap
.
getHeight
(),
matrix
,
true
);
return
bitmap
;
}
}
bitmap
=
Bitmap
.
createBitmap
(
width
,
height
,
Bitmap
.
Config
.
ARGB_8888
);
Canvas
canvas
=
new
Canvas
(
bitmap
);
drawable
.
setBounds
(
0
,
0
,
canvas
.
getWidth
(),
canvas
.
getHeight
());
drawable
.
draw
(
canvas
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
return
bitmap
;
}
/**
* draw 9Path
*
* @param canvas Canvas
* @param bmp 9path bitmap
* @param rect 9path rect
*/
public
static
void
drawNinePath
(
Canvas
canvas
,
Bitmap
bmp
,
Rect
rect
)
{
NinePatch
.
isNinePatchChunk
(
bmp
.
getNinePatchChunk
());
NinePatch
patch
=
new
NinePatch
(
bmp
,
bmp
.
getNinePatchChunk
(),
null
);
patch
.
draw
(
canvas
,
rect
);
}
public
static
void
drawBitmap
(
Canvas
canvas
,
Paint
paint
,
Bitmap
bmp
,
Rect
rect
)
{
try
{
if
(
NinePatch
.
isNinePatchChunk
(
bmp
.
getNinePatchChunk
()))
{
drawNinePath
(
canvas
,
bmp
,
rect
);
return
;
}
}
catch
(
Exception
e
)
{
}
canvas
.
drawBitmap
(
bmp
,
rect
.
left
,
rect
.
top
,
paint
);
}
public
static
int
dp2px
(
Context
context
,
float
dpValue
)
{
if
(
context
==
null
||
compareFloat
(
0
f
,
dpValue
)
==
0
)
return
0
;
final
float
scale
=
context
.
getResources
().
getDisplayMetrics
().
density
;
return
(
int
)
(
dpValue
*
scale
+
0.5f
);
}
/**
* Compare the size of two floating point numbers
*
* @param a
* @param b
* @return 1 is a > b
* -1 is a < b
* 0 is a == b
*/
public
static
int
compareFloat
(
float
a
,
float
b
)
{
int
ta
=
Math
.
round
(
a
*
1000000
);
int
tb
=
Math
.
round
(
b
*
1000000
);
if
(
ta
>
tb
)
{
return
1
;
}
else
if
(
ta
<
tb
)
{
return
-
1
;
}
else
{
return
0
;
}
}
/**
* Compare the size of two floating point numbers with accuracy
*
* @param a
* @param b
* @return 1 is a > b
* -1 is a < b
* 0 is a == b
*/
public
static
int
compareFloat
(
float
a
,
float
b
,
int
degree
)
{
if
(
Math
.
abs
(
a
-
b
)
<
Math
.
pow
(
0.1
,
degree
))
{
return
0
;
}
else
{
if
(
a
<
b
)
{
return
-
1
;
}
else
{
return
1
;
}
}
}
public
static
float
parseFloat
(
String
s
)
{
try
{
return
Float
.
parseFloat
(
s
);
}
catch
(
NumberFormatException
e
)
{
return
0
f
;
}
}
public
static
Rect
measureText
(
String
text
,
float
textSize
)
{
Paint
paint
=
new
Paint
();
Rect
textRect
=
new
Rect
();
paint
.
setTextSize
(
textSize
);
paint
.
getTextBounds
(
text
,
0
,
text
.
length
(),
textRect
);
paint
.
reset
();
return
textRect
;
}
public
static
boolean
verifyBitmap
(
Bitmap
bitmap
)
{
if
(
bitmap
==
null
||
bitmap
.
isRecycled
()
||
bitmap
.
getWidth
()
<=
0
||
bitmap
.
getHeight
()
<=
0
)
{
return
false
;
}
return
true
;
}
public
static
int
getColor
(
Context
context
,
@ColorRes
int
colorId
)
{
if
(
context
!=
null
)
{
return
ContextCompat
.
getColor
(
context
.
getApplicationContext
(),
colorId
);
}
return
Color
.
WHITE
;
}
}
m-consultant/src/main/res/drawable/rsb_default_thumb.xml
0 → 100644
View file @
59834452
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:shape=
"oval"
>
<solid
android:color=
"@color/platform_gray7"
/>
<stroke
android:width=
"1dp"
android:color=
"@color/platform_gray7"
/>
</shape>
m-consultant/src/main/res/drawable/thumb_yellow_stroke.xml
0 → 100644
View file @
59834452
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:shape=
"oval"
>
<solid
android:color=
"@android:color/white"
/>
<stroke
android:width=
"2dp"
android:color=
"@color/platform_main_theme"
/>
</shape>
m-consultant/src/main/res/layout/consultant_ui_filter_popup.xml
View file @
59834452
...
@@ -185,15 +185,27 @@
...
@@ -185,15 +185,27 @@
</ScrollView>
</ScrollView>
<com.google.android.material.slider.RangeSlider
<com.yidianling.consultant.ui.view.rangeseekbar.RangeSeekBar
android:id=
"@+id/rangeSliderPrice"
android:id=
"@+id/sb_steps_6"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:layout_height=
"wrap_content"
android:stepSize=
"50"
android:layout_width=
"wrap_content"
android:theme=
"@style/Theme.MaterialComponents.DayNight.NoActionBar"
app:rsb_gravity=
"bottom"
android:valueFrom=
"50"
app:rsb_mode=
"range"
android:valueTo=
"500"
app:rsb_progress_color=
"@color/platform_main_theme"
app:values=
"@array/initial_slider_values"
></com.google.android.material.slider.RangeSlider>
app:rsb_step_auto_bonding=
"false"
app:rsb_step_color=
"@color/platform_gray7"
app:rsb_step_height=
"5dp"
app:rsb_step_width=
"1dp"
app:rsb_steps=
"4"
app:rsb_thumb_drawable=
"@drawable/thumb_yellow_stroke"
app:rsb_thumb_height=
"15dp"
app:rsb_thumb_width=
"15dp"
app:rsb_tick_mark_layout_gravity=
"bottom"
app:rsb_tick_mark_mode=
"other"
app:rsb_tick_mark_text_array=
"@array/wordsArray"
app:rsb_tick_mark_text_margin=
"20dp"
>
</com.yidianling.consultant.ui.view.rangeseekbar.RangeSeekBar>
<LinearLayout
<LinearLayout
android:layout_width=
"match_parent"
android:layout_width=
"match_parent"
...
...
m-consultant/src/main/res/values/arrays.xml
0 → 100644
View file @
59834452
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array
name=
"wordsArray"
>
<item>
0
</item>
<item>
100
</item>
<item>
200
</item>
<item>
300
</item>
<item>
不限
</item>
</string-array>
</resources>
\ No newline at end of file
m-consultant/src/main/res/values/attrs.xml
0 → 100644
View file @
59834452
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable
name=
"RangeSeekBar"
>
<!--RangeSeekBar common attrs-->
<!--The maximum-->
<attr
name=
"rsb_max"
format=
"float"
/>
<!--The minimum-->
<attr
name=
"rsb_min"
format=
"float"
/>
<!--RangeSeekBar mode, single is normal seekBar, range is RangeSeekBar-->
<attr
name=
"rsb_mode"
format=
"enum"
>
<enum
name=
"single"
value=
"1"
/>
<enum
name=
"range"
value=
"2"
/>
</attr>
<!--RangeSeekBar gravity-->
<attr
name=
"rsb_gravity"
format=
"enum"
>
<enum
name=
"top"
value=
"0"
/>
<enum
name=
"bottom"
value=
"1"
/>
<enum
name=
"center"
value=
"2"
/>
</attr>
<!--The min interval of the thumbs -->
<attr
name=
"rsb_min_interval"
format=
"float"
/>
<!-- 0 for the normal mode, greater than 1 to switch to scale mode-->
<attr
name=
"rsb_tick_mark_number"
format=
"integer"
/>
<!--Scale mode
Number according to the scale of the actual proportion of the distribution of the location (markTextArray must be a number)
Other bisects the current layout (markTextArray can be any character)
-->
<attr
name=
"rsb_tick_mark_mode"
format=
"enum"
>
<enum
name=
"number"
value=
"0"
/>
<enum
name=
"other"
value=
"1"
/>
</attr>
<!--The tick mark text gravity -->
<attr
name=
"rsb_tick_mark_gravity"
format=
"enum"
>
<enum
name=
"left"
value=
"0"
/>
<enum
name=
"center"
value=
"1"
/>
<enum
name=
"right"
value=
"2"
/>
</attr>
<!--The tick mark text layout gravity -->
<attr
name=
"rsb_tick_mark_layout_gravity"
format=
"enum"
>
<enum
name=
"top"
value=
"0"
/>
<enum
name=
"bottom"
value=
"1"
/>
</attr>
<!--The tick mark text array -->
<attr
name=
"rsb_tick_mark_text_array"
format=
"reference"
/>
<!--The tick mark text margin bottom to progress -->
<attr
name=
"rsb_tick_mark_text_margin"
format=
"dimension"
/>
<attr
name=
"rsb_tick_mark_text_size"
format=
"dimension"
/>
<attr
name=
"rsb_tick_mark_text_color"
format=
"color"
/>
<!--it just work in range && number mode now-->
<attr
name=
"rsb_tick_mark_in_range_text_color"
format=
"color"
/>
<attr
name=
"rsb_progress_height"
format=
"dimension"
/>
<attr
name=
"rsb_progress_radius"
format=
"dimension"
/>
<!--the color of progress bar when in progress-->
<attr
name=
"rsb_progress_color"
format=
"color"
/>
<!--the default color of the progress bar-->
<attr
name=
"rsb_progress_default_color"
format=
"color"
/>
<attr
name=
"rsb_progress_drawable"
format=
"reference"
/>
<attr
name=
"rsb_progress_drawable_default"
format=
"reference"
/>
<!--SeekBar attrs-->
<attr
name=
"rsb_indicator_show_mode"
format=
"enum"
>
<enum
name=
"showWhenTouch"
value=
"0"
/>
<enum
name=
"alwaysHide"
value=
"1"
/>
<enum
name=
"alwaysShowAfterTouch"
value=
"2"
/>
<enum
name=
"alwaysShow"
value=
"3"
/>
</attr>
<attr
name=
"rsb_indicator_height"
format=
"dimension"
>
<enum
name=
"wrap_content"
value=
"-1"
/>
</attr>
<attr
name=
"rsb_indicator_width"
format=
"dimension"
>
<enum
name=
"wrap_content"
value=
"-1"
/>
</attr>
<!--indicator margin bottom to progress bar-->
<attr
name=
"rsb_indicator_margin"
format=
"dimension"
/>
<attr
name=
"rsb_indicator_text_size"
format=
"dimension"
/>
<attr
name=
"rsb_indicator_text_color"
format=
"color"
/>
<!--indicator arrow size, it just work when you not use rsb_indicator_drawable -->
<attr
name=
"rsb_indicator_arrow_size"
format=
"dimension"
/>
<!-- must use 9 path !!!-->
<attr
name=
"rsb_indicator_drawable"
format=
"reference"
/>
<attr
name=
"rsb_indicator_background_color"
format=
"color"
/>
<attr
name=
"rsb_indicator_padding_left"
format=
"dimension"
/>
<attr
name=
"rsb_indicator_padding_right"
format=
"dimension"
/>
<attr
name=
"rsb_indicator_padding_top"
format=
"dimension"
/>
<attr
name=
"rsb_indicator_padding_bottom"
format=
"dimension"
/>
<attr
name=
"rsb_indicator_radius"
format=
"dimension"
/>
<attr
name=
"rsb_thumb_drawable"
format=
"reference"
/>
<!--the thumb inactivated is when you don't touch the thumb button-->
<attr
name=
"rsb_thumb_inactivated_drawable"
format=
"reference"
/>
<attr
name=
"rsb_thumb_width"
format=
"dimension"
/>
<attr
name=
"rsb_thumb_height"
format=
"dimension"
/>
<attr
name=
"rsb_thumb_scale_ratio"
format=
"float"
/>
<!--steps SeekBar-->
<attr
name=
"rsb_steps"
format=
"integer"
/>
<attr
name=
"rsb_step_color"
format=
"color"
/>
<attr
name=
"rsb_step_width"
format=
"dimension"
/>
<attr
name=
"rsb_step_height"
format=
"dimension"
/>
<attr
name=
"rsb_step_radius"
format=
"dimension"
/>
<attr
name=
"rsb_step_auto_bonding"
format=
"boolean"
/>
<attr
name=
"rsb_step_drawable"
format=
"reference"
/>
</declare-styleable>
<declare-styleable
name=
"VerticalRangeSeekBar"
>
<!--the vertical RangeSeekBar draw orientation-->
<attr
name=
"rsb_orientation"
format=
"enum"
>
<enum
name=
"left"
value=
"1"
/>
<enum
name=
"right"
value=
"2"
/>
</attr>
<attr
name=
"rsb_tick_mark_orientation"
format=
"enum"
>
<enum
name=
"vertical"
value=
"1"
/>
<enum
name=
"horizontal"
value=
"2"
/>
</attr>
<attr
name=
"rsb_indicator_text_orientation"
format=
"enum"
>
<enum
name=
"vertical"
value=
"1"
/>
<enum
name=
"horizontal"
value=
"2"
/>
</attr>
</declare-styleable>
</resources>
m-consultant/src/main/res/values/styles.xml
View file @
59834452
...
@@ -45,9 +45,4 @@
...
@@ -45,9 +45,4 @@
<item
name=
"android:windowNoTitle"
>
true
</item>
<item
name=
"android:windowNoTitle"
>
true
</item>
<item
name=
"android:windowIsTranslucent"
>
true
</item>
<item
name=
"android:windowIsTranslucent"
>
true
</item>
</style>
</style>
<array
name=
"initial_slider_values"
>
<item>
100
</item>
<item>
200
</item>
</array>
</resources>
</resources>
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