仿FlipBoard app效果1首页悬浮窗

三星以前的手机自带一个FlipBoard的app,就是个简报吧。在主页面手指右滑可以看到,新版本的samsung貌似取消这个app了,用bixby取代了。要看效果得去找个以前的samsung手机。
下图是仿照写的一个效果,有点粗糙。


device-2018-05-23-113305.gif

来几张图片

刚进去的效果如下图


image.png

稍微滚动下如下图


image.png

继续滚动
image.png

实现的思路

最上边应该就是个recyclerview,然后顶部带了个悬浮条。
根据上边的图片分下,
最下层一个relativelayout,里边是张图片,文字,然后我盖了个view,用来处理滑动的时候透明度变暗的效果,
在上层就是个recyclerview,最顶部来个悬浮条。
至于recyclerview,我是给第一个item加了个itemDecoration,offsetTop=底部那个relativelayout的高度。
分析完就开始代码实现功能了。
题外话,这里要处理悬浮窗高度的变化,字体的变化,第一个item的时候悬浮窗的特殊处理
先上布局文件




    
    

    
    
    

        
        
        
    

实体类就简单造了一个

data class BriefBean(var title:String,var newArticle: Int,var testContent:String,var color:Int)

item的布局



    
        
        
        
    
    

activity的代码如下

//我们顶部悬浮窗的高度是从150到50变化的,因为recyclerview里那个高度默认是150
    var minHeight=50//顶部悬浮窗的最小高度
    var maxHeigth=150//最大高度.和item里的顶部分类高度一样
    var originalHeigth=300//默认显示的底图的高度,也是recyclerview第一个item的itemDecoration的top的高度
    var datas= arrayListOf()
    private fun initRv(){
        datas.add(BriefBean("商业",8,"place holder business",Color.BLACK))
        datas.add(BriefBean("新闻",2,"place holder news",Color.RED))
        datas.add(BriefBean("科技",3,"place holder technology",Color.GREEN))
        datas.add(BriefBean("体育",6,"place holder sports",Color.BLUE))
        datas.add(BriefBean("娱乐",8,"place holder recreation",Color.YELLOW))
        rv_brief.apply {
            layoutManager=LinearLayoutManager(this@ActivityBriefSamsung)
            addItemDecoration(object :RecyclerView.ItemDecoration(){
                override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State?) {
                    var position=parent.getChildAdapterPosition(view)
                    if(position==0){
                        outRect.top=originalHeigth //只给第一个弄个偏移量,方便刚进去的时候能看到底部的图片文字
                    }
                }
            })
            adapter=object :BaseRvAdapter(datas){
                override fun getLayoutID(viewType: Int): Int {
                    return R.layout.item_brief_samsung
                }

                override fun onBindViewHolder(holder: BaseRvHolder, position: Int) {
                    var bean=getItemData(position)
                    holder.setText(R.id.tv_float_title,bean.title)
                    holder.setText(R.id.tv_float_sub_title,"${bean.newArticle} new articles")
                    holder.setText(R.id.tv_placeholder,bean.testContent)
                    holder.getView(R.id.layout_float_top).apply {
                        visibility=if(position==0) View.GONE else View.VISIBLE//第一个不显示顶部的分类条目的
                        setBackgroundColor(bean.color)
                    }
                }

            }
        }
        rv_brief.addOnScrollListener(object :RecyclerView.OnScrollListener(){
            override fun onScrollStateChanged(recyclerView: RecyclerView?, newState: Int) {
                super.onScrollStateChanged(recyclerView, newState)

            }
            override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
                super.onScrolled(recyclerView, dx, dy)
                 var manager=recyclerView.layoutManager as LinearLayoutManager
                var first=manager.findFirstVisibleItemPosition();
                var holder=recyclerView.findViewHolderForAdapterPosition(first)
                var firstTop=holder.itemView.top//第一个可见item的top,和屏幕顶部的距离
                var firstBottom=holder.itemView.bottom
                var layoutParams1=layout_float_top1.layoutParams//这个是顶部悬浮条的布局,因为滑动的时候要修改
                var data=datas[first]


                if(first==0){//第一条数据和后边有点区别,单独处理
                    if(firstTop>=minHeight){
                        layoutParams1.height=minHeight//刚开始的时候上边的标题也就文字从透明到不透明,而高度是没变化的,
                        layout_float_top1.setBackgroundColor(Color.TRANSPARENT)//背景开始是透明的
                        var alpha=1-(firstTop-minHeight)*1f/(originalHeigth-minHeight)//根据滑动距离来修改透明度。
                        tv_float_title1.alpha=alpha
                        view_mask.alpha=alpha
                        view_mask.y=firstTop-originalHeigth*1f
                        iv_top_.scrollTo(0,-(firstTop-originalHeigth)/2)//滚动底图,用实际的一半距离。
                    }else{
                        view_mask.y=-originalHeigth*1f//把mask这个view滚到屏幕外边去,免得影响
                        layout_float_top1.setBackgroundColor(data.color)/修改悬浮条颜色
                    }
                    tv_float_title1.setTextSize(TypedValue.COMPLEX_UNIT_SP,26f)//实际体验发现首个黑色的背景标题字体颜色比较大
                    tv_float_sub_title1.setText("")
                }else{

                    var changeHeight=maxHeigth+firstTop
                    layoutParams1.height=Math.max(changeHeight,minHeight)
                    //字体大小从18sp到15sp变化,而悬浮窗高度从maxheight到minHeight变化
                    tv_float_title1.setTextSize(TypedValue.COMPLEX_UNIT_SP,15f+3f*(layoutParams1.height-minHeight)/(maxHeigth-minHeight))
                    layout_float_top1.setBackgroundColor(data.color)
                    tv_float_sub_title1.setText("${data.newArticle} new articles")
                    tv_float_sub_title1.alpha=Math.max(0f,1-(maxHeigth-layoutParams1.height)/40f)//滑动个40dp就让子标题不可见
                }
                tv_float_title1.setText(data.title)
                if(firstBottom<=minHeight){//这里处理悬浮窗往上滚出屏幕的效果
                    layout_float_top1.y=firstBottom-minHeight*1f
                    layoutParams1.height=minHeight
                }else{
                    layout_float_top1.y=0f
                }
                layout_float_top1.layoutParams=layoutParams1
         
            }
        })

    }

你可能感兴趣的:(仿FlipBoard app效果1首页悬浮窗)