新浦京81707con > 首页 > 澳门新莆京4066com安卓标题栏随屏幕滑动改变颜色

原标题:澳门新莆京4066com安卓标题栏随屏幕滑动改变颜色

浏览次数:97 时间:2020-03-01

明日看来简书最版的觉察页面包车型地铁尾部动态效果不错,作者就想尝尝实现以下:先看贯彻的职能图:

前言

鉴于手提式有线电话机显示屏大小的限量,各类控件需求依据需求开展展现,隐敝,移动等,以充实视觉效果,顾客体验。就拿最近市情上布满的APP如天涯论坛、QQ、天猫、美团等来讲,在他们的APP里面四处可以看到一些相比赏心悦指标管理方案。本文重要将一些宽广的须求对控件举办显示、隐瞒、渐变的场地进行整合治理了一番。如:点击荧屏Toolbar,bottom的来得掩瞒;滑动Scrollview/Webview/Recyclerview展现掩饰,反射率渐变;Fab悬浮按键滑动缩放展现隐瞒(是通过自定义Behavior达成)小说原创,转发请评释地址:小嵩的CSDN博客,地址:http://blog.csdn.net/qq_22393017

鉴于完成方案超多,加上篇幅问题。那篇文章爱惜写了腾讯网效果的代码,Taobao/QQ空间标题渐变效果的别的写了一篇,地址:精仿天猫商城标题栏光滑度渐变效果。仿美团的效应demo还在宏观,持续立异中,应接商量沟通~

为了大家项目标美貌大家也许平时会遇见一些以为很高烧的主题材料,如标题所说正是一个,二个scrollView包裹的页面恐怕存在listView的页面往往要求在往上海好笑剧团动的时候标题栏达成悬浮並且背景颜色也要跟着转移。废话相当少说了,直接说怎么贯彻啊。

澳门新莆京4066com 1效果图.gif

成效预览

1.果壳网的标题栏和尾部栏突显掩盖:

澳门新莆京4066com 2

此处写图片描述

2.Tmall、QQ空间标题栏渐变:

澳门新莆京4066com 3

3.美团网,大众点评最上端悬浮:

澳门新莆京4066com 4

成效演示完了,那么接下去初始深入分析,钻探实现思路。

1.假若是scrollView包裹的页面,大家必要把scrollView和标题栏定义在对峙构造中,保险标题栏能够悬浮,listView也是同理。

必要解析

当一切页面包车型地铁轮播图部分上划消失的长河中,折射率会现出渐变的作用,同不平时候当整个覆灭也许全体显得的时候找寻框宽度动态变化。

思路

第1种-乐乎首页的功力

澳门新莆京4066com,落到实处方案比较多,这里就讲主要的三种思路:

一、通过监听Srcollview/Recyclerview等控件的滑行,获取Y轴的活动间距,然后推断是上海滑稽剧团依然下跌,对Header 和Footer进行安装显隐动漫。
  二、同样是透过监听控件的滑动事件,获取Y轴的移动间隔,但在监听回调方法中,则是通过View.setTranslationY()方法动态设置Header和Footer的活动间隔,何况增加多少个Header和Footer移动间距的阀值,最大移动间隔为不可以知道结束。
  三、通过Behavior 举行嵌套滑动来设置Header 和Footer的显得与潜伏,可用系统预设的,也可自定义,自定义的Behavior小说末尾有demo代码,可自行下载仿照效法。关于Behavior,不打听的话能够搜一下相关地点的学问补习一下引入链接:Android Behavior的介绍
这段时间推荐使用这种方案,但有些场景也许用Behavior不便利完结,如涉及到Headview Viewpager Fragment切换时,可参看笔者另一篇小说:
Viewpager Fragment Headview的实现

授人予鱼不及授人以渔,思路清楚了之后实际代码也很简短,后面两种方案独有正是经过监听荧屏大概控件滑动事件来对View举行拍卖,而Behavior也是因为根据开垦中通常索要管理各类控件的和煦,Google才推出了这一个谐和布局的方案。

