How can i change font size in all flex application?
Write a style like
<mx:Style>
global {
fontSize: 20;
}
</mx:Style>
in your main application. It should be inherited by application contents.
Here is a solution to change the font size at runtime.
You can create a Factory class which will take care of text formatting, so you'll have a single place where to change the font size.
public class OtherClass
{
public function OtherClass()
{
var textfield:TextField = new TextField();
textfield = Factory.formatText(textfield );
textfield.text = "Hello World";
addChild(textfield );
}
}
public class Factory
{
public static function formatText(tf:TextField ):TextField
{
var fontName:String = "YourFont";
var fontSize:int = 12;
var fontColor:uint = 0x000000;
var format:TextFormat = new TextFormat( fontName, fontSize , fontColor );
tf.defaultTextFormat = format;
//etc...
return tf;
}
}
You can , of course , pass other parameters to the function in order to retain some flexibility in your text formatting.
Related
I'm using the mvvm approach to develop a barcode scanning app with xamarin. The main hurdle was that the 3rd party scanner object does not work in xaml. I used a ContentPage to create a simple logic-less c# code view which allows me to have a footer with buttons and a logo overlayed at the bottom of the scanner. My problem is that could not find any great best practices for binding items from your code view to your viewModel, as opposed binding a xaml view to a viewModel. Here is some of my view below.
public class BarcodeScannerPage : ContentPage
{
ZXingScannerView zxing;
BarcodeViewModel viewModel;
public BarcodeScannerPage() : base()
{
try
{
viewModel = new BarcodeViewModel();
BindingContext = viewModel;
zxing = new ZXingScannerView
{
HorizontalOptions = LayoutOptions.FillAndExpand,
VerticalOptions = LayoutOptions.FillAndExpand,
Options = new MobileBarcodeScanningOptions
{
TryHarder = true,
DelayBetweenContinuousScans = 3000
},
ScanResultCommand = viewModel.GetResult
};
var cancelButton = new Button
{
BackgroundColor = Color.Gray,
Text = "Cancel",
TextColor = Color.Blue,
FontSize = 15,
Command = viewModel.CancelButton
};
Binding cancelBinding = new Binding
{
Source = viewModel.CancelIsAvailable,
//Path = "ShowCancel",
Mode = BindingMode.OneWay,
};
cancelButton.SetBinding(IsVisibleProperty, cancelBinding);
var doneButton = new Button
{
BackgroundColor = Color.Gray,
Text = "Done",
TextColor = Color.Blue,
FontSize = 15,
Command = viewModel.DoneButton
};
Binding doneBinding = new Binding
{
Source = viewModel.DoneIsAvailable,
//Path = "ShowDone",
Mode = BindingMode.OneWay,
};
doneButton.SetBinding(Button.IsVisibleProperty, doneBinding);
When a barcode is scanned my command, GetResultCommand, sends the result to my BarcodeView model. I have created two Bools in my BarcodeView model named isDoneAvailable and isCancelAvailable. I want to bind these values to the Visibility property of the doneButton and cancelButton in my view. Right now the buttons are bound to whatever the bool values are at the creation of BarcodeViewModel, but they DO NOT update. I need to be able to control visibility from the GetResultCommand method of my BarcodeViewModel. Specifically, when a certain number of barcodes are scanned, I want to make the buttons appear and disappear. I have a feeling they don't update because the path is not set, but when I uncomment the path, the binding doesn't work at all. Any ideas what I've done wrong with the bindings of the buttons, or the correct way to set the Path to my bools in the viewModel? Here is some of my BarcodeViewModel code below.
public class BarcodeViewModel : INotifyPropertyChanged
{
public bool CancelIsAvailable { get { return _cancelIsAvailable; } set { _cancelIsAvailable = value; OnPropertyChanged("ShowCancel"); } }
public bool DoneIsAvailable { get { return _doneIsAvailable; } set { _doneIsAvailable = value; OnPropertyChanged("ShowDone"); } }
public void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this,
new PropertyChangedEventArgs(propertyName));
}
}
I still would like to know the correct way to get this binding to update but, I was able to work-around this issue by creating a button in my viewModel and referencing it in my view. Then when I dynamically updated the button in my viewModel, it also updated in my view.
I need to customize my alert box with two button and both the button need to have different skins on them.
I was able to do it for one skin. But i am unable to figure out about the two skins.
My code that i have right now is below:
public function Messages():void
{
Alert.buttonWidth = 100;
Alert.yesLabel = "Accept";
Alert.noLabel = "Reject";
var alert:Alert = Alert.show("Accept video chat request from "+far_alias+"?", "Incoming Video Chat Request", Alert.YES | Alert.NO | Alert.NONMODAL, Sprite(Application.application), handleIncomingCallResponse, null, Alert.YES);
alert.data = cm;
alert.name = alert_name;
alert.styleName = "requestVideoAlert"
_alertDic[alert_name] = alert;
Alert.yesLabel = "Yes";
Alert.noLabel = "No";
}
And the Css code is below:
<mx:Style>
.requestVideoAlert
{
background-color: #000000;
back-color: #000000;
area-fill:#000000;
border-color:#000000;
dropShadowEnabled: false;
button-style-name: cancelbtn;
}
.cancelbtn
{
skin: Embed(source='assets/images/videoChat-cancel-button.png');
}
This give the same skin on both the buttons "Accept" and "Reject"
Can some one help me with this.
Thank you
Zee
I dont know if you already found an solution but if no and you use flex 3 I can help you.
This code should do what you need.
Changing buttons and even changing style for text on buttons.
'
protected function application1_creationCompleteHandler(event:FlexEvent):void
{
initStyles();
var myAlert:Alert = Alert.show("description", "title", Alert.YES | Alert.NO);
var arrOfButtons:Array = myAlert.mx_internal::alertForm.mx_internal::buttons;
var button1:Button = arrOfButtons[0];
var button2:Button = arrOfButtons[1];
// buttons filters
button1.styleName = 'buttonStyle1';
button2.styleName = 'buttonStyle2';
button1.addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
}
private function onAddedToStage(event:Event):void
{
// you can change text on buttons as well
var btn:Button = event.target as Button;
var text:UITextField = btn.getChildAt(0) as UITextField;
text.filters = [ new GlowFilter(0x3946C0, 1, 4, 2, 8)];
}
/**
* set style of remove button for alert
**/
private function initButton1Style():void
{
var buttonStyle1:CSSStyleDeclaration = new CSSStyleDeclaration('buttonStyle1');
buttonStyle1.setStyle('fontWeight', "normal");
buttonStyle1.setStyle('fontColor', 0x000000);
buttonStyle1.setStyle('color', 0x000000);
buttonStyle1.setStyle("fillColors", [ 0xffffff, 0xF5A2A2, 0xF5A2A2, 0xffffff ]);
buttonStyle1.setStyle('fontSize', 10);
buttonStyle1.setStyle('themeColor', 0xff0000);
StyleManager.setStyleDeclaration(".buttonStyle1", buttonStyle1, true);
}
/**
* set style of buy button for alert
**/
private function initButton2Style():void
{
var buttonStyle2:CSSStyleDeclaration = new CSSStyleDeclaration('buttonStyle2');
buttonStyle2.setStyle('fontWeight', "normal");
buttonStyle2.setStyle('fontColor', 0x000000);
buttonStyle2.setStyle('color', 0x000000);
buttonStyle2.setStyle("fillColors", [ 0xffffff, 0xBAFFAB, 0xBAFFAB, 0xffffff ]);
buttonStyle2.setStyle('fontSize', 10);
buttonStyle2.setStyle('themeColor', 0x7CCB6C);
StyleManager.setStyleDeclaration(".buttonStyle2", buttonStyle2, true);
}
private function initStyles():void
{
initButton1Style();
initButton2Style();
}
]]>
</mx:Script>
'
Unfortunately, I don't think there's a simple way of doing this - the button styles are set in AlertForm by looping through all the buttons on the Alert and setting their stylename to buttonStyleName. In order to set seperate button styles, I think you'd have to extend both Alert (to use a custom AlertForm class) and AlertForm (to override styleChanged to assign seperate style names).
Try this:
package utils
{
import flash.events.EventDispatcher;
import mx.controls.Alert;
import mx.controls.Button;
import mx.core.mx_internal;
public class AlertUtility extends EventDispatcher
{
use namespace mx_internal;
public static function getYesNoAlert(title:String, message:String,closeFunction:Function):void{
var myAlert:Alert = Alert.show(message, title, Alert.YES | Alert.NO,null,closeFunction,null,Alert.NO);
var arrOfButtons:Array = myAlert.mx_internal::alertForm.mx_internal::buttons;
var button1:Button = arrOfButtons[0];
var button2:Button = arrOfButtons[1];
button1.styleName = 'alertBtnStyle1';
button2.styleName = 'alertBtnStyle2';
}
}
}
and in your style css:
mx|Button.alertBtnStyle1 {
skin: ClassReference("skins.myEmphasizedSkin");
/* desired style */
}
mx|Button.alertBtnStyle2 {
emphasizedSkin: ClassReference("skins.myButtonDefaultSkin");
/* desired style */
}
package {
import mx.controls.LinkButton;
import flash.text.TextLineMetrics;
public class multiLineLinkButton extends LinkButton {
override protected function createChildren():void {
super.createChildren();
if (textField){
textField.wordWrap = true;
textField.multiline = true;
}
}
override public function measureText(s:String):TextLineMetrics {
textField.text = s;
var lineMetrics:TextLineMetrics = textField.getLineMetrics(0);
lineMetrics.width = textField.textWidth;
lineMetrics.height = textField.textHeight;
return lineMetrics;
}
}
my issue here is if you use this component you will see that the text is bunched up into a very small area. It does not fill the entire width of the linkButton. Anyone know why this is happening?
The container is probably not wide enough. Set the container percentWidth to 100 and see if it fixes your problem. You can also set the LinkButton to a fixed width and see if that helps.
I have created a tree with a custom treeitemrenderer where I have added a textinput box next to each label. My data provider is an ArrayCollection.
When I enter value in the input box, I can see the value fine as I expand or collapse the tree using the disclousure arrow. There is a strange issue when I try to expand and collapse tree from the mxml page with a button click to expand and collapse tree using the following code.
The problem is as I expand or collapse tree, the values I entered in the input boxes appear to be moving.
For example, I have entered 15 in input box 1. When I expand and collapse tree, 15 moves to another input box, and moves to another, and then it moves back to where it was entered as I keep expanding and collapsing the tree. I am still learning Flex. I am not sure what is happening, it is something to do with arraycollection.
Any help would be greatly appreciated. Thanks.
private function expandTree():void{
for (var i:int = 0; i < thisTree.dataProvider.length; i ++){
thisTree.expandChildrenOf(thisTree.dataProvider[i], true)
}
}
private function collapseTree():void{
for (var i:int = 0; i < thisTree.dataProvider.length; i ++){
thisTree.expandChildrenOf(thisTree.dataProvider[i], false)
}
}
Flex item renderers are recycled, which is what is causing your data to walk like this. In your item renderer, I generally find it is useful to cast your data to a bindable value object and override the setter for data.
[Bindable]
private var myBindableValueObject:MyBindableValueObject;
override public function set data(v:Object):void
{
if(v == data)
return;
myBindableValueObject = v as MyBindableValueObject;
super.data = value;
validateNow();
}
You will need to bind the properties of the text input and labels to values in the value object. This will make sure the proper values are displayed at the appropriate location. Using this approach should eliminate the oddities that you are experiencing.
I tried as you suggested but I don't see any changes. Not sure I was able to follow your suggestion. Here is the code. Thanks.
package
{
import mx.collections.*;
import mx.controls.Label;
import mx.controls.TextInput;
import mx.controls.listClasses.*;
import mx.controls.treeClasses.*;
[Bindable]
public class TestSetupTreeItemRenderer extends TreeItemRenderer {
[Bindable]
public var _numQuestion:TextInput;
private var _numOfQuestionText:Label;
private var _listData:TreeListData;
[Bindable]
public var tItem:TestSetupTreeItem;
public function TestSetupTreeItemRenderer():void {
super();
mouseEnabled = false;
}
override protected function createChildren():void {
super.createChildren();
_numQuestion = new TextInput();
_numQuestion.text = "0"; //default
_numQuestion.width = 45;
_numQuestion.height = 20;
_numQuestion.restrict = "0123456789";
addChild(_numQuestion);
_numOfQuestionText = new Label();
_numOfQuestionText.width = 60;
_numOfQuestionText.height = 22;
addChild(_numOfQuestionText);
}
override public function set data(value:Object):void {
if(value == data)
return;
tItem= value as TestSetupTreeItem;
super.data = value;
validateNow();
}
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void {
super.updateDisplayList(unscaledWidth,unscaledHeight);
if(super.data){
tItem = super.data as TestSetupTreeItem;
this.label.width = 150;
this.label.truncateToFit(null);
this.label.multiline = true;
this.label.wordWrap = true;
var tld:TreeListData = TreeListData(super.listData);
this._numOfQuestionText.text = "of " + tItem.totalQuestionCount;
this._numOfQuestionText.x = 300;
this._numOfQuestionText.y = super.label.y;
this._numQuestion.x = 200;
this._numQuestion.y = super.label.y;
this._numQuestion.editable = true;
tItem.desiredQuestionCount = this._numQuestion.text;
}
}
}
}
I have a custom ActionScript component that I'm using in a Flex application (Flex 3.3, ActionScript 3). This component contains an Image control whose visibility is set dynamically based on a property of the data element provided to the component.
The problem is that even when I set the image to be visible, it will not render onscreen. Is there something specific I need to do in order for the image to render? Snippets of relevant code below:
override public function set data( value:Object ):void
{
_data = value;
if( _data ) {
if( _myImg ) {
_myImg.source = someImageClass;
_myImg.visible = _data.visibilityProperty;
_myImg.includeInLayout = _data.visibilityProperty;
_myImg.invalidateProperties();
_myImg.invalidateDisplayList();
}
}
invalidateProperties();
invalidateDisplayList();
}
override protected function createChildren():void
{
super.createChildren();
if( !_myImg ) {
_myImg = new Image();
_myImg.height = 16;
_myImg.width = 16;
addChild( _myImg );
}
}
override protected function updateDisplayList( unscaledWidth:Number, unscaledHeight:Number ):void
{
super.updateDisplayList( unscaledWidth, unscaledHeight );
_myImg.x = calculatedXCoordinate;
_myImg.y = calculatedYCoordinate;
}
Did you add the component to the display list? It looks like you've added the image to the displaylist of the component, but potentially haven't done anything with the component itself.
It turns out the the above code I posted will, in fact, work properly. I discovered that due to a copy-and-paste bug that I should have caught, I wasn't adding the Image to the display list, hence why it was never appearing.