Android沉浸式狀態(tài)欄及懸浮效果
一、概述
現(xiàn)在大多數(shù)的電商APP的詳情頁(yè)長(zhǎng)得幾乎都差不多,幾乎都是上面一個(gè)商品的圖片,當(dāng)你滑動(dòng)的時(shí)候,會(huì)有Tab懸浮在上面,這樣做用戶體驗(yàn)確實(shí)不錯(cuò),如果Tab滑上去,用戶可能還需要滑下來(lái),在來(lái)點(diǎn)擊Tab,這樣確實(shí)很麻煩。沉浸式狀態(tài)欄那,郭霖說(shuō)過(guò)谷歌并沒(méi)有給出沉浸式狀態(tài)欄這個(gè)明白,谷歌只說(shuō)了沉浸式模式(Immersive Mode)。不過(guò)沉浸式狀態(tài)欄這個(gè)名字其實(shí)聽(tīng)不粗,隨大眾吧,但是Android的環(huán)境并沒(méi)有IOS環(huán)境一樣特別統(tǒng)一,比如華為rom的跟小米rom的虛擬按鍵完全不一樣,所有Android開(kāi)發(fā)者不容易。。。。。
二、淘寶的效果
三、我們的效果
只能傳2M,把我的美女都給壓失真了。。。。。。
四、實(shí)現(xiàn)類
自定義ScrollView (StickyScrollView)
StatusBarUtil //非常不錯(cuò)的狀態(tài)欄工具
五、布局
- <?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設(shè)置了android:tag=”sticky”這樣的屬性
六、實(shí)現(xiàn)代碼
- 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);
- //默認(rèn)設(shè)置一個(gè)Frg
- getSupportFragmentManager().beginTransaction().replace(R.id.tabMainContainer, Fragment.newInstance()).commit();
- }
- /**
- * 獲取狀態(tài)欄高度
- * @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() {
- //獲取內(nèi)容總高度
- 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();//計(jì)算滑動(dòng)的總距離
- stickyScrollView.setStickTop(llTitle.getHeight() + getStatusHeight());//設(shè)置距離多少懸浮
- //注意要移除
- 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));//設(shè)置標(biāo)題欄的透明度及顏色
- StatusBarUtil.setTranslucentForImageView(MainActivity.this, alpha, title);//設(shè)置狀態(tài)欄的透明度
- } else {
- llTitle.setBackgroundColor(Color.argb((int) 255, 227, 29, 26));
- StatusBarUtil.setTranslucentForImageView(MainActivity.this, 255, title);
- }
- }
- }
注意:stickyScrollView.setStickTop(int height)我們通過(guò)這個(gè)方法可以設(shè)置Tab距離多高開(kāi)始懸浮
我們通過(guò)監(jiān)聽(tīng)ScrollView滑動(dòng)距離來(lái)不斷改變我們標(biāo)題欄跟狀態(tài)欄的透明度來(lái)達(dá)到效果,在這里我們計(jì)算了幾個(gè)高度(滑動(dòng)距離)。最后來(lái)算出滑動(dòng)總距離,根據(jù)滑動(dòng)的距離跟滑動(dòng)的總距離來(lái)算出透明度的數(shù)值。
StatusBarUtil.setTranslucentForImageView(MainActivity.this, 0, title);我們通過(guò)工具來(lái)實(shí)現(xiàn)圖片深入狀態(tài)欄。里面的傳的View是圖片下面的View。
六、總結(jié)
效果倒是不錯(cuò),美女也不錯(cuò)、但是在Android4.4之前根本就沒(méi)有沉浸式這個(gè)東西,大家可以下載源碼來(lái)研究。自己動(dòng)手實(shí)現(xiàn)一遍記得比較清楚。工作了。太忙了。最后感謝一下dota群的高叔(博客地址不知道)提供思路。