最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

每日动态!欢迎页轮播动画

来源:博客园

如图,引导开始,球从上落下,同时淡入文字,然后文字开始轮播,最后一页时停止,点击进入首页。

在来看看效果图。

重力球先不讲,主要欢迎轮播简单实现


(相关资料图)

首先新建一个类TextTranslationXGuideView,用于动画展示

文本是类似的,最后会有个图片箭头动画,布局很简单,就是一个 TextView 跟 ImageView,直接写 xml 布局里方便了

所以TextTranslationXGuideView 直接继承 FrameLayout,然后动态添加布局,控制动画

val root = LayoutInflater.from(context)            .inflate(R.layout.login_layout_text_translation_x_guide, this, false)        root.layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)        addView(root)        mBinding = LoginLayoutTextTranslationXGuideBinding.bind(root)
login_layout_text_translation_x_guide
            

文字颜色换行等通过 span 设置,所以需要一个类去配置

data class TextTranslationXGuideBean(        val content: String, //内容        val bright: String?, //高亮文本        val brightColor: Int = R.color.bl_black //高亮字体颜色    )

轮播配置成动态的,所以这里使用一个集合去存储

private val guideList = mutableListOf()
/**     * 添加单个引导文本     * @param content 内容     * @param bright 高亮文本     * @param brightColor 高亮字体颜色     * */    fun addTextGuide(        content: String,        bright: String? = null,        brightColor: Int? = null    ): TextTranslationXGuideView {        guideList.add(TextTranslationXGuideBean(content, bright, brightColor ?: R.color.bl_black))        return this    }

然后在动态设置内容跟图片

/** 设置引导内容 */    private fun setGuideContent(bean: TextTranslationXGuideBean) {        mBinding?.tvContent?.text = bean.content        val span = SpanUtils.with(mBinding?.tvContent)            .append(bean.content)            .setForegroundColor(resources.getColor(R.color.bl_black, null))        bean.bright?.let {            span.append("\n${bean.bright}")                .setForegroundColor(resources.getColor(bean.brightColor, null))        }        span.create()    }

接下来需要两个动画,一个淡入,一个平移(TextView 自带的跑马灯不好控制,后期如果更换方案改动也大)

private var mTranslationAnimator: ValueAnimator? = nullprivate var mFlickerAnimator: ValueAnimator? = nullinit {        initView()        initTranslationAnimation()        initGuideRightAnimate()    }

平移动画重复执行,轮播显示,通过下标控制,显示 guideList 中的数据,如果轮播到最后一条,展示箭头闪烁动画

private fun initTranslationAnimation() {        val point = -ScreenUtils.getScreenWidth().toFloat()        mTranslationAnimator = ValueAnimator.ofFloat(0f, point)        mTranslationAnimator?.duration = 300        mTranslationAnimator?.interpolator = LinearInterpolator()        mTranslationAnimator?.addUpdateListener { animation ->            val scrollX = animation.animatedValue as Float            translationX = scrollX            if (scrollX <= point) {                mTranslationAnimator?.cancel()                alpha = 0f                translationX = 0f                nextGuide()            }        }    }private fun initTranslationAnimation() {        val point = -ScreenUtils.getScreenWidth().toFloat()        mTranslationAnimator = ValueAnimator.ofFloat(0f, point)        mTranslationAnimator?.duration = 300        mTranslationAnimator?.interpolator = LinearInterpolator()        mTranslationAnimator?.addUpdateListener { animation ->            val scrollX = animation.animatedValue as Float            translationX = scrollX            if (scrollX <= point) {                mTranslationAnimator?.cancel()                alpha = 0f                translationX = 0f                nextGuide()            }        }    }/** 开始时调用 */    fun initGuide() {        position = 0        if (guideList.size > 0) {            guideList.getOrNull(position)?.let {                setGuideContent(it)            }            //渐入            alpha = 0f            startAlphaAnimation(1500) {                startTranslationAnimator()            }        }    }

结束时清楚缓存跳转首页

fun clear() {        guideList.clear()        mTranslationAnimator?.cancel()        mTranslationAnimator = null        mFlickerAnimator?.cancel()        mFlickerAnimator = null    }

全部实现

/** 登录引导动画 */class TextTranslationXGuideView(context: Context, attrs: AttributeSet?) :    FrameLayout(context, attrs) {    private var mBinding: LoginLayoutTextTranslationXGuideBinding? = null    private var mTranslationAnimator: ValueAnimator? = null    private var mFlickerAnimator: ValueAnimator? = null    private val guideList = mutableListOf()    private var position = 0//当前显示的引导索引    var clickRight: (() -> Unit)? = null    init {        initView()        initTranslationAnimation()        initGuideRightAnimate()    }    private fun initView() {        val root = LayoutInflater.from(context)            .inflate(R.layout.login_layout_text_translation_x_guide, this, false)        root.layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)        addView(root)        mBinding = LoginLayoutTextTranslationXGuideBinding.bind(root)        mBinding?.ivGuide1?.setOnThrottledClickListener {            clickRight?.invoke()        }        mBinding?.ivGuide2?.setOnThrottledClickListener {            clickRight?.invoke()        }    }    private fun initTranslationAnimation() {        val point = -ScreenUtils.getScreenWidth().toFloat()        mTranslationAnimator = ValueAnimator.ofFloat(0f, point)        mTranslationAnimator?.duration = 300        mTranslationAnimator?.interpolator = LinearInterpolator()        mTranslationAnimator?.addUpdateListener { animation ->            val scrollX = animation.animatedValue as Float            translationX = scrollX            if (scrollX <= point) {                mTranslationAnimator?.cancel()                alpha = 0f                translationX = 0f                nextGuide()            }        }    }    private fun startTranslationAnimator() {        mTranslationAnimator?.start()    }    private fun initGuideRightAnimate() {        mFlickerAnimator = ValueAnimator.ofFloat(0f, 1f)        mFlickerAnimator?.duration = 600        mFlickerAnimator?.interpolator = LinearInterpolator()        mFlickerAnimator?.repeatMode = ValueAnimator.REVERSE        mFlickerAnimator?.repeatCount = ValueAnimator.INFINITE        mFlickerAnimator?.addUpdateListener { animation ->            val alpha = animation.animatedValue as Float            mBinding?.ivGuide2?.alpha = alpha        }    }    private fun startGuideRightAnimator() {        mBinding?.ivGuide2?.visibility = View.VISIBLE        mBinding?.ivGuide2?.alpha = 0f        mFlickerAnimator?.start()    }    /** 开始时调用 */    fun initGuide() {        position = 0        if (guideList.size > 0) {            guideList.getOrNull(position)?.let {                setGuideContent(it)            }            //渐入            alpha = 0f            startAlphaAnimation(1500) {                startTranslationAnimator()            }        }    }    /** 下一个引导 */    private fun nextGuide() {        position += 1        //是否为最后一条数据        val isEndGuide = position == guideList.size - 1        //第一个图标需要先展示        mBinding?.ivGuide1?.visibility = if (isEndGuide) View.VISIBLE else View.GONE        guideList.getOrNull(position)?.let {            setGuideContent(it)            startAlphaAnimation {                if (position < guideList.size - 1) {                    //如果有,循环执行下一个引导                    startTranslationAnimator()                } else {                    //最后一个,执行渐变闪烁动画                    startGuideRightAnimator()                }            }        }    }    private fun startAlphaAnimation(duration: Long = 1000L, endListener: (() -> Unit)) {        animate().setDuration(duration).alpha(1f)            .setListener(object : Animator.AnimatorListener {                override fun onAnimationStart(p0: Animator?) {}                override fun onAnimationEnd(p0: Animator?) {                    endListener.invoke()                }                override fun onAnimationCancel(p0: Animator?) {}                override fun onAnimationRepeat(p0: Animator?) {}            })    }    /** 设置引导内容 */    private fun setGuideContent(bean: TextTranslationXGuideBean) {        mBinding?.tvContent?.text = bean.content        val span = SpanUtils.with(mBinding?.tvContent)            .append(bean.content)            .setForegroundColor(resources.getColor(R.color.bl_black, null))        bean.bright?.let {            span.append("\n${bean.bright}")                .setForegroundColor(resources.getColor(bean.brightColor, null))        }        span.create()    }    /**     * 添加单个引导文本     * @param content 内容     * @param bright 高亮文本     * @param brightColor 高亮字体颜色     * */    fun addTextGuide(        content: String,        bright: String? = null,        brightColor: Int? = null    ): TextTranslationXGuideView {        guideList.add(TextTranslationXGuideBean(content, bright, brightColor ?: R.color.bl_black))        return this    }    fun clear() {        guideList.clear()        mTranslationAnimator?.cancel()        mTranslationAnimator = null        mFlickerAnimator?.cancel()        mFlickerAnimator = null    }    data class TextTranslationXGuideBean(        val content: String, //内容        val bright: String?, //高亮文本        val brightColor: Int = R.color.bl_black //高亮字体颜色    )}
TextTranslationXGuideView

关键词: