Material Design

如果不需要支持 4.4,建议使用 statusBarColor
如果需要支持 4.4,简易 4.4 使用 windowTranslucentStatus;
5.x 使用 statusBarColor/colorPrimaryDark
(本答案在 5.1 和 5.0 中的解决方式并不会影响软键盘和 EditText 的行为,4.4 暂时无法测试,如有朋友发现 bug 请指出,我会在回答中注明,以免其他人一起掉坑里)

21用的什么方法改变状态栏的颜色?
设置statusBarColor为transparent。以前我以为修改statusBarColor可以改变状态栏颜色,可是结果不行。修改状态栏颜色有2种方法
1、colorPrimaryDark
2、用java代码修改statusBarColor,这里用java代码修改statusBarColor有效果,但是在style里的android:statusBarColor设置值没有任何效果,不知道为什么
getWindow().setStatusBarColor(getResources().getColor(R.color.colorRed));

19用的是android:windowTranslucentStatus让状态栏透明,19用SystemBarTintManager来改变状态栏颜色,实际上是在decorview内加了一个view跟状态栏叠在一起(其实在contentview里加也是可以的)。而21用的是android:statusBarColor让状态栏透明。

如果21也用android:windowTranslucentStatus的话,会导致状态栏颜色很深,不符合MD。

https://blog.csdn.net/qq_34020571/article/details/78622642

状态栏的处理有两种不同的方式:
niorgai.github.io/2016/03/20/Android-transulcent-status-bar/
1:全屏( ContentView 可以进入状态栏)
2:非全屏 ( ContentView 与状态栏分离, 状态栏直接着色) 

全屏模式: 左边图所示.
着色模式: 右边图所示.
ContentView: activity.findViewById(Window.ID_ANDROID_CONTENT) 获取的 View , 即 setContentView 方法所设置的 View, 实质为 FrameLayout. id/content
ContentParent: ContentView 的 parent , 实质为 LinearLayout.
ChildView: ContentView 的第一个子 View ,即布局文件中的 root layout .
三个view之间的关系:https://blog.csdn.net/c_cayujie/article/details/54381008

怎么获取Activity的ContentView?
方法1: Activity.findViewById(android.R.id.content) 首选
方法2: Activity.getWindow().getDecorView().findViewById(android.R.id.content)
方法3: Activity.findViewById(android.R.id.content).getRootView()

要想拿到布局文件的视图id,可以用这种方法:
((ViewGroup)findViewById(android.R.id.content)).getChildAt(0);
或getWindow().getDecorView().findViewById(android.R.id.content)

添加和删除组件:
public class MainActivity extends Activity {
    private LinearLayout layout;
    private TextView textView;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        layout = new LinearLayout( this );    // 变量layout是该Activity的成员变量(private LinearLayout layout)
        layout.setOrientation( LinearLayout.VERTICAL );    // 设置layout布局方向为垂直
        setContentView( layout );
        // 接下来向layout中添加TextView
        textView = new TextView( this );
        textView.setText( "This Is a TextView" );
        layout.addView( textView );
   }
    @Override
    protected void onResume() {
        // TODO Auto-generated method stub
        layout.removeView(textView);
        super.onResume();
    }

Android 中的Activity、Window、View之间的关系:
https://www.cnblogs.com/kest/p/5141817.html

fitsSystemWindows, 该属性可以设置是否为系统 View 预留出空间, 当设置为 true 时,会预留出状态栏的空间.
FLAG_TRANSLUCENT_STATUS, 设置全屏的标志位, 此时界面可以延伸到状态栏.

5.0以上操作:
    着色模式: 直接调用 setStatusBarColor 来设置状态栏的颜色
    通过查看 setStatusBarColor() 方法的文档,发现在调用该方法时需要设置以下属性:
        添加 FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS Flag(绘制系统栏).
        清除 FLAG_TRANSLUCENT_STATUS Flag(透明状态栏).
        调用 setStatusBarColor() 设置状态栏颜色.
            即:
            Window window = getWindow();
            //取消设置透明状态栏,使 ContentView 内容不再覆盖状态栏
            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            //需要设置这个 flag 才能调用 setStatusBarColor 来设置状态栏颜色
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            //设置状态栏颜色
            window.setStatusBarColor(getResources().getColor(R.color.white));
  
    全屏模式:
    由于 5.0 以上为状态栏添加了一个阴影, 所以为全屏模式添加了是否隐藏状态栏阴影的方法.
        隐藏阴影
            像着色模式一样添加 flag ,然后通过 setStatusBarColor() 设置颜色为透明.
            通过 setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN) 隐藏状态栏颜色.
        显示阴影
            设置 FLAG_TRANSLUCENT_STATUS 来隐藏状态栏.
            通过 setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE) 来恢复默认状态栏样式.
            
            
