一、概述
现在大多数的电商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