序文
まず、Xiaomiの読み込みアニメーションを見てみましょう。これは単なる写真ですが、すべてを記録することはできないため、読み込まれるとすぐに成功するものが多く、私には表示されません。チャンスがあれば、スクリーンショットを撮るだけですが、彼の読み込みアニメーションの特徴は、左側の円が回転し続けることです。
模倣効果は次のとおりです。
実装プロセス
これは難しいことではありません。式を学ぶだけです。つまり、中心、半径、角度を知り、円上の点の座標を見つけます。計算結果は、この点で実線の円を描くことができます。以下はカスタムダイアログです。 、それをしましょう一番下の現実では、ビューもカスタムビューです。
class MiuiLoadingDialog(context: Context) : Dialog(context) {
private var miuiLoadingView : MiuiLoadingView= MiuiLoadingView(context);
init {
setContentView(miuiLoadingView)
setCancelable(false)
}
override fun show() {
super.show()
val window: Window? = getWindow();
val wlp = window!!.attributes
wlp.gravity = Gravity.BOTTOM
window.setBackgroundDrawable( ColorDrawable(Color.TRANSPARENT));
wlp.width=WindowManager.LayoutParams.MATCH_PARENT;
window.attributes = wlp
}
}
复制代码
主なロジックは次のとおりです。まずclipPath
、メソッドで角の丸い形状を切り出し、次に固定された外側の円を描きます。
真ん中の円には、次のような式が必要です。
x1 = x0 + r * cos(a * PI /180 )
y1 = y0 + r * sin(a * PI /180 )
复制代码
x0とy0は外側の大きな円の中心点、rは中央の小さな円のサイズ、aは角度です。この角度を変更し続けるだけで、得られたx1とy1を次のように描くことができます。 drawCircle。
class MiuiLoadingView @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {
//Dialog上面圆角大小
val CIRCULAR: Float = 60f;
//中心移动圆位置
var rx: Float = 0f;
var ry: Float = 0f;
//左边距离
var MARGIN_LEFT: Int = 100;
//中心圆大小
var centerRadiusSize: Float = 7f;
var textPaint: Paint = Paint().apply {
textSize = 50f
color = Color.BLACK
}
var circlePaint: Paint = Paint().apply {
style = Paint.Style.STROKE
strokeWidth = 8f
isAntiAlias = true
color = Color.BLACK
}
var centerCirclePaint: Paint = Paint().apply {
style = Paint.Style.FILL
isAntiAlias = true
color = Color.BLACK
}
var degrees = 360;
val TEXT = "正在加载中,请稍等";
var textHeight = 0;
init {
var runnable = object : Runnable {
override fun run() {
val r = 12;
rx = MARGIN_LEFT + r * Math.cos(degrees.toDouble() * Math.PI / 180).toFloat()
ry =
((measuredHeight.toFloat() / 2) + r * Math.sin(degrees.toDouble() * Math.PI / 180)).toFloat();
invalidate()
degrees += 5
if (degrees > 360) degrees = 0
postDelayed(this, 1)
}
}
postDelayed(runnable, 0)
var rect = Rect()
textPaint.getTextBounds(TEXT, 0, TEXT.length, rect)
textHeight = rect.height()
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
setMeasuredDimension(widthMeasureSpec, 220);
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
var path = Path()
path.addRoundRect(
RectF(0f, 0f, measuredWidth.toFloat(), measuredHeight.toFloat()),
floatArrayOf(CIRCULAR, CIRCULAR, CIRCULAR, CIRCULAR, 0f, 0f, 0f, 0f), Path.Direction.CW
);
canvas.clipPath(path)
canvas.drawColor(Color.WHITE)
canvas.drawCircle(
MARGIN_LEFT.toFloat(), measuredHeight.toFloat() / 2,
35f, circlePaint
)
canvas.drawCircle(
rx, ry,
centerRadiusSize, centerCirclePaint
)
canvas.drawText(TEXT, (MARGIN_LEFT + 80).toFloat(), ((measuredHeight / 2)+(textHeight/2)).toFloat(), textPaint)
}
}
复制代码