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

一、概述

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

二、淘宝的效果

三、我们的效果

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

四、实现类

自定义ScrollView (StickyScrollView)

StatusBarUtil //非常不错的状态栏工具

五、布局

  1. <?xml version=“1.0” encoding=“utf-8”?>
  2. <RelativeLayout xmlns:android=“http://schemas.android.com/apk/res/android”
  3. xmlns:tools=“http://schemas.android.com/tools”
  4. android:layout_width=“match_parent”
  5. android:layout_height=“match_parent”>
  6. <FrameLayout
  7.     android:layout_width=“match_parent”
  8.     android:layout_height=“match_parent”>
  9.     <com.xiaoyuan.StickyScrollView
  10.         android:id=“@+id/scrollView”
  11.         android:layout_width=“match_parent”
  12.         android:layout_height=“match_parent”
  13.         android:focusable=“true”
  14.         android:focusableInTouchMode=“true”>
  15.         <LinearLayout
  16.             android:id=“@+id/ll_content”
  17.             android:layout_width=“match_parent”
  18.             android:layout_height=“match_parent”
  19.             android:orientation=“vertical”>
  20.             <ImageView
  21.                 android:layout_width=“match_parent”
  22.                 android:layout_height=“500dip”
  23.                 android:background=“@mipmap/meinv”/>
  24.             <TextView
  25.                 android:id=“@+id/title”
  26.                 android:layout_width=“match_parent”
  27.                 android:layout_height=“50dp”
  28.                 android:gravity=“center”
  29.                 android:text=“美” />
  30.             <TextView
  31.                 android:layout_width=“match_parent”
  32.                 android:layout_height=“50dip”
  33.                 android:gravity=“center”
  34.                 android:text=“女”/>
  35.             <TextView
  36.                 android:layout_width=“match_parent”
  37.                 android:layout_height=“50dip”
  38.                 android:gravity=“center”
  39.                 android:text=“美”/>
  40.             <TextView
  41.                 android:layout_width=“match_parent”
  42.                 android:layout_height=“50dip”
  43.                 android:gravity=“center”
  44.                 android:text=“不”/>
  45.             <TextView
  46.                 android:layout_width=“match_parent”
  47.                 android:layout_height=“50dip”
  48.                 android:gravity=“center”
  49.                 android:text=“美”/>
  50.             <LinearLayout
  51.                 android:layout_width=“match_parent”
  52.                 android:layout_height=“wrap_content”
  53.                 android:orientation=“vertical”
  54.                 android:tag=“sticky”>
  55.                 <LinearLayout
  56.                     android:layout_width=“match_parent”
  57.                     android:layout_height=“45dp”
  58.                     android:background=“#ffffff”
  59.                     android:orientation=“horizontal”>
  60.                     <TextView
  61.                         android:id=“@+id/infoText”
  62.                         android:layout_width=“0dp”
  63.                         android:layout_height=“match_parent”
  64.                         android:layout_weight=“1”
  65.                         android:gravity=“center”
  66.                         android:text=“美女信息”
  67.                         android:textColor=“#000000”
  68.                         android:textSize=“16dp” />
  69.                     <TextView
  70.                         android:id=“@+id/secondText”
  71.                         android:layout_width=“0dp”
  72.                         android:layout_height=“match_parent”
  73.                         android:layout_weight=“1”
  74.                         android:gravity=“center”
  75.                         android:text=“美女介绍”
  76.                         android:textColor=“#000000”
  77.                         android:textSize=“16dp” />
  78.                 </LinearLayout>
  79.             </LinearLayout>
  80.             <FrameLayout
  81.                 android:id=“@+id/tabMainContainer”
  82.                 android:layout_width=“match_parent”
  83.                 android:layout_height=“wrap_content”
  84.                 android:background=“#ffffff”
  85.                 android:minHeight=“400dp”>
  86.             </FrameLayout>
  87.         </LinearLayout>
  88.     </com.xiaoyuan.StickyScrollView>
  89.     <RelativeLayout
  90.         android:id=“@+id/ll_good_detail”
  91.         android:layout_width=“match_parent”
  92.         android:layout_height=“49dp”
  93.         android:background=“#00000000”
  94.         android:paddingTop=“@dimen/spacing_normal”>
  95.         <TextView
  96.             android:layout_width=“wrap_content”
  97.             android:layout_height=“wrap_content”
  98.             android:textColor=“#ffffff”
  99.             android:layout_alignParentLeft=“true”
  100.             android:layout_marginLeft=“10dip”
  101.             android:layout_centerHorizontal=“true”
  102.             android:text=“返回”/>
  103.         <TextView
  104.             android:layout_width=“wrap_content”
  105.             android:layout_height=“wrap_content”
  106.             android:textColor=“#ffffff”
  107.             android:layout_centerInParent=“true”
  108.             android:layout_centerHorizontal=“true”
  109.             android:layout_marginLeft=“10dip”
  110.             android:text=“美女”/>
  111.         <TextView
  112.             android:layout_width=“wrap_content”
  113.             android:layout_height=“wrap_content”
  114.             android:textColor=“#ffffff”
  115.             android:layout_alignParentRight=“true”
  116.             android:layout_marginRight=“10dip”
  117.             android:layout_centerHorizontal=“true”
  118.             android:text=“分享”/>
  119.     </RelativeLayout>
  120. </FrameLayout>
  121. </RelativeLayout>

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