第2种-天猫商城/QQ空间的效果与利益

即头部渐变的贯彻方案,其实原理是平等的。两个分别只是四个是活动,多个是光滑度变化。平移是经过View.setTranslationY()大概设置平移动漫的办法。渐变则是透过 View.setAlpha(阿尔法卡塔尔也许设置阿尔法动漫的点子。setAlpha(阿尔法卡塔尔国那个反射率的阿尔法值,能够是(底部已滑动间隔)/(尾部总中度)的比例,也得以仁慈依照业务需要改成任何的,百分比计算的参阅代码如下:

 float percent = (float)Math.abs(distance)/(float)Math.abs(mMinHeaderTranslation);
    //如果是设置背景透明度,则传入的参数是int类型,取值范围0-255
    //如果设置控件透明度,传入的参数是float类型,取值范围0.0-1.0
    //alpha 值越小越透明
    float falpha = 1-percent;
    int alpha = (int)(falpha * 255);

本人独立写了篇文章,仿天猫的功用,有意思味的话可活动到那边查看详细的情况:http://blog.csdn.net/qq_22393017/article/details/54602925

第3种-美团/大众点评的作用,有二种达成思路:

率先种是:通过两套结构,一套固定在头顶,一套嵌套在Scrollview里面,当滑动到需求悬浮之处时,通过addview 的办法将急需悬浮的控件增多到固定在头顶的容器里面。具体落实代码可参照这篇博客http://blog.csdn.net/xiaanming/article/details/17761431

此处自个儿就把思路说一下,看图:

澳门新莆京4066com 5

此地写图片描述

第三种是:Headview Scrollview 的布局,监听Scrollview的滑行,然后用接口回调,在Activity中对Headview设置View.setTranslationY(dy)方法,当滑动到须求悬浮的地点时,即高达阀值时,不再对Headview进行移动。

上海滑稽剧团的时候:

澳门新莆京4066com 6

这里写图片描述

下滑时:

澳门新莆京4066com 7

此地写图片描述

┈┈┈┈┈┈┈┈┈◆┈┈┈┈┈┈┈┈┈◆┈┈┈┈┈┈┈┈┈◆┈┈┈┈┈┈┈┈分隔线◆┈┈┈┈┈┈┈┈┈◆┈┈┈┈┈┈┈┈┈◆┈┈┈┈┈┈┈┈┈◆┈┈┈┈┈┈┈┈┈◆┈┈┈┈┈┈┈┈

思路讲授完了,没代码说个egg,so...小编整合了眨眼之间间,写了个demo,是有关果壳网首页标题栏,底部,Fab突显隐敝的,提供了:荧屏点击、webview、scrollview、recyclerview、MD 包自带behavior,自定义behavior的达成方案,可自动下载查看。

2.假若是scrollView我们需求用到onOverScrolled方法,不过那是一个protected方法,所以大家要通过自定义scrollView使用接口回调来促成,listView则供给利用的是onScroll方法,它相仿是八个protected方法,所以它的减轻思路和方面是相通的。

思路

从构造看,最外层是Scrollview和底部富含寻找框的构造,Scrollview里面包裹多个线性布局上下组织的结构,上边能够是ViewPager,下是滑动的Listview大概RecyclerView。1,布局如下:为了轻巧小编轮播图作者一直用了一个图片替代

<LinearLayout xmlns:androxmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><RelativeLayout android: android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"><!--自定义的ScrollView 包裹,轮播图和滑动列表--> <Myview.MyScrollView android: android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <!--轮播图--> <RelativeLayout android: android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:background="@color/colorPrimary"> <ImageView android:layout_width="match_parent" android:layout_height="200dp" android:scaleType="centerCrop" android:src="@drawable/wepp" /> </RelativeLayout> <android.support.v7.widget.RecyclerView android: android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="20dp"></android.support.v7.widget.RecyclerView> </LinearLayout> </Myview.MyScrollView> <!--承载搜索框的布局,是透明度渐变和搜索框动态变化的布局--> <RelativeLayout android: android:layout_width="match_parent" android:layout_height="50dp" android:background="#ffffff" android:orientation="vertical" android:visibility="visible"> <EditText android: android:layout_width="100dp" android:layout_height="30dip" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:layout_marginRight="10dp" android:background="@drawable/serch" android:drawableLeft="@mipmap/search" android:hint="搜索" android:padding="5dip" android:singleLine="true" android:textColorHint="#AAAAAA" android:textSize="14dip" /> </RelativeLayout></RelativeLayout></LinearLayout>

2,自定义的MyScrollView:解析,为何要自定义呢,为了博取滑动的Y轴的间隔,以此来和上边构造的承载轮播图的rlayout布局的平底距荧屏上面距实行比较,自定义的MyScrollView重写onScrollChanged这一个主意,然后加个回调方法OnScrollListener。就足以在Activity只怕Fragment中动态获取到滑动的离开Y了

public class MyScrollView extends ScrollView {private OnScrollListener onScrollListener;public MyScrollView(Context context, AttributeSet attrs) { super(context, attrs);}public void setOnScrollListener(OnScrollListener scrollListener) { this.onScrollListener = scrollListener;}@Overrideprotected void onScrollChanged(int l, int t, int oldl, int oldt) { super.onScrollChanged(l, t, oldl, oldt); if (onScrollListener!=null){ onScrollListener.onScrollChanged(l,t,oldl,oldt); }}public interface OnScrollListener { void onScrollChanged(int x, int y, int oldX, int oldY); } }

3,看在Activity中的管理Activty 世襲MyScrollView.OnScrollListener,重写onScrollChanged(int x, int y, int oldX, int oldY);此方法

public public class MainActivity extends BaseActivity implements MyScrollView.OnScrollListener{private EditText search_edit;private MyScrollView myScrollView;private int searchLayoutTop;//RelativeLayout search;RelativeLayout rlayout;private int rlayoutwidth;prvitate List<String> list;//假的数据源@Overridepublic void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); search_edit =  findViewById(R.id.search_edit); myScrollView = (MyScrollView)findViewById(R.id.myScrollView); search = (RelativeLayout) findViewById(R.id.search); rlayout = (RelativeLayout) findViewById(R.id.rlayout); recyclerview = (RecyclerView) findViewById(R.id.recyclerview); myScrollView.setOnScrollListener; list = new ArrayList<>(); search.getBackground().setAlpha; for (int i = 0; i < 100; i  ) { list.add("第"   i   "条数据"); } recyclerview . recyclerview.setLayoutManager(new LinearLayoutManager(getActivity; recyclerview.setAdapter()//适配器我就不写了,大家自己实现 } //这个方法可以在一开始启动时就获取控件的高度和宽度,如果直 接在onCreate()的方法中获取不到 @Overridepublic void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged; if (!hasFocus){ searchLayoutTop = rlayout.getBottom();//获取rlayout的布局的底部相对于整个布局的高度 rlayoutwidth = rlayout.getMeasuredWidth();//rlayout布局的宽度 }} @Overridepublic void onScrollChanged(int x, int y, int oldX, int oldY) { //变化率 float headHeight = rlayout.getMeasuredHeight() - search.getMeasuredHeight(); int alpha =   y / headHeight) * 255);//透明度变化速率 ViewGroup.LayoutParams lp = search_edit.getLayoutParams(); if (alpha >= 255){ alpha = 255; for (int i = 0; i < rlayoutwidth; i  ) { lp.width  = i/20; } } if (alpha <= 10){ alpha = 0; for (int i = rlayoutwidth; i > 0; i--) { lp.width -= i /20; } } search.getBackground().setAlpha; if (lp.width >= rlayoutwidth) lp.width = rlayoutwidth; if (lp.width <= 200) lp.width = 200; search_edit.setLayoutParams;}}

代码部分解读

小说就透过ScrollView的代码,演示一下微博首页的大要达成步骤,后边三种意义可依照思路完成,操作起来也轻易(小说尾部有demo下载链接)

Step one
自定义ScrollView,在 onScrollChanged 中增加接口的onScroll方法对其监听:

package com.hideorshowdemo.widget;

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

/**
 * TODO<自定义监听滑动的ScrollView>
 *
 * @author: 小嵩
 * @date: 2017/1/9 11:37
 */

public class ObservableScrollView extends ScrollView {

    private ScrollViewListener scrollViewListener = null;

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

    public ObservableScrollView(Context context, AttributeSet attrs,
                                int defStyle) {
        super(context, attrs, defStyle);
    }

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

    public void setOnScrollListener(ScrollViewListener scrollViewListener) {
        this.scrollViewListener = scrollViewListener;
    }

    @Override
    protected void onScrollChanged(int x, int y, int oldx, int oldy) {
        super.onScrollChanged(x, y, oldx, oldy);
        if (scrollViewListener != null) {

            if (oldy < y && ((y - oldy) > 15)) {// 滑动距离超过15像素,翻向底部,控件向上滑动
                scrollViewListener.onScroll(y - oldy);

            } else if (oldy > y && (oldy - y) > 15) {// 滑动距离超过15像素,向下滑动,翻向顶部
                scrollViewListener.onScroll(y - oldy);
            }

        }
    }

    public  interface ScrollViewListener{//dy Y轴滑动距离
         void onScroll(int dy);
    }
}

Step two
XML构造中援引自定义的ScrollView :

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">


    <LinearLayout
        android:id="@ id/content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">


   <com.hideorshowdemo.widget.ObservableScrollView
       android:id="@ id/scrollView"
       android:layout_width="match_parent"
       android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

       <include layout="@layout/empty_layout"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:padding="10dp"
            android:textSize="20dp"
            android:lineSpacingExtra="10dp"
            android:text="@string/TextContent"
            android:gravity="center"/>
    </LinearLayout>
   </com.hideorshowdemo.widget.ObservableScrollView>
</LinearLayout>

    <include layout="@layout/layout_toolbar"/>

    <LinearLayout
        android:id="@ id/lv_bottom"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_alignParentBottom="true">

        <include layout="@layout/layout_bottom"/>

    </LinearLayout>

</RelativeLayout>

Step three:
在Activity中起始化ScrollView,并促成接口回调方法:

package com.hideorshowdemo.activity;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;

import com.hideorshowdemo.R;
import com.hideorshowdemo.utils.HideAnimationUtils;
import com.hideorshowdemo.widget.ObservableScrollView;

import butterknife.Bind;
import butterknife.ButterKnife;
import butterknife.OnClick;

/**
 * TODO<ScrollView示例>
 *
 * @author: 小嵩
 * @date: 2017/1/9 11:24
 * @version: V1.0
 */

public class ScrollViewActivity extends AppCompatActivity {

    @Bind(R.id.iv_back)
    ImageView ivBack;
    @Bind(R.id.toolbar)
    Toolbar toolbar;
    @Bind(R.id.scrollView)
    ObservableScrollView scrollView;
    @Bind(R.id.lv_bottom)
    LinearLayout lvBottom;

    private boolean isShowing = true;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_scrollview);
        ButterKnife.bind(this);
        initView();
    }

    private void initView() {
        scrollView.setOnScrollListener(new ObservableScrollView.ScrollViewListener() {//滑动事件回调监听(一次滑动的过程会触发多次,通过isShowing来防止对头部和底部多次设置显示与隐藏)
            @Override
            public void onScroll(int dy) {
                if (dy > 0 && isShowing) {//手指往上滑,并且标题栏已经显示,则隐藏底部栏
                    isShowing = false;
                    new HideAnimationUtils(false, toolbar,lvBottom);
                } else if (dy <= 0 && !isShowing) {//往下滑,已隐藏,则显示
                    isShowing = true;
                    new HideAnimationUtils(true, toolbar,lvBottom);
                }
            }
        });
    }

    @OnClick(R.id.iv_back)
    public void OnClick(View v) {
        switch (v.getId()) {
            case R.id.iv_back:
                finish();
                break;
        }
    }


    @Override
    protected void onDestroy() {
        ButterKnife.unbind(this);
        super.onDestroy();
    }
}

里头HideAnimationUtils是本人封装的卡通片工具类,由于动漫效果是统一的,在各种Activity中调用,能裁减代码冗余,可机关依照供给变动或扬弃。

package com.hideorshowdemo.utils;

import android.view.View;
import android.view.animation.TranslateAnimation;


/**
 * TODO<标题栏动画显示隐藏的工具类>
 *
 * @author: 小嵩
 * @date: 2017/1/9 11:16
 * @version: V1.0
 */

public class HideAnimationUtils {

    private Boolean Show;
    private View view_title;
    private View view_bottom;

    public HideAnimationUtils(Boolean show, View title, View bottom) {
        this.Show = show;
        this.view_title = title;
        this.view_bottom = bottom;
        ShowOrHideTitle();
        ShowOrHideBottom();
    }

    private void ShowOrHideTitle(){//标题栏
        int fromY;//0表示控件Y轴起点
        int toY;//正值表示下移,负值上移
        if (Show) {//显示
            fromY = -view_title.getHeight();
            toY = 0;
        } else {//隐藏
            fromY = 0;
            toY = -view_title.getHeight();
        }
        final TranslateAnimation animation;//平移动画
        animation = new TranslateAnimation(0, 0, fromY, toY);
        animation.setDuration(400);//设置动画持续毫秒
        animation.setFillAfter(true);//动画执行完后是否停留在执行完的状态
        view_title.startAnimation(animation);
    }

    private void ShowOrHideBottom(){//底部栏
        int fromY;//0表示控件Y轴起点
        int toY;//正值表示下移,负值上移
        if (Show) {//显示
            fromY = view_bottom.getHeight();
            toY = 0;
        } else {//隐藏
            fromY = 0;
            toY = view_bottom.getHeight();
        }
        final TranslateAnimation animation;//平移动画
        animation = new TranslateAnimation(0, 0, fromY, toY);
        animation.setDuration(400);//设置动画持续毫秒
        animation.setFillAfter(true);//动画执行完后是否停留在执行完的状态
        view_bottom.startAnimation(animation);
    }
}

居功至伟告成,效果如下:

澳门新莆京4066com 8

效果图

点击显示屏呈现隐讳效果:

澳门新莆京4066com 9

此处写图片描述

自定义Behavior,完结滑动时fab悬浮按键缩放的遵循:

澳门新莆京4066com 10

此处写图片描述

GitHub地址:仿今日头条首页标题展现隐瞒demo
GitHub地址:TitlebarGradient-天猫商城购物详细情形页标题栏渐变

3.亮堂改怎么调用监听方法了就足以来成功效能的完毕,原理其实也相当粗略,正是监听滑动的可观来给标题栏设定分歧的背景象,当然也得以做更加多的事务。下边就二种分别把关键代码放在下边。

主要解析onScrollChanged(卡塔尔(قطر‎方法
 @Overridepublic void onScrollChanged(int x, int y, int oldX, int oldY) { //变化率 float headHeight = rlayout.getMeasuredHeight() - search.getMeasuredHeight(); int alpha =   y / headHeight) * 255);//透明度变化速率 ViewGroup.LayoutParams lp = search_edit.getLayoutParams(); if (alpha >= 255){ alpha = 255; for (int i = 0; i < rlayoutwidth; i  ) { lp.width  = i/20; } } if (alpha <= 10){ alpha = 0; for (int i = rlayoutwidth; i > 0; i--) { lp.width -= i /20; } } search.getBackground().setAlpha;//设置透明度 if (lp.width >= rlayoutwidth) lp.width = rlayoutwidth; if (lp.width <= 200) lp.width = 200; search_edit.setLayoutParams;//设置搜索框的宽度}

y能够自页面滑动的时候取获得,反射率渐变和找出框动态变化的依靠规范是:

 float headHeight = rlayout.getMeasuredHeight() - search.getMeasuredHeight();//变化的距离 int alpha =   y / headHeight) * 255);//透明度变化速率

什么样看头呢:我们思量,当前滚动的ScrollView的Y值去减去这一个headHeight,那几个间距值只同意他在headHeight的万丈去变通,假若ScrollView滑动的离开超越那些高度的话,那么大家从来设置alpha为255一贯体现变透明,倘使这些ScrollView滑动的到顶端时,大家一向设置阿尔法为0为透明,咱们率先获得那几个变化的离开,然后去除以那一个headHeight中度取得这几个比例,然后去乘上255获得同样比例中的发光度的值,记得那个数值都得是float类型,中度也是,假设int的话那样相除的话就形成0了。

a.ScrollView

有人疑问了那只是发光度的变化为找寻框的扭转也要依据那么些呢

请看:此方法是在代码中动态设置组件的增长幅度的不二等秘书诀

ViewGroup.LayoutParams lp = search_edit.getLayoutParams(); lp.width =10;search_edit.setLayoutParams

看注释:

 ViewGroup.LayoutParams lp = search_edit.getLayoutParams(); if (alpha >= 255){//这个执行时正是rlayout布局即轮播图父布局 全部隐藏的时候,当然这个时候搜索框是要进行变化的 alpha = 255; //这个循环的方法是动态搜索框的关键,可以重新改变搜索框的 变化的速率 for (int i = 0; i < rlayoutwidth; i  ) { lp.width  = i/20; } } if (alpha <= 10){//这个执行时正是rlayout布局即轮播图 父布局全部显示的时候,当然这个时候搜索框也是要进行变化的 alpha = 0; //这个循环的方法是动态搜索框的关键,可以重新改变搜索框的变化的速率 for (int i = rlayoutwidth; i > 0; i--) { lp.width -= i /20; } } search.getBackground().setAlpha;//设置透明度 if (lp.width >= rlayoutwidth) lp.width = rlayoutwidth; if (lp.width <= 200) lp.width = 200; search_edit.setLayoutParams;//设置搜索框的宽度

好了,以上的思路大约正是那般的,至于小说中的代码,有个别不全,因为笔者是在Fragment中搞的,小说中为了通俗一点自家一贯手敲的MainActivity 。注意在Fragment中从未那么些方法onWindowFocusChanged(),不过也许有一个格局能够拿走到构件间隔显示屏的相距,宽高档,请看:

Observer observer = rlayout.getViewTreeObserver(); observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { searchLayoutTop = rlayout.getBottom();//获取rlayout的布局的底部相对于整个布局的高度 searchwidth = search_edit.getMeasuredWidth(); rlayoutwidth = rlayout.getMeasuredWidth(); return true; } });

1State of Qatar.首先自定义接口

public interface ScrollViewListener {
    void onScrollChanged(int scrollX, int scrollY, boolean clampedX, boolean clampedY);
}
2卡塔尔(قطر‎自定义scrollView,完毕接口的回调

本文由新浦京81707con发布于首页,转载请注明出处:澳门新莆京4066com安卓标题栏随屏幕滑动改变颜色

关键词: 新浦京81707con Android... 透明度 头部 效果

上一篇:澳门新萄京客户端下载:这10款写作软件总有一款

下一篇:没有了