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

学向勤中得,萤窗万卷书。这篇文章主要讲述Android 沉浸式状态栏及悬浮效果相关的知识,希望能为你提供帮助。

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

文章图片

三、我们的效果
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距离多高开始悬浮
【Android 沉浸式状态栏及悬浮效果】我们通过监听ScrollView滑动距离来不断改变我们标题栏跟状态栏的透明度来达到效果, 在这里我们计算了几个高度( 滑动距离) 。最后来算出滑动总距离, 根据滑动的距离跟滑动的总距离来算出透明度的数值。
StatusBarUtil.setTranslucentForImageView(MainActivity.this, 0, title); 我们通过工具来实现图片深入状态栏。里面的传的View是图片下面的View。
六、总结
效果倒是不错, 美女也不错、但是在Android4.4之前根本就没有沉浸式这个东西, 大家可以下载源码来研究。自己动手实现一遍记得比较清楚。工作了。太忙了。最后感谢一下dota群的高叔(博客地址不知道)提供思路。
七、源码
csdn下载
githu下载
八、欢迎大家访问我的网站和我的公众号
极客导航—程序员自己的导航网站
极客导航
欢迎关注我的公众号
Android 沉浸式状态栏及悬浮效果

文章图片


    推荐阅读