Android 沉浸式状态栏及悬浮效果

转载请注明出处 http://blog.csdn.net/xiaoyuan511

一、概述

现在大多数的电商APP的详情页长得几乎都差不多,几乎都是上面一个商品的图片,当你滑动的时候,会有Tab悬浮在上面,这样做用户体验确实不错,如果Tab滑上去,用户可能还需要滑下来,在来点击Tab,这样确实很麻烦。沉浸式状态栏那,郭霖说过谷歌并没有给出沉浸式状态栏这个明白,谷歌只说了沉浸式模式(Immersive Mode)。不过沉浸式状态栏这个名字其实听不粗,随大众吧,但是Android的环境并没有IOS环境一样特别统一,比如华为rom的跟小米rom的虚拟按键完全不一样,所有Android开发者不容易。。。。。

二、淘宝的效果

三、我们的效果

只能传2M,把我的美女都给压失真了。。。。。。

四、实现类

  • 自定义ScrollView (StickyScrollView)
  • StatusBarUtil //非常不错的状态栏工具

五、布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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">

<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.xiaoyuan.StickyScrollView
        android:id="@+id/scrollView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:focusable="true"
        android:focusableInTouchMode="true">

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

            <ImageView
                android:layout_width="match_parent"
                android:layout_height="500dip"
                android:background="@mipmap/meinv"/>

            <TextView
                android:id="@+id/title"
                android:layout_width="match_parent"
                android:layout_height="50dp"
                android:gravity="center"
                android:text="美" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="50dip"
                android:gravity="center"
                android:text="女"/>

            <TextView
                android:layout_width="match_parent"
                android:layout_height="50dip"
                android:gravity="center"
                android:text="美"/>
            <TextView
                android:layout_width="match_parent"
                android:layout_height="50dip"
                android:gravity="center"
                android:text="不"/>
            <TextView
                android:layout_width="match_parent"
                android:layout_height="50dip"
                android:gravity="center"
                android:text="美"/>

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

                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="45dp"
                    android:background="#ffffff"
                    android:orientation="horizontal">

                    <TextView
                        android:id="@+id/infoText"
                        android:layout_width="0dp"
                        android:layout_height="match_parent"
                        android:layout_weight="1"
                        android:gravity="center"
                        android:text="美女信息"
                        android:textColor="#000000"
                        android:textSize="16dp" />

                    <TextView
                        android:id="@+id/secondText"
                        android:layout_width="0dp"
                        android:layout_height="match_parent"
                        android:layout_weight="1"
                        android:gravity="center"
                        android:text="美女介绍"
                        android:textColor="#000000"
                        android:textSize="16dp" />
                </LinearLayout>
            </LinearLayout>

            <FrameLayout
                android:id="@+id/tabMainContainer"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="#ffffff"
                android:minHeight="400dp">

            </FrameLayout>
        </LinearLayout>
    </com.xiaoyuan.StickyScrollView>

    <RelativeLayout
        android:id="@+id/ll_good_detail"
        android:layout_width="match_parent"
        android:layout_height="49dp"
        android:background="#00000000"
        android:paddingTop="@dimen/spacing_normal">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="#ffffff"
            android:layout_alignParentLeft="true"
            android:layout_marginLeft="10dip"
            android:layout_centerHorizontal="true"
            android:text="返回"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="#ffffff"
            android:layout_centerInParent="true"
            android:layout_centerHorizontal="true"
            android:layout_marginLeft="10dip"
            android:text="美女"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="#ffffff"
            android:layout_alignParentRight="true"
            android:layout_marginRight="10dip"
            android:layout_centerHorizontal="true"
            android:text="分享"/>

    </RelativeLayout>

</FrameLayout>

</RelativeLayout>

注意:我们把要悬浮的Tab设置了android:tag=”sticky”这样的属性

六、实现代码

public class MainActivity extends AppCompatActivity implements View.OnClickListener, StickyScrollView.OnScrollChangedListener {

TextView oneTextView, twoTextView;
private StickyScrollView stickyScrollView;
private int height;
private LinearLayout llContent;
private RelativeLayout llTitle;
private FrameLayout frameLayout;
private TextView title;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    initView();
    initListeners();

}

/**
 * 初始化View
 */