六、实现代码

  1. public class MainActivity extends AppCompatActivity implements View.OnClickListener, StickyScrollView.OnScrollChangedListener {
  2. TextView oneTextView, twoTextView;
  3. private StickyScrollView stickyScrollView;
  4. private int height;
  5. private LinearLayout llContent;
  6. private RelativeLayout llTitle;
  7. private FrameLayout frameLayout;
  8. private TextView title;
  9. @Override
  10. protected void onCreate(Bundle savedInstanceState) {
  11.     super.onCreate(savedInstanceState);
  12.     setContentView(R.layout.activity_main);
  13.     initView();
  14.     initListeners();
  15. }
  16. /**
  17.  * 初始化View
  18.  */
  19. private void initView() {
  20.     stickyScrollView = (StickyScrollView) findViewById(R.id.scrollView);
  21.     frameLayout = (FrameLayout) findViewById(R.id.tabMainContainer);
  22.     title = (TextView) findViewById(R.id.title);
  23.     oneTextView = (TextView) findViewById(R.id.infoText);
  24.     llContent = (LinearLayout) findViewById(R.id.ll_content);
  25.     llTitle = (RelativeLayout) findViewById(R.id.ll_good_detail);
  26.     oneTextView.setOnClickListener(this);
  27.     twoTextView = (TextView) findViewById(R.id.secondText);
  28.     twoTextView.setOnClickListener(this);
  29.     stickyScrollView.setOnScrollListener(this);
  30.     StatusBarUtil.setTranslucentForImageView(MainActivity.this, 0, title);
  31.     FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) llTitle.getLayoutParams();
  32.     params.setMargins(0, getStatusHeight(), 0, 0);
  33.     llTitle.setLayoutParams(params);
  34.     //默认设置一个Frg
  35.     getSupportFragmentManager().beginTransaction().replace(R.id.tabMainContainer, Fragment.newInstance()).commit();
  36. }
  37. /**
  38.  * 获取状态栏高度
  39.  * @return
  40.  */
  41. private int getStatusHeight() {
  42.     int resourceId = MainActivity.this.getResources().getIdentifier(“status_bar_height”“dimen”“android”);
  43.     return getResources().getDimensionPixelSize(resourceId);
  44. }
  45. @Override
  46. public void onClick(View v) {
  47.     if (v.getId() == R.id.infoText) {
  48.         getSupportFragmentManager().beginTransaction().replace(R.id.tabMainContainer, Fragment.newInstance()).commit();
  49.     } else if (v.getId() == R.id.secondText) {
  50.         getSupportFragmentManager().beginTransaction().replace(R.id.tabMainContainer, Fragment1.newInstance()).commit();
  51.     }
  52. }
  53. private void initListeners() {
  54.     //获取内容总高度
  55.     final ViewTreeObserver vto = llContent.getViewTreeObserver();
  56.     vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
  57.         @Override
  58.         public void onGlobalLayout() {
  59.             height = llContent.getHeight();
  60.             //注意要移除
  61.             llContent.getViewTreeObserver()
  62.                     .removeGlobalOnLayoutListener(this);
  63.         }
  64.     });
  65.     //获取Fragment高度
  66.     ViewTreeObserver viewTreeObserver = frameLayout.getViewTreeObserver();
  67.     viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
  68.         @Override
  69.         public void onGlobalLayout() {
  70.             height = height – frameLayout.getHeight();
  71.             //注意要移除
  72.             frameLayout.getViewTreeObserver()
  73.                     .removeGlobalOnLayoutListener(this);
  74.         }
  75.     });
  76.     //获取title高度
  77.     ViewTreeObserver viewTreeObserver1 = llTitle.getViewTreeObserver();
  78.     viewTreeObserver1.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
  79.         @Override
  80.         public void onGlobalLayout() {
  81.             height = height – llTitle.getHeight() – getStatusHeight();//计算滑动的总距离
  82.             stickyScrollView.setStickTop(llTitle.getHeight() + getStatusHeight());//设置距离多少悬浮
  83.             //注意要移除
  84.             llTitle.getViewTreeObserver()
  85.                     .removeGlobalOnLayoutListener(this);
  86.         }
  87.     });
  88. }
  89. @Override
  90. public void onScrollChanged(int l, int t, int oldl, int oldt) {
  91.     if (t <= 0) {
  92.         llTitle.setBackgroundColor(Color.argb((int) 0, 255, 255, 255));
  93.         StatusBarUtil.setTranslucentForImageView(MainActivity.this, 0, title);
  94.     } else if (t > 0 && t <= height) {
  95.         float scale = (float) t / height;
  96.         int alpha = (int) (255 * scale);
  97.         llTitle.setBackgroundColor(Color.argb((int) alpha, 227, 29, 26));//设置标题栏的透明度及颜色
  98.         StatusBarUtil.setTranslucentForImageView(MainActivity.this, alpha, title);//设置状态栏的透明度
  99.     } else {
  100.         llTitle.setBackgroundColor(Color.argb((int) 255, 227, 29, 26));
  101.         StatusBarUtil.setTranslucentForImageView(MainActivity.this, 255, title);
  102.     }
  103. }
  104.  }

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

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

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

六、总结

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

未经允许不得转载:JX BLOG » Android沉浸式状态栏及悬浮效果

赞 (0)

评论 0

评论前必须登录!

登陆 注册