android 上下轮播,广播 BulletinView

上下滚动组件比较少,而且使用方面也不是很灵活,这边就自己写了个,这边取了个巧 简单使用了一个动画就实现了上下滚动,仿照recyclerView 支持每个条目自定义

1.首先准备一个容器 LinearLayout

2. 容器内准备2个View 从adapter 创建并绑定

3.将view 添加到容器 并根据容器设置 layoutParams

4.给view 添加上下移动的平移动画

5.启动线程进行定时轮播 轮播前移除所有View 加入新View,在执行动画,就完美实现了上下无线轮播效果

kotlin 复制代码
class BulletinView(
    context: Context,
    attrs: AttributeSet?,
    defStyleAttr: Int,
    defStyleRes: Int
) : LinearLayout(context, attrs, defStyleAttr, defStyleRes) {
    constructor(context: Context) : this(context, null, 0, 0)
    constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0, 0)
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : this(
        context,
        attrs,
        defStyleAttr,
        0
    )
    //适配器
    var adapter: Adapter<ViewHolder>? = null
        set(value) {
            field = value
            if (onPause==2){
                onPause = 0
                handler.post(run)
            }
            onPause = 0
        }
    //当前位置
    private var position = 0

    /**
     * 0 未暂停 1标识要暂停 2 已暂停
     */
    private var onPause = 2
    private val handler = Handler(Looper.getMainLooper())
    private val run = Runnable {
        initView()
        next()
    }

    init { //设置排版 方向
        orientation = VERTICAL
    }
    //下一条
    private fun next() {
        if (onPause == 1) onPause = 2
        if (onPause == 0) {
            handler.postDelayed(run, 3000)
        }
    }

    //设置View
    private fun initView() {
        if (getPosition(++position) == 0) {
            position = 0
        }
        adapter?.let {
            val holder1 = it.bindingViewHolder(
                it.getViewType(getPosition(position)),
                this,
                getPosition(position)
            )
            val holder2 = it.bindingViewHolder(
                it.getViewType(getPosition(position + 1)),
                this,
                getPosition(position + 1)
            )
            it.bindingView(holder1, it.getViewType(getPosition(position)), getPosition(position))
            it.bindingView(
                holder2,
                it.getViewType(getPosition(position + 1)),
                getPosition(position + 1)
            )
            removeAllViews()
            addView(holder1.itemView)
            addView(holder2.itemView)
            holder1.itemView.layoutParams = LayoutParams(layoutParams)
            holder2.itemView.layoutParams = LayoutParams(layoutParams)
            setAnimate(holder1.itemView)
            setAnimate(holder2.itemView)
        }
    }
    //获取下标 防止越界
    private fun getPosition(position: Int): Int {
        return if (position >= (adapter?.getCount() ?: 0)) {
            0
        } else {
            position
        }
    }

    //适配器
    interface Adapter<T : ViewHolder> {
        fun bindingViewHolder(viewType: Int, group: ViewGroup, position: Int): T
        fun getViewType(viewType: Int): Int
        fun bindingView(holder: T, viewType: Int, position: Int)
        fun getCount(): Int
    }

    /**
     * 属性动画
     * 平移
     * 从下往上
     */
    private fun setAnimate(view: View): TranslateAnimation {
//      imageView中凡是有get,set方法的属性,都可以通过属性动画操作
//      创建属性动画对象,并设置移动的方向和偏移量
//      translationX是imageview的平移属性
        val objectAnimator = TranslateAnimation(0f, 0f, 0f, -height.toFloat())
//      设置移动时间
        objectAnimator.duration = 500
//      开始动画
        objectAnimator.fillAfter = true
        view.animation = objectAnimator
        objectAnimator.start()
        return objectAnimator
    }
    //暂停
    fun onPause(){
        onPause = 1
    }
    //启动
    fun onStart(){
        if (onPause==2){
            onPause = 0
            handler.post(run)
        }
        onPause = 0
    }

}

使用方法

kotlin 复制代码
 fun setBulletin(){
        val list = mutableListOf("https://lmg.jj20.com/up/allimg/1114/0406210Z024/2104060Z024-5-1200.jpg","https://lmg.jj20.com/up/allimg/1114/0406210Z024/2104060Z024-5-1200.jpg")
        binding.bulletinView.adapter = object : Adapter<ViewHolder> {
            override fun bindingViewHolder(
                viewType: Int,
                group: ViewGroup,
                position: Int
            ): ViewHolder { //这边绑定ViewHolder
               return ViewHolder (
                   BaseBannerBinding.inflate(
                       LayoutInflater.from(
                           this@MainActivity
                       ), group, false
                   )
               )
            }

            override fun getViewType(viewType: Int): Int {
               return 0
            }

            override fun getCount(): Int {
                return list.size
            }

            override fun bindingView(holder: ViewHolder, viewType: Int, position: Int) {
                val binding: BaseBannerBinding = BaseBannerBinding.bind(holder.itemView)
                binding.ivIcon.load(list[position])
            }


        }
    }
相关推荐
雨白6 小时前
Jetpack系列(二):Lifecycle与LiveData结合,打造响应式UI
android·android jetpack
kk爱闹8 小时前
【挑战14天学完python和pytorch】- day01
android·pytorch·python
每次的天空10 小时前
Android-自定义View的实战学习总结
android·学习·kotlin·音视频
恋猫de小郭10 小时前
Flutter Widget Preview 功能已合并到 master,提前在体验毛坯的预览支持
android·flutter·ios
断剑重铸之日11 小时前
Android自定义相机开发(类似OCR扫描相机)
android
随心最为安11 小时前
Android Library Maven 发布完整流程指南
android
岁月玲珑11 小时前
【使用Android Studio调试手机app时候手机老掉线问题】
android·ide·android studio
还鮟15 小时前
CTF Web的数组巧用
android
小蜜蜂嗡嗡17 小时前
Android Studio flutter项目运行、打包时间太长
android·flutter·android studio
aqi0017 小时前
FFmpeg开发笔记(七十一)使用国产的QPlayer2实现双播放器观看视频
android·ffmpeg·音视频·流媒体