private void initView() {
    stickyScrollView = (StickyScrollView) findViewById(R.id.scrollView);
    frameLayout = (FrameLayout) findViewById(R.id.tabMainContainer);
    title = (TextView) findViewById(R.id.title);
    oneTextView = (TextView) findViewById(R.id.infoText);
    llContent = (LinearLayout) findViewById(R.id.ll_content);
    llTitle = (RelativeLayout) findViewById(R.id.ll_good_detail);
    oneTextView.setOnClickListener(this);
    twoTextView = (TextView) findViewById(R.id.secondText);
    twoTextView.setOnClickListener(this);

    stickyScrollView.setOnScrollListener(this);
    StatusBarUtil.setTranslucentForImageView(MainActivity.this, 0, title);
    FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) llTitle.getLayoutParams();
    params.setMargins(0, getStatusHeight(), 0, 0);
    llTitle.setLayoutParams(params);

    //默认设置一个Frg
    getSupportFragmentManager().beginTransaction().replace(R.id.tabMainContainer, Fragment.newInstance()).commit();
}

/**
 * 获取状态栏高度
 * @return
 */
private int getStatusHeight() {
    int resourceId = MainActivity.this.getResources().getIdentifier("status_bar_height", "dimen", "android");
    return getResources().getDimensionPixelSize(resourceId);

}

@Override
public void onClick(View v) {
    if (v.getId() == R.id.infoText) {
        getSupportFragmentManager().beginTransaction().replace(R.id.tabMainContainer, Fragment.newInstance()).commit();
    } else if (v.getId() == R.id.secondText) {
        getSupportFragmentManager().beginTransaction().replace(R.id.tabMainContainer, Fragment1.newInstance()).commit();

    }
}

private void initListeners() {
    //获取内容总高度
    final ViewTreeObserver vto = llContent.getViewTreeObserver();
    vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            height = llContent.getHeight();
            //注意要移除
            llContent.getViewTreeObserver()
                    .removeGlobalOnLayoutListener(this);

        }
    });

    //获取Fragment高度
    ViewTreeObserver viewTreeObserver = frameLayout.getViewTreeObserver();
    viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            height = height - frameLayout.getHeight();
            //注意要移除
            frameLayout.getViewTreeObserver()
                    .removeGlobalOnLayoutListener(this);
        }
    });

    //获取title高度
    ViewTreeObserver viewTreeObserver1 = llTitle.getViewTreeObserver();
    viewTreeObserver1.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            height = height - llTitle.getHeight() - getStatusHeight();//计算滑动的总距离
            stickyScrollView.setStickTop(llTitle.getHeight() + getStatusHeight());//设置距离多少悬浮
            //注意要移除
            llTitle.getViewTreeObserver()
                    .removeGlobalOnLayoutListener(this);
        }
    });

}

@Override
public void onScrollChanged(int l, int t, int oldl, int oldt) {
    if (t <= 0) {
        llTitle.setBackgroundColor(Color.argb((int) 0, 255, 255, 255));
        StatusBarUtil.setTranslucentForImageView(MainActivity.this, 0, title);
    } else if (t > 0 && t <= height) {
        float scale = (float) t / height;
        int alpha = (int) (255 * scale);
        llTitle.setBackgroundColor(Color.argb((int) alpha, 227, 29, 26));//设置标题栏的透明度及颜色
        StatusBarUtil.setTranslucentForImageView(MainActivity.this, alpha, title);//设置状态栏的透明度
    } else {
        llTitle.setBackgroundColor(Color.argb((int) 255, 227, 29, 26));
        StatusBarUtil.setTranslucentForImageView(MainActivity.this, 255, title);
    }
}
 }

注意:stickyScrollView.setStickTop(int height)我们通过这个方法可以设置Tab距离多高开始悬浮

我们通过监听ScrollView滑动距离来不断改变我们标题栏跟状态栏的透明度来达到效果,在这里我们计算了几个高度(滑动距离)。最后来算出滑动总距离,根据滑动的距离跟滑动的总距离来算出透明度的数值。

StatusBarUtil.setTranslucentForImageView(MainActivity.this, 0, title);我们通过工具来实现图片深入状态栏。里面的传的View是图片下面的View。

六、总结

效果倒是不错,美女也不错、但是在Android4.4之前根本就没有沉浸式这个东西,大家可以下载源码来研究。自己动手实现一遍记得比较清楚。工作了。太忙了。最后感谢一下dota群的高叔(博客地址不知道)提供思路。

七、源码

csdn下载

githu下载

八、欢迎大家访问我的网站和我的公众号

极客导航—程序员自己的导航网站

极客导航

程序猿那点事—程序员的心灵港湾

时间: 2024-08-25 07:14:27

Android 沉浸式状态栏及悬浮效果的相关文章

Android 沉浸式状态栏

效果图 android 5.0 以上 android 4.4 API 19 以上都是原生安卓系统的效果,具体到国内的各种各样改过的系统可能会有细微差别,测试过小米和华为的机器效果基本一样. 实现 1.修改主题属性 方法一: 在values-v19文件夹下声明AppTheme为透明状态栏,代码如下 1 <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"> 2 <!-- C

