TextView

API Reference: UI.TextView

TextView is rich version of Label

TypeScript code blocks include examples of how to implement, override and components within the theme. You can create page with the UI Editor to make your page compatible with theming and then you can implement themable components programmatically. Once the page is created with the UI Editor, it generates a class under scripts/generated/pages. You can then extend that class with the following TypeScript classes.

TypeScript
JavaScript
TypeScript
import PageSampleDesign from 'generated/pages/pageSample';
import FlexLayout = require('sf-core/ui/flexlayout');
import Application = require('sf-core/application');
import TextBox = require('sf-core/ui/textbox');
import Color = require('sf-core/ui/color');
import TextView = require('sf-core/ui/textview');
import TextAlignment = require('sf-core/ui/textalignment');
//You should create new Page from UI-Editor and extend with it.
export default class Sample extends PageSampleDesign {
myTextView: TextView;
constructor() {
super();
// Overrides super.onShow method
this.onShow = onShow.bind(this, this.onShow.bind(this));
// Overrides super.onLoad method
this.onLoad = onLoad.bind(this, this.onLoad.bind(this));
this.layout.flexDirection = FlexLayout.FlexDirection.ROW;
this.layout.justifyContent = FlexLayout.JustifyContent.CENTER;
this.layout.alignItems = FlexLayout.AlignItems.CENTER;
}
}
/**
* @event onShow
* This event is called when a page appears on the screen (everytime).
* @param {function} superOnShow super onShow function
* @param {Object} parameters passed from Router.go function
*/
function onShow(superOnShow: () => void) {
const { headerBar } = this;
superOnShow();
Application.statusBar.visible = false;
headerBar.visible = false;
}
/**
* @event onLoad
* This event is called once when page is created.
* @param {function} superOnLoad super onLoad function
*/
function onLoad(superOnLoad: () => void) {
superOnLoad();
this.myTextView = new TextView({
text: "TextView"
});
this.layout.addChild(this.myTextView, "myTextView", ".sf-textView", {
width: 120,
height: 60,
backgroundColor: "#00A1F1",
textAlignment: "MIDCENTER"
});
}
JavaScript
const Page = require("sf-core/ui/page");
const extend = require("js-base/core/extend");
const Color = require('sf-core/ui/color');
const FlexLayout = require('sf-core/ui/flexlayout');
const TextView = require('sf-core/ui/textview');
const TextAlignment = require('sf-core/ui/textalignment');
var Page1 = extend(Page)(
function(_super) {
_super(this, {
onShow: function(params) {
Application.statusBar.visible = false;
this.headerBar.visible = false;
}
});
this.layout.flexDirection = FlexLayout.FlexDirection.ROW;
this.layout.justifyContent = FlexLayout.JustifyContent.CENTER;
this.layout.alignItems = FlexLayout.AlignItems.CENTER;
var myText = new TextView({
width: 120,
height: 60,
backgroundColor: Color.create("#00A1F1"),
text: "TextView",
textAlignment: TextAlignment.MIDCENTER
});
this.layout.addChild(myText);
}
);
module.exports = Page1;

Auto Content Size

In a column-flexlayout : If no height and flexgrow set for a label object, it automatically resizes according to text content.

In a row-flexlayout : If no width and flexgrow set for a label object, it automatically resizes according to text content.

AttributedText

Attributed Text, is an "inline" text formatting option. Formatting option can change the following features of the text. A TextView can have more than one or more attributed text.

  • font name

  • font type (weight, bold, italic)

  • text color

  • underline

  • underline color (iOS only)

  • link (touching to a text-block within a TextView trigger the link)

  • text background

