美文网首页
状态栏背景图片可滑动

状态栏背景图片可滑动

作者: knock_knock | 来源:发表于2016-09-21 01:30 被阅读615次

    参考文章:
    《Android 开发:Translucent System Bar 的最佳实践》

    关于透明状态栏

    仔细看了上面文章中的实现,发现不能完全满足项目需求,于是在上面项目的基础上做了一些修改,效果描述如下:

    • 图片(非背景图)占用StatusBar显示
    • 图片可以随页面滑动
    • ActionBar和StatusBar随滑动距离透明度渐变
    • 仅支持 API>19

    静态效果:

    动态效果:

    原理

    API>19的手机上,可以在styles中设置windowTranslucentStatus属性使状态栏变透明,[1][同时Activity的布局也会占据原来StatusBar的位置]。

    因为[1]的原因,ActionBar会上移和statusbar重叠,为了避免出现在种情况我们会考虑使用fitsSystemWindows,随之而来的问题就是图片不能显示在StatusBar下面了。这就是我在采用参考文章中的思路时遇到的问题,这个问题让我不得不考虑其它的实现方式。

    回到问题的起点,设置windowTranslucentStatus属性后,ActionBar占用了StatusBar的位置。 在这里放置一个占位的View,高度设置为StatusBar的高度不就可以了吗?

    我最终采用的就是上面的思路,满足了产品的需求。下面是代码部分,在上面基础上加了ActionBar随滑动距离的渐变:

    styles:

    //values-v19/styles.xml
    <style name="ImageTranslucentTheme"
      parent="Theme.AppCompat.Light.DarkActionBar">
      <item name="android:windowTranslucentStatus">true</item>
      <item name="android:windowTranslucentNavigation">true</item>     
      <item name="windowActionBar">false</item>
      <item name="windowNoTitle">true</item>
    </style>
    

    布局文件:

    //layout/activity_image_translucent_bar.xml
    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:toolbar="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <android.support.v4.widget.NestedScrollView
            android:id="@+id/scrollView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fillViewport="true"
            android:overScrollMode="never">
    
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical">
    
                <ImageView
                    android:layout_width="match_parent"
                    android:layout_height="@dimen/ban_size"
                    android:background="@mipmap/topinfo_ban_bg" />
    
                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="1234456678898900"
                    android:textSize="200dp" />
    
            </LinearLayout>
    
        </android.support.v4.widget.NestedScrollView>
    
        <LinearLayout
            android:id="@+id/topbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">
    
            <View
                android:id="@+id/status_placeholder"
                android:layout_width="match_parent"
                android:layout_height="0dp" />
    
            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                toolbar:navigationIcon="@mipmap/ic_drawer_home">
    
            </android.support.v7.widget.Toolbar>
    
        </LinearLayout>
    
    
    </RelativeLayout>
    
    

    编码:

    public class ImageTranslucentBarActivity extends AppCompatActivity {
        private static final String STATUS_BAR_HEIGHT_RES_NAME = "status_bar_height";
        private static final String TAG = ImageTranslucentBarActivity.class.getSimpleName();
        private GradientDrawable gradientDrawable; //头部遮罩
        private LinearLayout topbar;//标题栏+placeholder
        private View placeholder;//占用statusbar的位置
        private Toolbar toolbar;
        private NestedScrollView scrollView;
        private int banSize;
        private int mActionBarHeight;
        private int mStatusBarHeight;
        private int bufferDistance;//缓冲距离
        private int threshold;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_image_translucent_bar);
            placeholder = findViewById(R.id.status_placeholder);
            topbar = (LinearLayout) findViewById(R.id.topbar);
            toolbar = (Toolbar) findViewById(R.id.toolbar);
            scrollView = (NestedScrollView) findViewById(R.id.scrollView);
            toolbar.inflateMenu(R.menu.base_toolbar_menu);
            //StatusBar占位
            mStatusBarHeight = getInternalDimensionSize(getResources(),
                    STATUS_BAR_HEIGHT_RES_NAME);
            LayoutParams params = (LayoutParams) placeholder.getLayoutParams();
            params.height = mStatusBarHeight;
            placeholder.setLayoutParams(params);
            //toolbar高度
            mActionBarHeight = getActionBarHeight(this);
            //图片高度
            banSize = getResources().getDimensionPixelSize(R.dimen.ban_size);
            bufferDistance = getResources()
                    .getDimensionPixelOffset(R.dimen.buffer_distance);
            //头部遮罩,之所以写在代码里,是因为要实现随滑动距离变色
            gradientDrawable = (GradientDrawable) getResources()
                    .getDrawable(R.drawable.gradient_bg);
            topbar.setBackgroundDrawable(gradientDrawable);
            threshold = banSize - mStatusBarHeight + bufferDistance;
            scrollView.setOnScrollChangeListener(
                    new NestedScrollView.OnScrollChangeListener() {
                @Override
                public void onScrollChange(NestedScrollView v,
                                           int scrollX,
                                           int scrollY,
                                           int oldScrollX,
                                           int oldScrollY) {
                    if (scrollY <= threshold) {
                        float scale0 = Math.min(scrollY * 1.0f / (banSize - mStatusBarHeight
                        - mActionBarHeight), 1.0f);
                        float scale1 = Math.min(scrollY * 1.0f / (banSize - mStatusBarHeight), 1.0f);
                        int startColor = Color.argb((int) (255 * scale0), (int) (254 * scale0),
                                (int) (134 * scale0), (int) (158 * scale0));
                        int endColor = Color.argb((int) (255 * scale1), (int) (254 * scale1),
                                (int) (134 * scale1), (int) (158 * scale1));
                        int[] colors = new int[]{startColor, endColor};
                        gradientDrawable.setColors(colors);
                        topbar.setBackgroundDrawable(gradientDrawable);
                    }
                }
            });
        }
    
        @TargetApi(14)
        private int getActionBarHeight(Context context) {
            int result = 0;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
                TypedValue tv = new TypedValue();
                context.getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true);
                result = TypedValue.complexToDimensionPixelSize(tv.data,
                        context.getResources().getDisplayMetrics());
            }
            return result;
        }
    
        private int getInternalDimensionSize(Resources res, String key) {
            int result = 0;
            int resourceId = res.getIdentifier(key, "dimen", "android");
            if (resourceId > 0) {
                result = res.getDimensionPixelSize(resourceId);
            }
            return result;
        }
    }
    

    相关文章

      网友评论

          本文标题:状态栏背景图片可滑动

          本文链接:https://www.haomeiwen.com/subject/bhzoettx.html