Android沉浸式设计

简介

一个好的APP设计能够增强用户体验,留住用户,在UI上更加美观,给用户更加舒服的体验。而沉浸式设计能够使APP整体UI设计呈现一体化,使APP界面图片延伸到状态栏, 应用本身沉浸于状态栏。

沉浸式设计就是让人专注于当前的目标(有设计者营造)情境下感到愉悦和满足,而忘记真实世界的情景的设计方法。

Android沉浸式设计

对于Android5.0以后的API,已经自动实现了沉浸式效果了,状态栏会跟随你的主题colorPrimaryDark属性。5.0以后的API有三种方式可以设置沉浸式设计:

1)所以通过设置主题的样式即可达到沉浸式设计。

上图中在styles.xml指定主题样式即可。

2)在样式中设置android:statusBarColor

设置android:statusBarColor需要在API21(也就是5.0)以上才能支持。

3)通过代码设置

注意:这种方法设置需要放在setContentView方法之前设置,而且同样是需要在5.0以后的API才能设置。

Android5.0以后的版本使用沉浸式设计固然简单,但是唯一的缺点就是不支持低于5.0的版本,我们知道Android的绝大部分手机用户的版本还是在5.0以下的,这就需要我们做兼容开发了。

做沉浸式设计,目前最低只能兼容到4.4版本,低于Android4.4版本,是不可能做到沉浸式设计的,因为Android4.4新出的API,可以设置状态栏为透明状态,低于该版本就不能设置状态栏为透明状态,因此低于Android4.4版本不能做到沉浸式设计。

沉浸式兼容到Android4.4版本(一)

能够做到兼容到Android4.4版本的,需要我们做一些特殊处理,就是利用Android4.4版本新出的API,设置状态栏为透明状态。

两种方式可以设置状态栏为透明状态:

1)在属性样式里面设置

true 一般我们不会推荐使用这种方式,因为兼容性不好。

2)在代码里设置

注意:

getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);需要在setContentView方法之前设置。

下面给出该实例代码:

Activity:

public class TranslucentActivity01 extends AppCompatActivity {

    private Toolbar mToolbar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //设置全屏
        //getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
        //设置透明状态栏
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        setContentView(R.layout.activity_translucent01);
        mToolbar = (Toolbar)this.findViewById(R.id.tool_bar);
        setSupportActionBar(mToolbar);
    }
}
复制代码

xml布局:

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.main.translucent.TranslucentActivity01">

    <com.main.toolbar.MyScrollView
        android:id="@+id/scrollView"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:background="#ffffffff"
        android:clipChildren="false"
        android:clipToPadding="false"
        android:paddingTop="?attr/actionBarSize">

        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:orientation="vertical">

            <Button
                android:id="@+id/button1"
                style="?android:attr/buttonStyleSmall"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_margin="5dp"
                android:text="Button0"/>

            <Button
                style="?android:attr/buttonStyleSmall"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_margin="5dp"
                android:text="Button1"/>

            <Button
                style="?android:attr/buttonStyleSmall"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_margin="5dp"
                android:text="Button2"/>

            <EditText
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_margin="5dp"/>
        </LinearLayout>
    </com.main.toolbar.MyScrollView>

    <android.support.v7.widget.Toolbar
        android:id="@+id/tool_bar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        android:fitsSystemWindows="true">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="标题"/>
    </android.support.v7.widget.Toolbar>

</RelativeLayout>
复制代码

注意:

Toolbar需要添加android:fitsSystemWindows="true",否则APP的内容顶到最上面去了,即状态栏会遮挡一部分界面,该属性的作用:设置布局时,是否考虑当前系统窗口的布局,如果为true就会调整整个系统窗口,布局(包括状态栏的view)以适应你的布局。

运行效果

沉浸式兼容到Android4.4版本(二)

上面的沉浸式设计的方法已经可以兼容到Android4.4版本,但是还是有bug,当里面有ScrollView并且ScrollView里面有Edittext的时候,就会出现软键盘一弹起就会把toolbar拉下来。

在这里讲解第二种兼容方法,并且解决该bug:

1)同样需要在代码种设置状态栏的透明状态。

public class TranslucentActivity02 extends AppCompatActivity {

    private Toolbar mToolbar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //设置透明状态栏
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        setContentView(R.layout.activity_translucent);
        mToolbar = (Toolbar)this.findViewById(R.id.tool_bar);
        setSupportActionBar(mToolbar);
    }
}
复制代码

