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

anni 7年前
   <h3><strong>一、概述</strong></h3>    <p>现在大多数的电商APP的详情页长得几乎都差不多,几乎都是上面一个商品的图片,当你滑动的时候,会有Tab悬浮在上面,这样做用户体验确实不错,如果Tab滑上去,用户可能还需要滑下来,在来点击Tab,这样确实很麻烦。沉浸式状态栏那, 郭霖 说过谷歌并没有给出沉浸式状态栏这个明白,谷歌只说了沉浸式模式(Immersive Mode)。不过沉浸式状态栏这个名字其实听不粗,随大众吧,但是 Android 的环境并没有IOS环境一样特别统一,比如华为rom的跟小米rom的虚拟按键完全不一样,所有Android开发者不容易。。。。。</p>    <h3><strong>二、淘宝的效果</strong></h3>    <p style="text-align:center"><img src="https://simg.open-open.com/show/4e9d1dae19ad13eb564e4df7992ec68a.gif"></p>    <h3><strong>三、我们的效果</strong></h3>    <p style="text-align:center"><img src="https://simg.open-open.com/show/eeff9aa927e371296e714823aa2ed01f.gif"></p>    <p>只能传2M,把我的美女都给压失真了。。。。。。</p>    <h3><strong>四、实现类</strong></h3>    <ul>     <li>自定义ScrollView (StickyScrollView)</li>     <li><a href="/misc/goto?guid=4959714722896670052" rel="nofollow,noindex">StatusBarUtil</a>  //非常不错的状态栏工具</li>    </ul>    <h3><strong>五、布局</strong></h3>    <pre>  <code class="language-java"><?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></code></pre>    <p>注意:我们把要悬浮的Tab设置了android:tag=”sticky”这样的属性</p>    <h3><strong>六、实现代码</strong></h3>    <pre>  <code class="language-java">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);      }  }   }</code></pre>    <p>注意:stickyScrollView.setStickTop(int height)我们通过这个方法可以设置Tab距离多高开始悬浮</p>    <p>我们通过监听ScrollView滑动距离来不断改变我们标题栏跟状态栏的透明度来达到效果,在这里我们计算了几个高度(滑动距离)。最后来算出滑动总距离,根据滑动的距离跟滑动的总距离来算出透明度的数值。</p>    <p>StatusBarUtil.setTranslucentForImageView(MainActivity.this, 0, title);我们通过工具来实现图片深入状态栏。里面的传的View是图片下面的View。</p>    <h3>六、总结</h3>    <p>效果倒是不错,美女也不错、但是在Android4.4之前根本就没有沉浸式这个东西,大家可以下载源码来研究。自己动手实现一遍记得比较清楚。工作了。</p>    <h3> </h3>    <p> </p>    <p>来自:http://www.androidchina.net/5996.html</p>    <p> </p>