直播平台源代码,Android自定义View实现呼吸灯效果
直播平台源代码,Android自定义View实现呼吸灯效果
自定义View
自定义 BreathView 的Kotlin代码如下:
1 | <br>import android.animation.ValueAnimator<br>import android.animation.ValueAnimator.AnimatorUpdateListener<br>import android.content.Context<br>import android.graphics.Canvas<br>import android.graphics.Color<br>import android.graphics.Paint<br>import android.util.AttributeSet<br>import android.view.View<br>import android.view.animation.Animation<br>import android.view.animation.LinearInterpolator<br> class BreathView @JvmOverloads constructor(<br> context: Context,<br> attrs: AttributeSet? = null,<br> defStyleAttr: Int = 0<br>) : View(context, attrs, defStyleAttr), AnimatorUpdateListener {<br> private val mCenterCircleRadius: Float<br> private var mMaxCircleRadius: Float<br> private val mCirclePaint: Paint<br> private var mAlphaValue = 0<br> init {<br> val a = context.obtainStyledAttributes(attrs, R.styleable.BreathView)<br> mCenterCircleRadius = a.getDimension(R.styleable.BreathView_centerCircleRadius, 5f)<br> mMaxCircleRadius = a.getDimension(R.styleable.BreathView_maxCircleRadius, 10f)<br> if (mCenterCircleRadius >= mMaxCircleRadius) {<br> mMaxCircleRadius = mCenterCircleRadius * 2<br> }<br> val circleColor = a.getColor(R.styleable.BreathView_circleColor, Color.GREEN)<br> a.recycle()<br> mCirclePaint = Paint()<br> mCirclePaint.isAntiAlias = true<br> mCirclePaint.style = Paint.Style.FILL<br> mCirclePaint.color = circleColor<br> val circleAlphaValueAnimator = ValueAnimator.ofInt(0, 255)<br> circleAlphaValueAnimator.duration = BREATH_TIME<br> circleAlphaValueAnimator.repeatCount = Animation.INFINITE<br> circleAlphaValueAnimator.repeatMode = ValueAnimator.REVERSE<br> circleAlphaValueAnimator.interpolator = LinearInterpolator()<br> circleAlphaValueAnimator.addUpdateListener(this)<br> circleAlphaValueAnimator.start()<br> }<br> override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {<br> super.onMeasure(widthMeasureSpec, heightMeasureSpec)<br> var width = MeasureSpec.getSize(widthMeasureSpec)<br> var height = MeasureSpec.getSize(heightMeasureSpec)<br> val widthMode = MeasureSpec.getMode(widthMeasureSpec)<br> val heightMode = MeasureSpec.getMode(widthMeasureSpec)<br> if (widthMode == MeasureSpec.AT_MOST || widthMode == MeasureSpec.UNSPECIFIED) {<br> width = Math.max(width.toFloat(), mMaxCircleRadius * 2).toInt()<br> }<br> if (heightMode == MeasureSpec.AT_MOST || heightMode == MeasureSpec.UNSPECIFIED) {<br> height = Math.max(width.toFloat(), mMaxCircleRadius * 2).toInt()<br> }<br> setMeasuredDimension(width, height)<br> }<br> override fun draw(canvas: Canvas) {<br> super.draw(canvas)<br> val centerX = width / 2.0f<br> val centerY = height / 2.0f<br> mCirclePaint.alpha = 255<br> canvas.drawCircle(centerX, centerY, mCenterCircleRadius, mCirclePaint)<br> mCirclePaint.alpha = mAlphaValue<br> canvas.drawCircle(centerX, centerY, mMaxCircleRadius, mCirclePaint)<br> }<br> override fun onAnimationUpdate(valueAnimator: ValueAnimator) {<br> mAlphaValue = valueAnimator.animatedValue as Int<br> invalidate()<br> }<br> companion object {<br> private const val BREATH_TIME: Long = 1000 //动画执行时间/呼吸速率<br> }<br>} |
自定义 BreathView 的Java代码如下:
1 | <br>import android.animation.ValueAnimator;<br>import android.content.Context;<br>import android.content.res.TypedArray;<br>import android.graphics.Canvas;<br>import android.graphics.Color;<br>import android.graphics.Paint;<br>import android.util.AttributeSet;<br>import android.view.View;<br>import android.view.animation.Animation;<br>import android.view.animation.LinearInterpolator;<br> public class BreathView extends View implements ValueAnimator.AnimatorUpdateListener {<br> private static final long BREATH_TIME = 1000; //动画执行时间/呼吸速率<br>private final float mCenterCircleRadius;<br>private float mMaxCircleRadius;<br>private final Paint mCirclePaint;<br>private int mAlphaValue;<br>public BreathView(Context context) {<br>this(context, null);<br>}<br>public BreathView(Context context, AttributeSet attrs) {<br>this(context, attrs, 0);<br>}<br>public BreathView(Context context, AttributeSet attrs, int defStyleAttr) {<br>super(context, attrs, defStyleAttr);<br>final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.BreathView);<br>mCenterCircleRadius = a.getDimension(R.styleable.BreathView_centerCircleRadius, 5f);<br>mMaxCircleRadius = a.getDimension(R.styleable.BreathView_maxCircleRadius, 10f);<br>if (mCenterCircleRadius >= mMaxCircleRadius) {<br>mMaxCircleRadius = mCenterCircleRadius * 2;<br>}<br>int circleColor = a.getColor(R.styleable.BreathView_circleColor, Color.GREEN);<br>a.recycle();<br>mCirclePaint = new Paint();<br>mCirclePaint.setAntiAlias(true);<br>mCirclePaint.setStyle(Paint.Style.FILL);<br>mCirclePaint.setColor(circleColor);<br>ValueAnimator circleAlphaValueAnimator = ValueAnimator.ofInt(0, 255);<br>circleAlphaValueAnimator.setDuration(BREATH_TIME);<br>circleAlphaValueAnimator.setRepeatCount(Animation.INFINITE);<br>circleAlphaValueAnimator.setRepeatMode(ValueAnimator.REVERSE);<br>circleAlphaValueAnimator.setInterpolator(new LinearInterpolator());<br>circleAlphaValueAnimator.addUpdateListener(this);<br>circleAlphaValueAnimator.start();<br>}<br>@Override<br>protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {<br>super.onMeasure(widthMeasureSpec, heightMeasureSpec);<br>int width = MeasureSpec.getSize(widthMeasureSpec);<br>int height = MeasureSpec.getSize(heightMeasureSpec);<br>int widthMode = MeasureSpec.getMode(widthMeasureSpec);<br>int heightMode = MeasureSpec.getMode(widthMeasureSpec);<br>if(widthMode == MeasureSpec.AT_MOST || widthMode == MeasureSpec.UNSPECIFIED) {<br>width = (int) Math.max(width, mMaxCircleRadius * 2);<br>}<br>if(heightMode == MeasureSpec.AT_MOST || heightMode == MeasureSpec.UNSPECIFIED) {<br> height = (int) Math.max(width, mMaxCircleRadius * 2);<br> }<br>setMeasuredDimension(width, height);<br>}<br>@Override<br>public void draw(Canvas canvas) {<br> super.draw(canvas);<br>float centerX = getWidth() / 2.0f;<br>float centerY = getHeight() / 2.0f;<br>mCirclePaint.setAlpha(255);<br>canvas.drawCircle(centerX, centerY, mCenterCircleRadius, mCirclePaint);<br>mCirclePaint.setAlpha(mAlphaValue);<br>canvas.drawCircle(centerX, centerY, mMaxCircleRadius, mCirclePaint);<br>}<br>@Override<br>public void onAnimationUpdate(ValueAnimator valueAnimator) {<br>mAlphaValue = (int) valueAnimator.getAnimatedValue();<br>invalidate();<br>}<br>} |
以上就是直播平台源代码,Android自定义View实现呼吸灯效果, 更多内容欢迎关注之后的文章
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
2022-03-07 短视频app开发,Flutter StaggeredGridView的瀑布流效果
2022-03-07 直播软件搭建,状态栏颜色跟随设备系统变化而变化
2022-03-07 直播软件开发,自定义搜索栏的图标样式和搜索框