波形文字
代码kotlin
class WavTextView @JvmOverloads constructor(
context: Context?,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) :
View(context, attrs, defStyleAttr) {
private var mBaseline: Int = 0
private var mCenterY: Float = 0F
private var mCenterX: Float = 0F
private var mR: Float = 0F
private var mPath: Path = Path()
private var mPath2: Path = Path()
private var mRectF: RectF = RectF()
private var mPaint: Paint = Paint(Paint.ANTI_ALIAS_FLAG)
init {
mPaint.textAlign = Paint.Align.CENTER
mPaint.color = Color.BLUE
mPaint.style = Paint.Style.FILL
mPaint.strokeWidth = 0F
}
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
super.onSizeChanged(w, h, oldw, oldh)
mCenterX = measuredWidth / 2F
mCenterY = measuredHeight / 2F
mR = min(mCenterX, mCenterY) / 2F
mRectF.left = (mCenterX - mR)
mRectF.right = (mCenterX + mR)
mRectF.top = (mCenterY - mR)
mRectF.bottom = (mCenterY + mR)
mPath2.addCircle(mCenterX, mCenterY, mR, Path.Direction.CW)
mPaint.textSize = mR * 1.5F
val fontMetrics = mPaint.fontMetricsInt
mBaseline = (fontMetrics.bottom + fontMetrics.top) / 2
removeCallbacks(runnable)
post(runnable)
}
var controlPercent = 0.4F
var controlOffset = 0F
private val runnable = object : Runnable {
override fun run() {
controlOffset += (Math.random() * mR * 0.12F).toFloat()
if (controlOffset >= mR * 2) {
controlOffset = 0F
}
invalidate()
postDelayed(this, 10)
}
}
var text: String = ""
var bottomColor: Int = Color.WHITE
var topColor: Int = Color.CYAN
var wavColor: Int = Color.BLUE
override fun onDraw(canvas: Canvas?) {
super.onDraw(canvas)
mPaint.color = topColor
canvas?.drawText(text, mCenterX, mCenterY - mBaseline, mPaint)
mPath.reset()
mPaint.color = wavColor
mPath.moveTo(controlOffset - mR * 2, mCenterY)
repeat((mCenterX / mR).toInt() + 2) {
mPath.rQuadTo(mR / 2, -mR * controlPercent, mR, 0F)
mPath.rQuadTo(mR / 2, mR * controlPercent, mR, 0F)
}
mPath.rLineTo(0F, mR * 2)
mPath.lineTo(controlOffset - mR * 2, mCenterY * 2)
mPath.rLineTo(0F, -mR * 2)
mPath.close()
canvas?.drawPath(mPath, mPaint)
canvas?.clipPath(mPath)
mPaint.color = bottomColor
canvas?.drawText(text, mCenterX, mCenterY - mBaseline, mPaint)
}
}
使用
xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#000">
<com.zmp.pagedemo.view.WavTextView
android:id="@+id/wtv1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<com.zmp.pagedemo.view.WavTextView
android:id="@+id/wtv2"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<com.zmp.pagedemo.view.WavTextView
android:id="@+id/wtv3"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<com.zmp.pagedemo.view.WavTextView
android:id="@+id/wtv4"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
Activity
private fun initView() {
wtv1.text = "锲而不舍"
wtv1.topColor = Color.MAGENTA
wtv1.bottomColor = Color.WHITE
wtv2.text = "舍身取义"
wtv2.topColor = Color.RED
wtv2.bottomColor = Color.GREEN
wtv3.text = "义不容辞"
wtv3.topColor = Color.MAGENTA
wtv4.text = "辞富居贫"
wtv4.bottomColor = Color.RED
}
``