最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

android小動畫:不斷擴(kuò)散的圓點(diǎn)

 更新時間:2021年11月26日 15:51:52   作者:多列米  
這篇文章介紹了如何實(shí)現(xiàn)android小動畫:不斷擴(kuò)散的圓點(diǎn),文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,下面的實(shí)例代碼,大家可以看看

?效果圖

(ps: 其實(shí)就兩個半徑和透明度一起變化的小圓, 本項(xiàng)目中用來指示指尖位置)

實(shí)現(xiàn)原理

監(jiān)聽點(diǎn)擊的位置,在父布局中動態(tài)增加 自定義的動畫View

代碼實(shí)現(xiàn)

(1)activity點(diǎn)擊監(jiān)聽及添加View

   // 觸屏點(diǎn)擊位置
    private var pointX: Int = 0
    private var pointY: Int = 0
    private var circleView: SpreadCircleView?= null

    // 觸摸點(diǎn)擊
    override fun onTouchEvent(event: MotionEvent?): Boolean {
        when (event!!.action) {
            MotionEvent.ACTION_DOWN -> {
                pointX = event.x.toInt()
                pointY = event.y.toInt()
            }
            MotionEvent.ACTION_MOVE -> { }
            MotionEvent.ACTION_UP ->{ addPointCircle() }
            else -> { }
        }
        return true
    }
   /**
     * 添加自動擴(kuò)散的圓點(diǎn) View
     */
    fun addPointCircle(){
        if(circleView == null){
            circleView = SpreadCircleView(this);
            circleView?.let{
                lifecycle.addObserver(it)
            }
        }
        binding.rootLayout.removeView(circleView)
        circleView?.let{
            // 寬度和高度相同
            val width = it.maxRadius.toInt() * 2
            var lp = FrameLayout.LayoutParams(width,  width )
            lp.marginStart = pointX - width/2
            lp.topMargin = pointY - width/2
            binding.rootLayout.addView(it, lp)
            it.startAnimation()
        }
    }

(2)圓點(diǎn)View實(shí)現(xiàn)(屬性動畫,根據(jù)動畫進(jìn)度來確定圓的當(dāng)前半徑,利用LifecycleObserver綁定周期)

/**
 *  Created by Liming on  2021/9/1 15:36
 *  不斷擴(kuò)散的小圓, 用于顯示指尖位置
 */
class SpreadCircleView : View, LifecycleObserver {

    private var paint: Paint = Paint()
    // 圓圈最大半徑
    val maxRadius = 25.toPx()
    // 圓圈中心點(diǎn)
    var centerX:Int = 0
    var centerY:Int = 0

    private var animator : ObjectAnimator? = null

    // 是否已開始繪制第二個圓
    var hasDrawCicle2 = false

    // 動畫進(jìn)度
    private var progress = 0f
        set(value){
            field = value
            // 刷新界面
            invalidate()
        }

    constructor(context: Context?) : super(context)
    constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)
    constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context,
        attrs,
        defStyleAttr)

    init{
        paint.style = Paint.Style.FILL
        paint.color = ContextCompat.getColor(context, R.color.rect_orange) // #ffa200
        paint.strokeWidth = 3.toPx()
        paint.isAntiAlias = true // 防鋸齒
    }

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        //圓心位置
        centerX = w / 2;
        centerY = h / 2;
    }

    override fun draw(canvas: Canvas?) {
        super.draw(canvas)
        // 第一個圓
        drawCircle(canvas, progress)
        // 第二個圓
        if(hasDrawCicle2 || progress > 0.5f ){
            // 第一個圓的進(jìn)度第一次達(dá)到 0.5 時,開始繪制第二個圓,
            hasDrawCicle2 = true
            var progress2 = progress + 0.5f
            if(progress2 > 1){
                progress2 = progress2 - 1
            }
            drawCircle(canvas, progress2)
        }
    }

    /**
     * 根據(jù)進(jìn)度繪制 半徑和透明度變化的圓
     */
    fun drawCircle(canvas: Canvas?, animProgress: Float){
        // 透明度 0 - 255
        var alpha = 255 * (1 - animProgress)
        paint.alpha = alpha.toInt()
        var radius = maxRadius * animProgress
        // 繪制圓
        canvas?.drawCircle(centerX.toFloat(), centerY.toFloat(), radius, paint )
    }


    private fun getAnimator(): ObjectAnimator?{
        if(animator == null){
            animator = ObjectAnimator.ofFloat(this,
                "progress", 0f, 0.99f)
            animator?.duration = 1500
            animator?.repeatCount = -1 //-1代表無限循環(huán)
            animator?.interpolator = LinearInterpolator()
        }
        return animator
    }

    fun startAnimation() {
        // 開始動畫
        getAnimator()?.start()
        hasDrawCicle2 = false
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    fun resume() {
        // 開始動畫
        animator?.start()
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    fun pause() {
        animator?.pause()
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    fun destory() {
        // 清除動畫,避免內(nèi)存泄漏,
        animator?.cancel()
        clearAnimation()
    }
} 

補(bǔ)充一個用到的擴(kuò)展函數(shù)

    fun Int.toPx(): Float{
        val resources = Resources.getSystem()
        return TypedValue.applyDimension(
                TypedValue.COMPLEX_UNIT_DIP,
                this.toFloat(),
                resources.displayMetrics
        )
    }

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論

静宁县| 平武县| 文安县| 靖州| 福清市| 洛隆县| 泰州市| 德安县| 屏南县| 通河县| 韶山市| 东莞市| 宁德市| 交城县| 万荣县| 乌恰县| 远安县| 逊克县| 三原县| 静宁县| 来安县| 兴文县| 万年县| 和平区| 龙南县| 宝鸡市| 四子王旗| 长宁县| 永和县| 湖北省| 拜城县| 东光县| 寿宁县| 修文县| 黑山县| 邵武市| 杂多县| 利津县| 绥江县| 高平市| 正蓝旗|