Android沉浸式状态栏 + scrollView顶部伸缩 + actionBar渐变

最近需求要做一个拉缩渐变的状态栏,往上拉的时候,需要显示actionBar,这个过程是渐变的,顶部的图片背景能实现拉缩,并且还要实现状态栏沉浸式 效果如如下: 实现状态栏的透明化 实现ScrollView的拉缩 实现ActionBar的渐变 实现 1.至于试下实现ScrollView的拉缩这个效果很简单重写onTouchEvent方法,利用滑动的垂直方向的距离,然后在设置图片的大小 这里要注意的是:在手指释放的时候需要进行恢复图片的高度如果有兴趣的话可以加入Android工程师交流Q群:7520

Android 沉浸式状态栏 实现方式二 ( 更简单 )

以前写过一个沉浸式状态栏 的实现方式 Android 沉浸式状态栏 实现方式一 现在有个更为简单的实现方式 . 相关链接 http://www.apkbus.com/forum.php?mod=viewthread&tid=255929&extra=page%3D3%26filter%3Dsortid%26orderby%3Ddateline%26sortid%3D12 1.效果图 demo 的 github 地址  https://github.com/zyj1609wz/Android

【Android实战】Android沉浸式状态栏实现(下)

之前的Android沉浸式状态栏实现并没有考虑软键盘的影响,接下来的内容将会针对这个问题给出解决方式,先看一下效果图 这个是一个留言板的效果图: 即弹出软键盘的时候并不会导致整个布局上移. 详细怎样实现?依照下面步骤进行设置: 1.布局文件里声明例如以下 <activity android:name="com.storm.durian.activity.LeaveMessageDetailsActivity" android:screenOrientation="por

android沉浸式状态栏实现

传统的手机状态栏是呈现出黑色条状的,有的和手机主界面有很明显的区别.这样就在一定程度上牺牲了视觉宽度,界面面积变小. 沉浸模式的状态栏和主界面完全融为了一体,在设计上有不同的视觉感受. 我们先上两张图,很容易看出区别:        Android在4.4的时候增加了透明状态栏与导航栏的功能,依托于这个新特性,我们可以开始跟随潮流,实现Android的沉浸式状态栏 其实上图展示的这个关于界面的代码非常简单 /** * 关于界面 * * @author SuS * @time 2015.07.29

教程分享:如何实现Android沉浸式状态栏——教你让你的状态栏变个色!

一.概述 近期注意到QQ新版使用了沉浸式状态栏,ok,先声明一下:本篇博客效果下图: 关于这个状态栏变色到底叫「Immersive Mode」/「Translucent Bars」有兴趣可以去了解下. 恩,接下来正题. 首先只有大于等于4.4版本支持这个半透明状态栏的效果,但是4.4和5.0的显示效果有一定的差异,所有本篇博文内容为: 如何实现半透明状态栏效果在大于4.4版本之上. 如何让4.4的效果与5.0的效果尽可能一致. 看了不少参考文章,都介绍到这个库,大家可以了解:SystemBarT

Android 沉浸式状态栏攻略 让你的状态栏变色吧

转载请标明出处: http://blog.csdn.net/lmj623565791/article/details/48649563: 本文出自:[张鸿洋的博客] 一.概述 近期注意到QQ新版使用了沉浸式状态栏,ok,先声明一下:本篇博客效果下图: 关于这个状态栏变色到底叫「Immersive Mode」/「Translucent Bars」有兴趣可以去 为什么在国内会有很多用户把 ?透明栏?(Translucent Bars)称作 ?沉浸式顶栏??上面了解了解,请勿指点我说的博文标题起得不对

android 沉浸式状态栏(像ios那样的状态栏与应用统一颜色样式)

这个特性是andorid4.4支持的,最少要api19才干够使用.以下介绍一下使用的方法,很得简单: 添加一个demo源代码: https://github.com/ws123/StatusDemo public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setCon

android沉浸式状态栏、变色状态栏、透明状态栏、修改状态栏颜色及透明

首先我要区分清楚沉浸式状态栏与变色状态栏. 沉浸式状态栏指的是,状态栏隐藏,在手指做了相关操作后,状态栏显示出来,例如视频播放器,在播放视频时是隐藏状态栏的,但是点击屏幕的时候,状态栏会显示出来,再例如文本阅读器,在阅读的时候是全屏的,然后从屏幕上方下滑或者下方上划,虚拟键和状态栏出现了,但却是直接覆盖在程序文字上的,这是所谓的沉浸式状态栏. 那么大家平时所说的状态栏与导航栏颜色相同,或者透明,指的是变色状态栏,或者透明状态栏. 对于这两个概念的理解,大家可以参考http://www.andro