TypeScript
JavaScript
TypeScript
import PageSampleDesign from 'generated/pages/pageSample';
import FlexLayout = require('sf-core/ui/flexlayout');
import Application = require('sf-core/application');
import TextBox = require('sf-core/ui/textbox');
import Color = require('sf-core/ui/color');
import TextView = require('sf-core/ui/textview');
import System = require('sf-core/device/system');
import Font = require('sf-core/ui/font');
import AttributedString = require('sf-core/ui/attributedstring');
//You should create new Page from UI-Editor and extend with it.
export default class Sample extends PageSampleDesign {
myTextView: TextView;
constructor() {
super();
// Overrides super.onShow method
this.onShow = onShow.bind(this, this.onShow.bind(this));
// Overrides super.onLoad method
this.onLoad = onLoad.bind(this, this.onLoad.bind(this));
this.layout.flexDirection = FlexLayout.FlexDirection.ROW;
this.layout.justifyContent = FlexLayout.JustifyContent.CENTER;
this.layout.alignItems = FlexLayout.AlignItems.CENTER;
}
}
/**
* @event onShow
* This event is called when a page appears on the screen (everytime).
* @param {function} superOnShow super onShow function
* @param {Object} parameters passed from Router.go function
*/
function onShow(superOnShow: () => void) {
const { headerBar } = this;
superOnShow();
Application.statusBar.visible = false;
headerBar.visible = false;
}
/**
* @event onLoad
* This event is called once when page is created.
* @param {function} superOnLoad super onLoad function
*/
function onLoad(superOnLoad: () => void) {
superOnLoad();
this.myTextView = new TextView({
lineSpacing: 20
});
if (System.OS === "iOS") {
this.myTextView.letterSpacing = 5;
}
else {
// letterSpacing working on ANDROID Lollipop (API-21) AND UPPER
this.myTextView.letterSpacing = 0.3;
}
this.myTextView.onClick = function (link) {
console.log("link " + link);
};
let attributeString = new AttributedString();
attributeString.string = "First\n";
attributeString.foregroundColor = Color.GREEN;
let attributeString2 = new AttributedString();
attributeString2.string = "Second";
attributeString2.link = "Second Link ";
let attributeString3 = new AttributedString();
attributeString3.string = " Third";
attributeString3.link = "Third Link";
attributeString3.backgroundColor = Color.RED;
attributeString3.underline = true;
//@ts-ignore
attributeString3.font = Font.create("TimesNewRomanPS-RegularMT", 30);
//@ts-ignore
attributeString3.ios.underlineColor = Color.YELLOW;
this.myTextView.attributedText = [attributeString, attributeString2, attributeString3];
this.layout.addChild(this.myTextView, "myTextView", ".sf-textView", {
width: null,
height: null,
flexGrow: 1,
maxLines: 0
});
}
JavaScript
const Page = require("sf-core/ui/page");
const extend = require("js-base/core/extend");
const System = require('sf-core/device/system');
const TextView = require('sf-core/ui/textview');
const Color = require('sf-core/ui/color');
const Font = require('sf-core/ui/font');
const AttributedString = require('sf-core/ui/attributedstring');
var Page1 = extend(Page)(
function(_super) {
_super(this, {
onShow: function(params) {
Application.statusBar.visible = false;
this.headerBar.visible = false;
},
onLoad: function(params) {
var textView = new TextView({
flexGrow: 1,
lineSpacing: 20
});
if (System.OS === "iOS") {
textView.letterSpacing = 5;
}
else {
// letterSpacing working on ANDROID Lollipop (API-21) AND UPPER
textView.letterSpacing = 0.3;
}
textView.onClick = function(link) {
console.log("link " + link);
};
var attributeString = new AttributedString();
attributeString.string = "First\n";
attributeString.foregroundColor = Color.GREEN;
var attributeString2 = new AttributedString();
attributeString2.string = "Second";
attributeString2.link = "Second Link ";
var attributeString3 = new AttributedString();
attributeString3.string = " Third";
attributeString3.link = "Third Link";
attributeString3.backgroundColor = Color.RED;
attributeString3.underline = true;
attributeString3.font = Font.create("TimesNewRomanPS-RegularMT",30);
attributeString3.ios.underlineColor = Color.YELLOW;
textView.attributedText = [attributeString, attributeString2, attributeString3];
this.layout.addChild(textView);
}
});
}
);
module.exports = Page1;

Letter Spacing

