zl程序教程

您现在的位置是:首页 >  移动开发

当前栏目

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

Android 效果 状态栏 悬浮 沉浸
2023-09-27 14:21:20 时间

一、概述

现在大多数的电商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群的高叔(博客地址不知道)提供思路。

本文作者:佚名 来源:51CTO
Android 自定义ToolBar并沉浸式   ToolBar是Android 5.0推出的一个新的导航控件用于取代之前的ActionBar,由于其高度的可定制性、灵活性、具有Material Design风格等优点,越来越多的App也用上了ToolBar。
Android如何实现超级棒的沉浸式体验 原文:Android如何实现超级棒的沉浸式体验 欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由brzhang发表于云+社区专栏 做APP开发的过程中,有很多时候,我们需要实现类似于下面这种沉浸式的体验。
      小菜前些日子整理了两次小小的沉浸式状态栏的总结:Android 沉浸式状态栏的多种样式 和 Android 沉浸式状态栏以及伪沉浸式状态栏。今天小菜再稍稍补充一点,Java/Kotlin 代码中设置 LayerDrawable 方式实现沉浸式状态栏。
      小菜最近在调整页面状态栏的效果,主要包括沉浸式状态栏和伪沉浸状态栏(同事唠嗑给定义的玩的)。       前段时间整理过一篇 Android 沉浸式状态栏的多种样式,现在小菜在稍微的补充一下,都是在日常应用中测试整理的。
Android项目实战(四十一):游戏和视频类型应用 状态栏沉浸式效果 原文:Android项目实战(四十一):游戏和视频类型应用 状态栏沉浸式效果  手机app ,当打游戏或者全屏看视频的时候会发现这时候手机顶部的状态栏是不显示的,当我们从手机顶端向下进行滑动或手机底端向上滑动的时候,状态栏会显示出来,如果短暂的几秒时间没有操作的话,状态栏会再次隐藏。
Android项目实战(四十一):游戏和视频类型应用 状态栏沉浸式效果  手机app ,当打游戏或者全屏看视频的时候会发现这时候手机顶部的状态栏是不显示的,当我们从手机顶端向下进行滑动或手机底端向上滑动的时候,状态栏会显示出来,如果短暂的几秒时间没有操作的话,状态栏会再次隐藏。
3、Android状态栏微技巧,带你真正理解沉浸式模式 4、android4.4以上沉浸式状态栏和导航栏实现以及Bar的其他管理 心得:看了大神们写的,告诫自己不要被沉浸式唬住,其实就是个名字而已,展现就是个风格(主要和状态栏颜色,高度,是否隐藏相关而已),千万别被绕进去。
Android沉浸式(侵入式)标题栏(状态栏)Status(三) 从附录文章1,2可以看到,依靠Android系统提供的标准方案,状态栏即便在透明状态下,仍然有些半透明而不是全透明。