如果在 onViewCreated() 之后 运行,自定义视图将不会更新
Custom view will not update if run after onViewCreated()
我构建了一个名为 progressCircle
的自定义 view
class,它是一个类似于 snapchat 的圆形进度条 - 它位于约束布局内,位于圆形按钮上方。
此视图具有参数 angle
,当从 onViewCreated()
调用时,如果 运行
将完美运行
progressCircle.angle = 100f
但是,我正在尝试为这个 onClick 设置动画。如果我运行这个相同的代码,onClick,progressCircle
不会出现?!经过反复试验,我发现在这里更新背景颜色使视图可见并且已更新。即;
button.setOnClickListener {
progressCircle.setBackgroundColor(android.R.color.transparent)
progressCircle.angle = 270f
}
这是怎么回事,我怎样才能解决这个问题,以便我可以正确地制作动画...
编辑:
class ProgressCircle(context: Context, attrs: AttributeSet) : View(context, attrs) {
private val paint: Paint
private val rect: RectF
private val fillPaint: Paint
private val fillRect: RectF
var angle: Float
var startAngle: Float = 0f
init {
val typedArray = context.obtainStyledAttributes(attrs, R.styleable.ProgressCircle)
angle = typedArray.getFloat(R.styleable.ProgressCircle_angle, 0f)
typedArray.recycle()
val offsetAngle = 0f
val color = getColor(context, R.color.outputON)
val strokeWidth = 15f
val circleSize = 276f
paint = Paint().apply {
setAntiAlias(true)
setStyle(Paint.Style.STROKE)
setStrokeWidth(strokeWidth)
setColor(color)
}
rect = RectF(
strokeWidth,
strokeWidth,
(circleSize - strokeWidth),
(circleSize - strokeWidth)
)
fillPaint = Paint().apply {
setAntiAlias(true)
setStyle(Paint.Style.FILL)
setColor(getColor(context, R.color.flat_blue_1))
}
val offsetFill = strokeWidth
fillRect = RectF(
offsetFill,
offsetFill,
(circleSize - offsetFill),
(circleSize - offsetFill)
)
//Initial Angle (optional, it can be zero)
angle = offsetAngle
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
if (getColor(context, R.color.flat_blue_1) > 0) {
canvas.drawArc(rect, 0f, 360f, false, fillPaint)
}
canvas.drawArc(rect, startAngle, angle, false, paint)
}
}
TIA
默认情况下,视图仅在某些内容发生更改时才重绘自身 - 即,根据 View
documentation:
视图“无效”时
Drawing is handled by walking the tree and recording the drawing commands of any View that needs to update. After this, the drawing commands of the entire tree are issued to screen, clipped to the newly damaged area.
如果您希望自定义视图在 angle
属性 更改时自行重绘,您需要调用 invalidate()
:
var angle: Float
set(value) {
// Do the default behavior of setting the value
field = value
// Then call invalidate() to force a redraw
invalidate()
}
}
我构建了一个名为 progressCircle
的自定义 view
class,它是一个类似于 snapchat 的圆形进度条 - 它位于约束布局内,位于圆形按钮上方。
此视图具有参数 angle
,当从 onViewCreated()
调用时,如果 运行
progressCircle.angle = 100f
但是,我正在尝试为这个 onClick 设置动画。如果我运行这个相同的代码,onClick,progressCircle
不会出现?!经过反复试验,我发现在这里更新背景颜色使视图可见并且已更新。即;
button.setOnClickListener {
progressCircle.setBackgroundColor(android.R.color.transparent)
progressCircle.angle = 270f
}
这是怎么回事,我怎样才能解决这个问题,以便我可以正确地制作动画...
编辑:
class ProgressCircle(context: Context, attrs: AttributeSet) : View(context, attrs) {
private val paint: Paint
private val rect: RectF
private val fillPaint: Paint
private val fillRect: RectF
var angle: Float
var startAngle: Float = 0f
init {
val typedArray = context.obtainStyledAttributes(attrs, R.styleable.ProgressCircle)
angle = typedArray.getFloat(R.styleable.ProgressCircle_angle, 0f)
typedArray.recycle()
val offsetAngle = 0f
val color = getColor(context, R.color.outputON)
val strokeWidth = 15f
val circleSize = 276f
paint = Paint().apply {
setAntiAlias(true)
setStyle(Paint.Style.STROKE)
setStrokeWidth(strokeWidth)
setColor(color)
}
rect = RectF(
strokeWidth,
strokeWidth,
(circleSize - strokeWidth),
(circleSize - strokeWidth)
)
fillPaint = Paint().apply {
setAntiAlias(true)
setStyle(Paint.Style.FILL)
setColor(getColor(context, R.color.flat_blue_1))
}
val offsetFill = strokeWidth
fillRect = RectF(
offsetFill,
offsetFill,
(circleSize - offsetFill),
(circleSize - offsetFill)
)
//Initial Angle (optional, it can be zero)
angle = offsetAngle
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
if (getColor(context, R.color.flat_blue_1) > 0) {
canvas.drawArc(rect, 0f, 360f, false, fillPaint)
}
canvas.drawArc(rect, startAngle, angle, false, paint)
}
}
TIA
默认情况下,视图仅在某些内容发生更改时才重绘自身 - 即,根据 View
documentation:
Drawing is handled by walking the tree and recording the drawing commands of any View that needs to update. After this, the drawing commands of the entire tree are issued to screen, clipped to the newly damaged area.
如果您希望自定义视图在 angle
属性 更改时自行重绘,您需要调用 invalidate()
:
var angle: Float
set(value) {
// Do the default behavior of setting the value
field = value
// Then call invalidate() to force a redraw
invalidate()
}
}