2)给布局最外层容器设置android:fitsSystemWindows="true"属性,并且给最外层容器(也可以修改android:windowBackground颜色)设置状态栏想要的颜色。

3)内容布局需要包裹一层并且设置背景颜色即可。

下面给出整个xml布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    android:background="?attr/colorPrimary"
    tools:context="com.main.translucent.TranslucentActivity02">

    <com.main.toolbar.MyScrollView
        android:background="#ffffffff"
        android:id="@+id/scrollView"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:clipChildren="false"
        android:clipToPadding="false"
        android:paddingTop="?attr/actionBarSize">

        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:orientation="vertical">

            <Button
                android:id="@+id/button1"
                style="?android:attr/buttonStyleSmall"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_margin="5dp"
                android:text="Button0"/>

            <Button
                style="?android:attr/buttonStyleSmall"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_margin="5dp"
                android:text="Button1"/>

            <Button
                style="?android:attr/buttonStyleSmall"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_margin="5dp"
                android:text="Button2"/>

            <EditText
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_margin="5dp"/>
        </LinearLayout>
    </com.main.toolbar.MyScrollView>

    <android.support.v7.widget.Toolbar
        android:id="@+id/tool_bar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        android:title="沉浸式03">
    </android.support.v7.widget.Toolbar>

</RelativeLayout>

复制代码

得到的沉浸式效果图:

沉浸式兼容到Android4.4版本(三)

以上的方法都能够兼容到Android4.4版本,实现沉浸式设计,当然还有另外的方案可以实现沉浸式,那就是通过修改Toolbar的高度。

1)修改状态栏为透明状态;

getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); setContentView(R.layout.activity_translucent03);

2)不需要给Toolbar设置android:fitsSystemWindows="true";

<android.support.v7.widget.Toolbar
        android:id="@+id/tool_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?attr/colorPrimary">
        <TextView
            android:layout_width="wrap_content"
            android:layout_gravity="center_horizontal"
            android:layout_height="wrap_content"
            android:text="标题"/>
    </android.support.v7.widget.Toolbar>
复制代码

3)通过反射获取得到状态栏高度。

通过源码我们知道状态栏运行的类:android.R.dimen,其属性为status_bar_height

因此我们通过反射可以获取得到状态栏高度。

private int getStatusBarHeight(Context context){
        // 反射运行的类:android.R.dimen.status_bar_height.
        int mStatusHeight = -1;
        try {
            Class<?> mClass =Class.forName("com.android.internal.R$dimen");
            Object object = mClass.newInstance();
            String heightStr = mClass.getField("status_bar_height").get(object).toString();
            int height = Integer.valueOf(heightStr);
            //dp--->px
            mStatusHeight = context.getResources().getDimensionPixelSize(height);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return mStatusHeight;
    }
复制代码

4)修改Toolbar的PaddingTop

下面是该实例的代码:

Activity:

public class TranslucentActivity03 extends AppCompatActivity {

    private Toolbar mToolbar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        setContentView(R.layout.activity_translucent03);

        mToolbar = (Toolbar) this.findViewById(R.id.tool_bar);
        mToolbar.setPadding(
                mToolbar.getPaddingLeft(),
                mToolbar.getPaddingTop() + getStatusBarHeight(this),
                mToolbar.getPaddingRight(),
                mToolbar.getPaddingBottom());

    }


    /**
     * 获取状态栏高度
     *
     * @param context
     * @return
     */
    private int getStatusBarHeight(Context context) {
        // 反射运行的类:android.R.dimen.status_bar_height.
        int mStatusHeight = -1;
        try {
            Class<?> mClass = Class.forName("com.android.internal.R$dimen");
            Object object = mClass.newInstance();
            String heightStr = mClass.getField("status_bar_height").get(object).toString();
            int height = Integer.valueOf(heightStr);
            //dp--->px
            mStatusHeight = context.getResources().getDimensionPixelSize(height);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return mStatusHeight;
    }

}
复制代码

