美文网首页
仿FlipBoard app效果1首页悬浮窗

仿FlipBoard app效果1首页悬浮窗

作者: 有点健忘 | 来源:发表于2018-05-23 17:45 被阅读41次

三星以前的手机自带一个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的时候悬浮窗的特殊处理
先上布局文件

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
<RelativeLayout
    android:id="@+id/layout_top_bg"
    android:layout_width="match_parent"
    android:layout_height="300dp">
    <ImageView
        android:id="@+id/iv_top_"
        android:src="@mipmap/pic11"
        android:scaleType="fitXY"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    <TextView
        android:id="@+id/tv_title"
        android:textColor="#fff"
        android:textSize="20sp"
        android:textStyle="bold"
        android:layout_alignParentBottom="true"
        android:text="title................title..........title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</RelativeLayout>
    <android.support.v7.widget.RecyclerView
        android:id="@+id/rv_brief"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
    <View
        android:id="@+id/view_mask"
        android:background="#000000"
        android:alpha="0.0"
        android:layout_width="match_parent"
        android:layout_height="300dp"/>
    <RelativeLayout
        android:id="@+id/layout_float_top1"
        android:layout_width="match_parent"
        android:layout_height="50dp">

        <ImageView
            android:id="@+id/iv_3dot1"
            android:layout_alignParentRight="true"
            android:layout_margin="3dp"
            android:src="@android:drawable/ic_input_add"
            android:layout_width="44dp"
            android:layout_height="44dp" />
        <TextView
            android:id="@+id/tv_float_title1"
            android:text="商业"
            android:textSize="26sp"
            android:textColor="#fff"
            android:layout_centerInParent="true"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        <TextView
            android:id="@+id/tv_float_sub_title1"
            android:text="8 articles"
            android:textColor="#fff"
            android:textSize="13sp"
            android:layout_alignParentBottom="true"
            android:layout_marginBottom="10dp"
            android:layout_centerHorizontal="true"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    </RelativeLayout>
</FrameLayout>

实体类就简单造了一个

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

item的布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <RelativeLayout
        android:id="@+id/layout_float_top"
        android:layout_width="match_parent"
        android:layout_height="150dp">
        <ImageView
            android:id="@+id/iv_3dot"
            android:layout_alignParentRight="true"
            android:layout_margin="3dp"
            android:src="@android:drawable/ic_input_add"
            android:layout_width="46dp"
            android:layout_height="46dp" />
        <TextView
            android:id="@+id/tv_float_title"
            android:text="title"
            android:textSize="18sp"
            android:textColor="#fff"
            android:layout_centerInParent="true"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        <TextView
            android:id="@+id/tv_float_sub_title"
            android:text="8 articles"
            android:textColor="#fff"
            android:textSize="13sp"
            android:layout_alignParentBottom="true"
            android:layout_marginBottom="10dp"
            android:layout_centerHorizontal="true"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    </RelativeLayout>
    <TextView
        android:id="@+id/tv_placeholder"
        android:text="place holder"
        android:gravity="center"
        android:background="#ffffff"
        android:layout_width="match_parent"
        android:layout_height="530dp" />
</LinearLayout>

activity的代码如下

//我们顶部悬浮窗的高度是从150到50变化的,因为recyclerview里那个高度默认是150
    var minHeight=50//顶部悬浮窗的最小高度
    var maxHeigth=150//最大高度.和item里的顶部分类高度一样
    var originalHeigth=300//默认显示的底图的高度,也是recyclerview第一个item的itemDecoration的top的高度
    var datas= arrayListOf<BriefBean>()
    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<BriefBean>(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<View>(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首页悬浮窗

      本文链接:https://www.haomeiwen.com/subject/utqdjftx.html