透明系统栏:
Translucent System Bar 
4.4引入
情景一:没有Tab栏
1、在values、values-v19、values-v21的style.xml都设置一个 Translucent System Bar 风格的Theme
values/style.xml:
<style name="ImageTranslucentTheme" parent="AppTheme">
    <!--在Android 4.4之前的版本上运行,直接跟随系统主题-->
</style>

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

values-v21/style.xml:
<style name="ImageTranslucentTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="android:windowTranslucentStatus">false</item>
    <item name="android:windowTranslucentNavigation">true</item>
    <!--Android 5.x开始需要把颜色设置透明,否则导航栏会呈现系统默认的浅灰色-->
    <item name="android:statusBarColor">@android:color/transparent</item>
</style>

2、在AndroidManifest.xml中对指定Activity的theme进行设置

3、在Activity的布局文件中设置背景图片,同时,需要把android:fitsSystemWindows设置为true!
 
情景二:有Tab栏

<item name="android:statusBarColor">@color/color_31c27c</item>


需要用Toolbar,主题必须的NoActionBar,否则就在activity中setContentView()前调用requestWindowFeature(Window.FEATURE_NO_TITLE)。

代码中怎么获取内容布局的根布局,并设置setFitSystem为true:
    ViewGroup contentFrameLayout = (ViewGroup) findViewById(Window.ID_ANDROID_CONTENT); 
    View parentView = contentFrameLayout.getChildAt(0);
    if (parentView != null && Build.VERSION.SDK_INT >= 14) 
    { parentView.setFitsSystemWindows(true);}
    
    Decorview(是一个FrameLayout)
        |—LinearLayout
            |—FrameLayout 给ActionBar(当设置主题为NoActionBar是为ViewStub)
            |—FrameLayout 给ContentView
只要我们在LinearLayout的第一个位置插入一个View就可以让ContentView下移了!
    if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.KITKAT)
    {
        ViewGroup firstChildAtDecorView = ((ViewGroup) ((ViewGroup) getWindow().getDecorView()).getChildAt(0));
        View statusView = new View(this);
        //颜色的设置可抽取出来让子类实现之
        ViewGroup.LayoutParams statusViewLp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getStatusBarHeight()); 
        statusView.setBackgroundColor(getResources().getColor(android.R.color.holo_blue_light));
        firstChildAtDecorView.addView(statusView, 0, statusViewLp);
    }
    
    private int getStatusBarHeight() {
        int resId = getResources().getIdentifier("status_bar_height","dimen","android");
        if(resId>0){ return getResources().getDimensionPixelSize(resId);
        }
        return 0;
    }
    
//透明状态栏和导航栏,隐藏ActionBar 
getSupportActionBar().hide(); 
getWindow().getDecorView().setSystemUiVisibility( View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN|View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); 
getWindow().setNavigationBarColor(Color.TRANSPARENT); 
getWindow().setStatusBarColor(Color.TRANSPARENT);

setSystemUiVisibility(int visibility)方法可传入的实参为:
https://www.jianshu.com/p/3dc25a1ccb78
    1. View.SYSTEM_UI_FLAG_VISIBLE:显示状态栏,Activity不全屏显示(即:应用平常的显示画面)。有Actionbar
    2. View.INVISIBLE:隐藏状态栏,同时Activity会伸展全屏显示。有Actionbar
    3. View.SYSTEM_UI_FLAG_FULLSCREEN:Activity全屏显示,且状态栏被隐藏覆盖掉。
    
    4. View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN:Activity全屏显示,但状态栏不会被隐藏覆盖,状态栏依然可见,Activity顶端布局部分会被状态遮住。
    5. View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION:效果同View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
    6. View.SYSTEM_UI_LAYOUT_FLAGS:效果同View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN,Activity的焦点通过Back键和recent键不一样。 点击recent键再返回时,Activity顶端布局部分会被状态遮住。点击Back键再返回时,Activity顶端布局部分不会被状态遮住!
    4 5 6效果相同,但是用处不大啊!
    
    7. View.SYSTEM_UI_FLAG_HIDE_NAVIGATION:隐藏虚拟按键(导航栏)。有些手机会用虚拟按键来代替物理按键。
    8. View.SYSTEM_UI_FLAG_LOW_PROFILE:状态栏显示处于低能显示状态(low profile模式),状态栏上一些图标显示会被隐藏。
    Android4.4新特性又增加下面俩个:(Android 4.4新特性之开启全屏沉浸模式)
    9. View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY:为粘性沉浸式模式。下拉只能显示状态栏,不能显示Actionbar!状态栏会自动隐藏。
    10.View.SYSTEM_UI_FLAG_IMMERSIVE:为非粘性沉浸式。状态栏和导航栏下拉显示后不再自动隐藏。
    11. View.SYSTEM_UI_FLAG_LAYOUT_STABLE:这个标志来帮助你的应用维持一个稳定的布局。
    
requestWindowFeature(Window.FEATURE_NO_TITLE);//隐藏标题栏
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);//隐藏状态栏
        

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值