xml布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.main.translucent.TranslucentActivity03">
    <com.main.toolbar.MyScrollView
        android:background="#ffffffff"
        android:id="@+id/scrollView"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:clipChildren="false"
        android:clipToPadding="false"
        android:paddingTop="?attr/actionBarSize">

        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:orientation="vertical">

            <Button
                android:id="@+id/button1"
                style="?android:attr/buttonStyleSmall"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_margin="5dp"
                android:text="Button0"/>

            <Button
                style="?android:attr/buttonStyleSmall"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_margin="5dp"
                android:text="Button1"/>

            <Button
                style="?android:attr/buttonStyleSmall"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_margin="5dp"
                android:text="Button2"/>

            <EditText
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_margin="5dp"/>
        </LinearLayout>
    </com.main.toolbar.MyScrollView>

    <android.support.v7.widget.Toolbar
        android:id="@+id/tool_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?attr/colorPrimary">
        <TextView
            android:layout_width="wrap_content"
            android:layout_gravity="center_horizontal"
            android:layout_height="wrap_content"
            android:text="标题"/>
    </android.support.v7.widget.Toolbar>

</RelativeLayout>

复制代码

运行效果图:

沉浸式兼容到Android4.4版本(四)

除了以上的实现方式,当然我们可以使用第三方来实现Android的沉浸式设计。这里实例采用的是SystemTint第三方。

1)在app下的build.gradle添加依赖

2)新建BaseActivity,统一处理,新的Activity只需要继承BaseActivity即可。

public class BaseActivity extends AppCompatActivity {

    private SystemBarTintManager tintManager;

    private boolean mIsOpenBar = true;
    private int color = 0xff3F51B5;//默认颜色

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        initTint();
    }

    /**
     * 是否需要实现沉浸式
     * @param openBar
     */
    public void setOpenBar(boolean openBar) {
        mIsOpenBar = openBar;
    }

    /**
     * 设置沉浸式颜色
     * @param color
     */
    public void setColor(int color) {
        this.color = color;
        if (mIsOpenBar){
            setTintBar(color);
        }
    }

    /**
     * 初始化
     */
    private void initTint() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        }
        // create our manager instance after the content view is set
        tintManager = new SystemBarTintManager(this);
        // enable status bar tint
        tintManager.setStatusBarTintEnabled(true);
        // enable navigation bar tint
        tintManager.setNavigationBarTintEnabled(true);

        if (mIsOpenBar){
            setTintBar(color);
        }
    }

    /**
     * 设置沉浸式
     * @param color
     */
    private void setTintBar(int color) {
        // set a custom tint color for all system bars
        tintManager.setTintColor(color);
        // set a custom navigation bar resource
        tintManager.setNavigationBarTintColor(color);
        // set a custom status bar drawable
        tintManager.setStatusBarTintColor(color);
//        tintManager.setStatusBarTintResource(R.color.colorAccent);
    }
}

复制代码

初始化SystemTint和设置状态栏颜色等等在BaseActivity处理即可。具体可查看注释。

3)新Activity继承BaseAcitivity,通过setColor来设置状态栏颜色即可。

public class TranslucentActivity04 extends BaseActivity {

    private Toolbar mToolbar;
    //需要在根布局加入一下的
//    android:clipToPadding="false"
//    android:fitsSystemWindows="true"

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_translucent04);
        mToolbar = (Toolbar) this.findViewById(R.id.tool_bar);
        this.findViewById(R.id.button1).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                setColor(0xffffD306);
                mToolbar.setBackgroundColor(0xffffD306);
            }
        });
    }
}
复制代码

4)xml布局的根布局需要添加

android:clipToPadding="false"和android:fitsSystemWindows="true"属性

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clipToPadding="false"
    android:fitsSystemWindows="true"
    tools:context="com.main.translucent.TranslucentActivity04">

    <com.main.toolbar.MyScrollView
        android:id="@+id/scrollView"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:background="#ffffffff"
        android:paddingTop="?attr/actionBarSize">

        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:orientation="vertical">

            <Button
                android:id="@+id/button1"
                style="?android:attr/buttonStyleSmall"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_margin="5dp"
                android:text="Button0"/>

            <Button
                style="?android:attr/buttonStyleSmall"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_margin="5dp"
                android:text="Button1"/>

            <Button
                style="?android:attr/buttonStyleSmall"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_margin="5dp"
                android:text="Button2"/>

            <EditText
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_margin="5dp"/>
        </LinearLayout>
    </com.main.toolbar.MyScrollView>

    <android.support.v7.widget.Toolbar
        android:id="@+id/tool_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?attr/colorPrimary">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:text="标题"/>
    </android.support.v7.widget.Toolbar>

</RelativeLayout>

复制代码

运行效果图:

通过以上的学习,我们可以做出Android的沉浸式设计效果,并且能够兼容到Android4.4版本,给用户精美的UI效果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值