The implementation is differs in both OS. iOS accepts point to allocate space between letters. Android accepts 'em' that is the typography unit of font width. According to given text size , em unit is determined such as if given text size is 16 sp then 1em unit is equal to 16 sp. There is also another consideration that em is the width of the widest letter of current language. Such as in English em takes the M letter as widest letter and being considered while spacing.

TypeScript
JavaScript
TypeScript
this.myTextView = new TextView({
lineSpacing: 20
});
let attributeString3 = new AttributedString();
attributeString3.string = " Third";
attributeString3.backgroundColor = Color.RED;
attributeString3.underline = true;
//@ts-ignore
attributeString3.font = Font.create("TimesNewRomanPS-RegularMT", 30);
attributeString3.ios.underlineColor = Color.YELLOW;
// letterSpacing working on ANDROID Lollipop (API-21) AND UPPER
this.myTextView.letterSpacing = (System.OS === "iOS" ? 5 : 5 / attributeString3.font.size);
this.myTextView.attributedText = [attributeString3];
this.layout.addChild(this.myTextView, "myTextView", ".sf-textView", {
width: null,
height: null,
flexGrow: 1,
maxLines: 0
});
JavaScript
var textView = new TextView({
flexGrow: 1
});
var attributeString3 = new AttributedString();
attributeString3.string = " Third";
attributeString3.backgroundColor = Color.RED;
attributeString3.underline = true;
attributeString3.font = Font.create("TimesNewRomanPS-RegularMT", 30);
attributeString3.ios.underlineColor = Color.YELLOW;
// letterSpacing working on ANDROID Lollipop (API-21) AND UPPER
textView.letterSpacing = (System.OS === "iOS" ? 5 : 5 / attributeString3.font.size);
textView.attributedText = [attributeString3];
this.layout.addChild(textView);

TextView vs Label

This comparison is documented within Label guide

IDE support

It is possible to edit attributed text display features within IDE easily. While editing the TextView from design area, double-click causes opening of inline text editor in the design area. For TextView only, IDE is showing an additional dialog to change the formatting of the selected text. The attributed text, for the changed features, may no longer be affected by the properties & styling.

Copy & Paste rich text with UI editor

  • UI editor supports copy-pasting of rich text across TextViews

  • It is possible to copy a rich text from other HTML sources and paste it into TextView. In that case, it may work, it may not. Smartface officially does neither supports nor recommends this approach. Use it at your own risk.

HTML to Attributed Text

Smartface has prepared a html-to-text library, that converts HTML to AttributedText. This library can convert some basic level HTML to AttributedText. UI editor uses this library to convert rich HTML text to with JavaScript. It is possible to observe this behavior in UI editor generated codes.

Using HTML with Dark Theme Support

Since the library takes a static html string and converts them to attributedString, the specified colors will stay as is no matter which Smartface Theme you apply.

Unless you have two different html strings for different themes, you have to specify their colors manually.

import createAttributedStrings from 'sf-extension-utils/lib/html-to-text';
import propFactory from "@smartface/contx/lib/smartface/sfCorePropFactory";
import AttributedString from 'sf-core/ui/attributedstring';
import { getCombinedStyle } from 'sf-extension-utils/lib/getCombinedStyle';
/**
* Consider the two variable has an equivelant value in a different theme.
*/
const textViewTitleStyle = getCombinedStyle('.sf-textview.title');
const textViewLinkStyle = getCombinedStyle('.sf-textview.link');
// Example function for wrapping
function htmlToText() {
const htmlText = '<p>Your HTML text goes here</p>';
const attributedStrings = createAttributedStrings(htmlText);
this.tvMain.onLinkClick = (link) => {
// Your URLs will be opened in the browser of the device
Application.call({ uriScheme: link });
}
attributedStrings.map((string) => {
const as = new AttributedString(propFactory(string));
if (as.link) {
as.foregroundColor = textViewLinkStyle.textColor;
as.underline = true;
//@ts-ignore
as.ios.underlineColor = textViewLinkStyle.textColor
}
else {
as.foregroundColor = textViewTitleStyle.textColor;
}
return as;
});
}

More information about themes can be found at this documentation: