CSS support for styling status bar (#3156)

This commit is contained in:
Maya Zhecheva
2016-11-24 14:20:12 +02:00
committed by Vladimir Enchev
parent 3f4a5beca9
commit 2e13205797
14 changed files with 397 additions and 11 deletions

View File

@@ -600,4 +600,19 @@
*/
export function cubicBezier(x1: number, y1: number, x2: number, y2: number): animationModule.CubicBezierAnimationCurve;
}
/**
* Specifies the types of the status bar style.
*/
export module StatusBarStyle {
/**
* The light style of the status bar - light background with dark letters.
*/
export var light: string;
/**
* The dark style of the status bar - dark background with light letters.
*/
export var dark: string;
}
}

View File

@@ -179,3 +179,8 @@ export module AnimationCurve {
return new animationModule.CubicBezierAnimationCurve(x1, y1 ,x2, y2);
}
}
export module StatusBarStyle {
export var light = "light";
export var dark = "dark";
}

View File

@@ -10,6 +10,7 @@ import * as frameModule from "ui/frame";
import proxy = require("ui/core/proxy");
import keyframeAnimation = require("ui/animation/keyframe-animation");
import types = require("utils/types");
import {Color} from "color";
let fs: typeof fileSystemModule;
function ensureFS() {
@@ -29,7 +30,18 @@ function ensureFrame() {
const AffectsLayout = global.android ? PropertyMetadataSettings.None : PropertyMetadataSettings.AffectsLayout;
const backgroundSpanUnderStatusBarProperty = new Property("backgroundSpanUnderStatusBar", "Page", new proxy.PropertyMetadata(false, AffectsLayout));
const statusBarStyleProperty = new Property("statusBarStyle", "Page", new proxy.PropertyMetadata(undefined));
function onStatusBarStylePropertyChanged(data: PropertyChangeData) {
const page = <Page>data.object;
if (page.isLoaded) {
page._updateStatusBar();
}
}
(<proxy.PropertyMetadata>statusBarStyleProperty.metadata).onSetNativeValue = onStatusBarStylePropertyChanged;
const androidStatusBarBackgroundProperty = new Property("androidStatusBarBackground", "Page", new proxy.PropertyMetadata(undefined));
const actionBarHiddenProperty = new Property("actionBarHidden", "Page", new proxy.PropertyMetadata(undefined, AffectsLayout));
function onActionBarHiddenPropertyChanged(data: PropertyChangeData) {
@@ -54,6 +66,8 @@ function enableSwipeBackNavigationPropertyChanged(data: PropertyChangeData) {
export class Page extends ContentView implements dts.Page {
public static backgroundSpanUnderStatusBarProperty = backgroundSpanUnderStatusBarProperty;
public static statusBarStyleProperty = statusBarStyleProperty;
public static androidStatusBarBackgroundProperty = androidStatusBarBackgroundProperty;
public static actionBarHiddenProperty = actionBarHiddenProperty;
public static iosSwipeBackNavigationEnabledProperty = enableSwipeBackNavigationProperty;
public static navigatingToEvent = "navigatingTo";
@@ -90,6 +104,8 @@ export class Page extends ContentView implements dts.Page {
this._updateActionBar(this.actionBarHidden);
}
this._updateStatusBar();
super.onLoaded();
}
@@ -101,6 +117,21 @@ export class Page extends ContentView implements dts.Page {
this._setValue(Page.backgroundSpanUnderStatusBarProperty, value);
}
get statusBarStyle(): string {
return this.style._getValue(Page.statusBarStyleProperty);
}
set statusBarStyle(value: string) {
this.style._setValue(Page.statusBarStyleProperty, value);
}
get androidStatusBarBackground(): Color {
return this.style.androidStatusBarBackground;
}
set androidStatusBarBackground(value: Color) {
this.style.androidStatusBarBackground = value;
}
get actionBarHidden(): boolean {
return this._getValue(Page.actionBarHiddenProperty);
}
@@ -121,6 +152,10 @@ export class Page extends ContentView implements dts.Page {
//
}
public _updateStatusBar() {
//
}
public _updateEnableSwipeBackNavigation(hidden: boolean) {
//
}
@@ -365,4 +400,4 @@ export class Page extends ContentView implements dts.Page {
resetCssValuesFunc(this);
view.eachDescendant(this, resetCssValuesFunc);
}
}
}

View File

@@ -1,6 +1,9 @@
import pageCommon = require("./page-common");
import view = require("ui/core/view");
import app = require("application");
import enums = require("ui/enums");
import pageCommon = require("./page-common");
import platform = require("platform");
import style = require("ui/styling/style");
import view = require("ui/core/view");
import * as actionBar from "ui/action-bar";
import * as gridLayout from "ui/layouts/grid-layout";
import * as traceModule from "trace";
@@ -23,9 +26,12 @@ function ensureColor() {
}
export var DIALOG_FRAGMENT_TAG = "dialog";
const SYSTEM_UI_FLAG_LIGHT_STATUS_BAR = 0x00002000;
const STATUS_BAR_LIGHT_BCKG = "#F5F5F5";
const STATUS_BAR_DARK_BCKG = "#66000000";
interface DialogFragmentClass {
new (owner: Page, fullscreen: boolean, shownCallback: () => void, dismissCallback: () => void): android.app.DialogFragment;
new (owner: Page, fullscreen: boolean, shownCallback: () => void, dismissCallback: () => void): android.app.DialogFragment;
}
var DialogFragmentClass: DialogFragmentClass;
@@ -69,7 +75,7 @@ function ensureDialogFragmentClass() {
super.onStart();
if (!this._owner.isLoaded) {
this._owner.onLoaded();
}
}
this._shownCallback();
}
@@ -169,7 +175,7 @@ export class Page extends pageCommon.Page {
super._raiseShowingModallyEvent();
this._dialogFragment.show(parent.frame.android.activity.getFragmentManager(), DIALOG_FRAGMENT_TAG);
this._dialogFragment.show(parent.frame.android.activity.getFragmentManager(), DIALOG_FRAGMENT_TAG);
}
protected _hideNativeModalView(parent: Page) {
@@ -184,4 +190,86 @@ export class Page extends pageCommon.Page {
public _updateActionBar(hidden: boolean) {
this.actionBar.update();
}
public _updateStatusBar () {
this._updateStatusBarStyle(this.statusBarStyle);
this._updateStatusBarBackground();
}
public _updateStatusBarStyle(value?: string) {
if (value && platform.device.sdkVersion >= "23") {
let window = app.android.startActivity.getWindow();
let decorView = window.getDecorView();
if (value === enums.StatusBarStyle.light) {
let nativeColor = new colorModule.Color(STATUS_BAR_LIGHT_BCKG).android;
window.setStatusBarColor(nativeColor);
decorView.setSystemUiVisibility(SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
} else {
let nativeColor = new colorModule.Color(STATUS_BAR_DARK_BCKG).android;
window.setStatusBarColor(nativeColor);
decorView.setSystemUiVisibility(0);
}
}
}
private _updateStatusBarBackground() {
if (this.androidStatusBarBackground && platform.device.sdkVersion >= "23") {
let window = app.android.startActivity.getWindow();
let nativeColor = this.androidStatusBarBackground.android;
window.setStatusBarColor(nativeColor);
}
}
}
export class PageStyler implements style.Styler {
// statusBarStyle
private static setStatusBarStyleProperty(v: view.View, newValue: any) {
let page = <Page>v;
page._updateStatusBarStyle(newValue);
}
private static resetStatusBarStyleProperty(v: view.View, nativeValue: any) {
let page = <Page>v;
page._updateStatusBarStyle(nativeValue);
}
private static getStatusBarStyleProperty(v: view.View): any {
let page = <Page>v;
return page.statusBarStyle;
}
// android-status-bar-background-property
private static setAndroidStatusBarBackgroundProperty(v: view.View, newValue: any) {
let window = app.android.startActivity.getWindow();
let nativeColor = new colorModule.Color(newValue).android;
window.setStatusBarColor(nativeColor);
}
private static resetAndroidStatusBarBackgroundProperty(v: view.View, nativeValue: any) {
let window = app.android.startActivity.getWindow();
let nativeColor = (nativeValue instanceof colorModule.Color) ? (<colorModule.Color>nativeValue).android : new colorModule.Color(nativeValue).android;
window.setStatusBarColor(nativeColor);
}
private static getAndroidStatusBarBackgroundProperty(v: view.View): any {
let page = <Page>v;
return page.androidStatusBarBackground;
}
public static registerHandlers() {
style.registerHandler(style.statusBarStyleProperty, new style.StylePropertyChangedHandler(
PageStyler.setStatusBarStyleProperty,
PageStyler.resetStatusBarStyleProperty,
PageStyler.getStatusBarStyleProperty), "Page");
style.registerHandler(style.androidStatusBarBackgroundProperty, new style.StylePropertyChangedHandler(
PageStyler.setAndroidStatusBarBackgroundProperty,
PageStyler.resetAndroidStatusBarBackgroundProperty,
PageStyler.getAndroidStatusBarBackgroundProperty), "Page");
}
}
PageStyler.registerHandlers();

View File

@@ -5,6 +5,7 @@ declare module "ui/page" {
import observable = require("data/observable");
import contentView = require("ui/content-view");
import frame = require("ui/frame");
import color = require("color");
import actionBar = require("ui/action-bar");
import dependencyObservable = require("ui/core/dependency-observable");
import keyframeAnimation = require("ui/animation/keyframe-animation");
@@ -52,10 +53,20 @@ declare module "ui/page" {
*/
export class Page extends contentView.ContentView {
/**
* Dependency property that specify if page background should span under status bar.
* Dependency property that specifies if page background should span under status bar.
*/
public static backgroundSpanUnderStatusBarProperty: dependencyObservable.Property;
/**
* Dependency property that specifies the style of the status bar.
*/
public static statusBarStyleProperty: dependencyObservable.Property;
/**
* Dependency property that specifies the background of the status bar in Android.
*/
public static androidStatusBarBackgroundProperty: dependencyObservable.Property;
/**
* Dependency property used to hide the Navigation Bar in iOS and the Action Bar in Android.
*/
@@ -102,6 +113,16 @@ declare module "ui/page" {
*/
backgroundSpanUnderStatusBar: boolean;
/**
* Gets or sets the style of the status bar.
*/
statusBarStyle: string;
/**
* Gets or sets the color of the status bar in Android.
*/
androidStatusBarBackground: color.Color;
/**
* Used to hide the Navigation Bar in iOS and the Action Bar in Android.
*/

View File

@@ -5,7 +5,7 @@ import trace = require("trace");
import uiUtils = require("ui/utils");
import { device } from "platform";
import { DeviceType } from "ui/enums";
import style = require("ui/styling/style");
import * as utils from "utils/utils";
import getter = utils.ios.getter;
@@ -133,7 +133,7 @@ class UIViewControllerImpl extends UIViewController {
}
}
else {
if(!application.ios.window) {
if (!application.ios.window) {
uiUtils.ios._layoutRootView(owner, utils.ios.getter(UIScreen, UIScreen.mainScreen).bounds);
}
owner._updateLayout();
@@ -440,6 +440,20 @@ export class Page extends pageCommon.Page {
}
}
public updateStatusBar() {
this._updateStatusBarStyle(this.statusBarStyle);
}
public _updateStatusBarStyle(value?: string) {
const frame = this.frame;
if (this.frame && value) {
let navigationController = frame.ios.controller;
let navigationBar = navigationController.navigationBar;
navigationBar.barStyle = value === "dark" ? 1 : 0;
}
}
public _updateEnableSwipeBackNavigation(enabled: boolean) {
const navController = this._ios.navigationController;
if (this.frame && navController && navController.interactivePopGestureRecognizer) {
@@ -536,4 +550,31 @@ export class Page extends pageCommon.Page {
return super._addViewToNativeVisualTree(view);
}
}
}
export class PageStyler implements style.Styler {
// statusBarStyle
private static setStatusBarStyleProperty(v: View, newValue: any) {
let page = <Page>v;
page._updateStatusBarStyle(newValue);
}
private static resetStatusBarStyleProperty(v: View, nativeValue: any) {
let page = <Page>v;
page._updateStatusBarStyle(nativeValue);
}
private static getStatusBarStyleProperty(v: View): any {
let page = <Page>v;
return page.statusBarStyle;
}
public static registerHandlers() {
style.registerHandler(style.statusBarStyleProperty, new style.StylePropertyChangedHandler(
PageStyler.setStatusBarStyleProperty,
PageStyler.resetStatusBarStyleProperty,
PageStyler.getStatusBarStyleProperty), "Page");
}
}
PageStyler.registerHandlers();

View File

@@ -111,6 +111,10 @@ declare module "ui/styling/style" {
//SegmentedBar-specific props
public selectedBackgroundColor: Color;
// Page-specific props
public statusBarStyle: string;
public androidStatusBarBackground: Color;
constructor(parentView: View);
public _beginUpdate();
@@ -182,6 +186,9 @@ declare module "ui/styling/style" {
export var selectedBackgroundColorProperty: styleProperty.Property;
export var statusBarStyleProperty: styleProperty.Property;
export var androidStatusBarBackgroundProperty: styleProperty.Property;
// Helper property holding most layout related properties available in CSS.
// When layout related properties are set in CSS we chache them and send them to the native view in a single call.
export var nativeLayoutParamsProperty: styleProperty.Property;

View File

@@ -835,6 +835,21 @@ export class Style extends DependencyObservable implements styling.Style {
this._setValue(zIndexProperty, value);
}
// Page-specific properties
get statusBarStyle(): string {
return this._getValue(statusBarStyleProperty);
}
set statusBarStyle(value: string) {
this._setValue(statusBarStyleProperty, value);
}
get androidStatusBarBackground(): Color {
return this._getValue(androidStatusBarBackgroundProperty);
}
set androidStatusBarBackground(value: Color) {
this._setValue(androidStatusBarBackgroundProperty, value);
}
// TabView-specific properties
get tabTextColor(): Color {
return this._getValue(tabTextColorProperty);
@@ -1139,6 +1154,14 @@ export var androidSelectedTabHighlightColorProperty = new styleProperty.Property
new PropertyMetadata(undefined, PropertyMetadataSettings.None, undefined, Color.isValid, Color.equals),
converters.colorConverter);
//Page-specific props
export var statusBarStyleProperty = new styleProperty.Property("statusBarStyle", "status-bar-style",
new PropertyMetadata(undefined));
export var androidStatusBarBackgroundProperty = new styleProperty.Property("androidStatusBarBackground", "android-status-bar-background",
new PropertyMetadata(undefined, PropertyMetadataSettings.None, undefined, Color.isValid, Color.equals),
converters.colorConverter);
// SegmentedBar-specific props
export var selectedBackgroundColorProperty = new styleProperty.Property("selectedBackgroundColor", "selected-background-color",
new PropertyMetadata(undefined, PropertyMetadataSettings.None, undefined, Color.isValid, Color.equals),

View File

@@ -318,6 +318,16 @@
*/
androidSelectedTabHighlightColor: color.Color;
/**
* Gets or sets the style of the status bar.
*/
statusBarStyle: string;
/**
* Gets or sets background color of the status bar for Android
*/
androidStatusBarBackground: color.Color;
/**
* Gets or sets the selected background color of a SegmentedBar.
*/