上滑标题栏渐变效果

Android仿京东的上滑标题栏渐变效果

最近闲来无事,看到京东的的上滑标题栏渐变显示,下滑标题栏渐变消失的效果有些好奇,个人感觉这种效果很Butf,so自己尝试写了一下,先看一下京东的效果图:

这里写图片描述
这里写图片描述

先说一下整体思路吧

  1. 除了ToolBar(也就是上面的标题栏) 被一个ScrollView包起来。
  2. 监听活动距离
  3. 根据距离设置标题栏的透明度

好啦,整体思路说完我们就开始说实现吧

实现

  1. 布局文件编写:

首先是FrameLayout 作为大的父布局,然后是内容区域和A标题栏,内容区域使用ScrollView包起来,如果标题栏上有设置和消息的小图标就在写一个B标题栏 与A标题栏位置相同即可了(因为上滑的时候标题栏透明,而图标是要显示的,如果图标和A标题栏都写在一起会发现 如果标题栏透明则图标也会透明了,也就不显示了。)

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
  >

    <com.lnhx.sky.jdscrolltoobardemo.view.ScrollTopView
        android:id="@+id/content"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            >
            <ImageView
                android:layout_width="match_parent"
                android:layout_height="200dp"
                android:background="@color/colorAccent"
                />
            <ImageView
                android:layout_width="match_parent"
                android:layout_height="1000dp"
                android:background="@color/colorPrimary"
                />
        </LinearLayout>
    </com.lnhx.sky.jdscrolltoobardemo.view.ScrollTopView>
    <RelativeLayout
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:background="#ffffff"
        android:layout_gravity="top"
        android:layout_height="50dp">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/app_name"
            android:textColor="@color/colorAccent"
            android:layout_centerInParent="true"
            android:textSize="15sp" />
    </RelativeLayout>
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="50dp">
        <LinearLayout
            android:layout_width="wrap_content"
            android:orientation="horizontal"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_alignParentRight="true"
            android:layout_marginRight="15dp"
            >
            <ImageView
                android:id="@+id/set"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@drawable/set_icon"
                android:layout_marginRight="15dp"
                />
            <ImageView
                android:id="@+id/mes"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@drawable/mes_icon"
                />

        </LinearLayout>
    </RelativeLayout>
</FrameLayout>

效果图如下

这里写图片描述

2.自定义ScrollView

创建类继承ScrollView,实现构造方法,重写onScrollChanged方法,定义OnScrollLLinserener接口,接口中只有一个方法 void scroll(ScrollTopView topView,int l, int t, int oldl, int oldt)。OnScrollLLinserener的set方法。

 package com.lnhx.sky.wbsportgradedemo.view;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.ScrollView;

/**
 * Created by Sky on 2017-5-22.
 */

public class ScrollTopView extends ScrollView {


    private OnScrollLLinserener onScrollLLinserener;//回调接口标量
    private float startY;//手指按下的Y
    private float scrollY;//手指移动的Y

    public ScrollTopView(Context context) {
        super(context);
    }

    public ScrollTopView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public ScrollTopView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public void setOnScrollLLinserener(OnScrollLLinserener onScrollLLinserener)//初始化onScrollLLinserener

    {
        this.onScrollLLinserener = onScrollLLinserener;
    }



    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        if (onScrollLLinserener!=null)
        {
            this.onScrollLLinserener.scroll( this, l,  t,  oldl,  oldt);//根据OnScrollLLinserener判断如果不为空,则调用接口的scrolll函数,scroll函数会在Activity中实现
        }



    }

    public   interface OnScrollLLinserener{
       /*
       * 用于回调的接口
       * */
        void scroll(ScrollTopView topView,int l, int t, int oldl, int oldt);
    }
}

**注意:如果你觉为什么要这么麻烦获取空间高度呢,直接用 getHeight()方法不行吗,楼主之前也曾被坑,后来度娘告诉我不行,如果直接用getHeight获取高度,则是0。再次附上参考链接http://www.cnblogs.com/yxwkf/p/5221684.html 不明白的去看看吧。

2.为我们自定义的ScrollView设置OnScrollLLinserener监听,并实现scroll方法

 content = (ScrollTopView) findViewById(R.id.content);
        content.setOnScrollLLinserener(new ScrollTopView.OnScrollLLinserener() {
            @Override
            public void scroll(ScrollTopView topView,int l, int t, int oldl, int oldt) {

            }
        });

重点内容
3.在scroll方法中根据startY、scrollY、和控件高度来实现效果吧
首先我们根据oldt获取互动距离因为我们是上滑实现。然后,我们根据屏幕高度的1/3和滑动距离比较,当toolbarhight >=scrollDis时,我们获取scrollDis与toolBarr比,(因为toolBar的渐变的透明度是与互动的距离相关的) 得到比例来设置toolBar的透明度。然后看代码吧,

content.setOnScrollLLinserener(new ScrollTopView.OnScrollLLinserener() {
            @Override
             public void scroll(ScrollTopView topView,int l, int t, int oldl, int oldt) {
                 scrollDis = oldt;

                  if ( (toolbarhight/3f) >= scrollDis) {
                    float alp = scrollDis / (toolbarhight/3f);
                    toolbar.setAlpha(alp);
                }

            }
        });

但是,我们会看到也是我上文提到的,标题栏上有设置和消息的图标,他们是不透明的,而且会根据标题栏的出现改变颜色。所以我们这样做:

 if (alp<=0.5){
    set.setImageResource(R.drawable.set_icon);
     mes.setImageResource(R.drawable.mes_icon);
  }else{
  set.setImageResource(R.drawable.set_icon_se);
  mes.setImageResource(R.drawable.mes_icon_se);
 }

现在大概讲清楚了:Activity的总体代码是这样的

public class MainActivity extends AppCompatActivity {

    private RelativeLayout toolbar;


    private ScrollTopView content;
    private float toolbarhight;
    private ImageView set,mes;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initView();
    }
    private void initView() {

        toolbar = (RelativeLayout) findViewById(R.id.toolbar);
        set = (ImageView) findViewById(R.id.set);
        mes = (ImageView) findViewById(R.id.mes);
        toolbar.setAlpha(0);
        content = (ScrollTopView) findViewById(R.id.content);

          toolbarhight = getResources().getDisplayMetrics().heightPixels;
        content.setOnScrollLLinserener(new ScrollTopView.OnScrollLLinserener() {
            @Override
            public void scroll(float startY, float scrollY) {

                 scrollDis = oldt;

                  if ( (toolbarhight/3f) >= scrollDis) {
                    float alp = scrollDis / (toolbarhight/3f);
                    toolbar.setAlpha(alp);
                    if (alp<=0.5)
                    {
                        set.setImageResource(R.drawable.set_icon);
                        mes.setImageResource(R.drawable.mes_icon);
                    }else
                    {
                        set.setImageResource(R.drawable.set_icon_se);
                        mes.setImageResource(R.drawable.mes_icon_se);
                    }
                }

            }
        });

    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值