How do you set ByteArray to IconItemRenderer in Flex 4? - apache-flex

I am having problems setting a ByteArray image to the "iconField" in IconItemRenderer. I think I'm halfway there as to use the "iconFunction", however what should I call to set the image in "iconField"?
Please help! Thank you in advance.
<s:IconItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
iconFunction="initializeIcon"
iconWidth="45"
iconHeight="45">
<fx:Script>
<![CDATA[
import mx.utils.Base64Decoder;
private function initializeIcon(data:Object):void
{
var imageName:String = data.image; //image is Base64 encoded data from a dynamic array
var byteArr:ByteArray;
var base64Dec:Base64Decoder = new Base64Decoder();
base64Dec.decode(imageName);
byteArr = base64Dec.toByteArray();
//set iconField? what should I do from here on.
}
]]>
</fx:Script>
</s:IconItemRenderer>

This code will solve your problem.
<?xml version="1.0"?>
<s:IconItemRenderer xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:component="spark.components.*"
iconField='byteArray'>
<fx:Script>
<![CDATA[
import mx.utils.Base64Decoder;
override public function set data(value:Object):void {
super.data = value;
var imageName:String = data.image;
var base64Dec:Base64Decoder = new Base64Decoder();
base64Dec.decode(imageName);
data.byteArray = base64Dec.toByteArray();
}
]]>
</fx:Script>
</s:IconItemRenderer>
Just fyi I think it's not best practice to put decoder into item renderer. I would recommend keep it level above.
Also keep in mind that IconItemRenderer is only available for mobile applications.

Related

Flex PopUpAnchor created manually not showing up

I need to create a component using ActionScript. Can't use mxml in this case.
In my component I need to create PopUpAnchor using new operator and addElement to the stage. Unfortunatelly when I'm doing it, the PopUpAnchor's displayPopUp property does not respond to any values.
Here is my the example:
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
initialize="init(event)">
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
import spark.components.Label;
import spark.components.PopUpAnchor;
protected function init(event:FlexEvent):void
{
var anchor:PopUpAnchor = new PopUpAnchor();
var label:Label = new Label();
label.text = 'ABC';
anchor.addChild(label);
addElement(anchor);
anchor.displayPopUp = true;
}
]]>
</fx:Script>
</s:WindowedApplication>
I'm using Flex SDK 4.5 with AIR SDK 2.6.
What am I doing wrong?
I figured it out. The problem is that i connot use addChild on anchor. I should use popUp property instead.
So, this line is WRONG:
anchor.addChild(label);
and should be corrected to this form:
anchor.popUp = label;

How to pass a string from .mxml to .as class in adobe air flex?

I want to pass a string from .mxml to a .as class..For that i tried using[Bindable]..But i
get only null value.How can i get the string from mxml?
I have given the link to show u what i have tried:
http://192.150.16.67/devnet/flex/articles/databinding_pitfalls.html
Please find below code this may help you for your question.
Main.mxml
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<fx:Script>
<![CDATA[
private var stringReaderObject:StringReader;
private function clickHandler():void
{
if(!stringReaderObject)
{
stringReaderObject = new StringReader();
}
stringReaderObject.readString = inputTextID.text;
}
]]>
</fx:Script>
<s:Group x="50" y="50">
<s:layout>
<s:VerticalLayout/>
</s:layout>
<s:TextInput id="inputTextID"/>
<s:Button label="Click" click="clickHandler()"/>
</s:Group>
</s:Application>
Class Name: - StringReader.as
package
{
public class StringReader
{
private var _readString:String;
public function StringReader()
{
}
public function set readString(value:String):void
{
_readString = value;
trace(_readString);
}
public function get readString():String
{
return _readString;
}
}
}
trace will identify how you can pass value from MXML to .as class.
it can be achievable by another 2 ways those are as below: -
1) By creating public variable in you class.
2) By creating global in your application and access it in your class.
hope this may help you.

webstageview not loading on phone but working in emulator

I'm trying to get a webstageview to load a local html file....this code works perfectly on the emulator, but when i run it on my android device (running android 2.3), it does not work....it just creates a blank webstageview that never loads the local html file...the zoom function is intact so i know it's opening the webstageview, but i never see the content....any advice? i am stuck...
<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:ns1="*"
xmlns:controls="com.flexcapacitor.controls.*"
actionBarVisible="false" backKeyPressed="onBackKeyPressed(event)"
creationComplete="view1_creationCompleteHandler(event)" title="{data.image}"
xmlns:components="com.flexcapacitor.components.*">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
import spark.components.ViewNavigator;
public var webView1:StageWebView=new StageWebView();
protected function view1_creationCompleteHandler(event:FlexEvent):void
{
webView1.stage=this.stage;
webView1.viewPort=new Rectangle(0,50,stage.stageWidth, stage.stageHeight);
var fPath:String=new File(new File("app:/"+data.html).nativePath).url;
webView1.loadURL(fPath);
}
protected function onBackKeyPressed(event:FlexEvent):void{
webView1.viewPort = null;
webView1.dispose();
webView1 = null;
}
protected function backbutton_clickHandler(event:MouseEvent):void
{
webView1.viewPort = null;
webView1.dispose();
webView1 = null;
navigator.popView();
}
]]>
</fx:Script>
<s:Button id="backbackbutton" x="0" y="0" width="100%" height="50" label="Back" click="backbutton_clickHandler(event)"/>
i ended up having to make some temporary files to open it properly....not sure why it wouldn't work before even though the emulator worked fine...here's the code that works:
<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:ns1="*"
xmlns:controls="com.flexcapacitor.controls.*"
actionBarVisible="false" backKeyPressed="onBackKeyPressed(event)"
creationComplete="view1_creationCompleteHandler(event)" title="{data.image}"
xmlns:components="com.flexcapacitor.components.*">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
import spark.components.ViewNavigator;
public var webView1:StageWebView=new StageWebView();
protected function view1_creationCompleteHandler(event:FlexEvent):void
{
webView1.stage=this.stage;
webView1.viewPort=new Rectangle(0,50,stage.stageWidth, stage.stageHeight);
var fa:File = File.applicationDirectory.resolvePath(data.html);
var f2a:File = File.createTempDirectory();
var fb:File = File.applicationDirectory.resolvePath(data.location);
fa.copyTo(f2a.resolvePath(data.html),true);
fb.copyTo(f2a.resolvePath(data.location),true);
webView1.loadURL(f2a.url + File.separator +data.html);
}
protected function onBackKeyPressed(event:FlexEvent):void{
webView1.viewPort = null;
webView1.dispose();
webView1 = null;
}
protected function backbutton_clickHandler(event:MouseEvent):void
{
webView1.viewPort = null;
webView1.dispose();
webView1 = null;
navigator.popView();
}
]]>
</fx:Script>
<s:Button id="backbackbutton" x="0" y="0" width="100%" height="50" label="Back"
accentColor="#000000" chromeColor="#404040" click="backbutton_clickHandler(event)"
color="#FFFFFF"/>
Did you add your 'app' folder to your build path so the html file is included in your release build? If not, right click on your project and go to properties > Actionscript Build Path > Source Path > Add Folder...

How to set a public var in a popup window?

I am trying to set a variable in a titlewindow pupup and use it in a script section. The variable is not being set and I don't know why.
Here is my Main.mxml file:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600" creationComplete="application1_creationCompleteHandler(event)">
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
import mx.managers.PopUpManager;
protected function application1_creationCompleteHandler(event:FlexEvent):void
{
var test:TestWindow = TestWindow(PopUpManager.createPopUp(this,TestWindow,true));
PopUpManager.centerPopUp(test);
test.testText = 'test 2';
test.bol = true;
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
</s:Application>
Here is my titleWindow file:
<?xml version="1.0" encoding="utf-8"?>
<s:TitleWindow xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" width="400" height="300"
close="PopUpManager.removePopUp(this);" creationComplete="titlewindow1_creationCompleteHandler(event)">
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
import mx.managers.PopUpManager;
[Bindable] public var testText:String = 'test 1';
public var bol:Boolean = false;
protected function titlewindow1_creationCompleteHandler(event:FlexEvent):void
{
if(bol){
trace('Boolean is true');
}
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:Label text='{testText}'/>
</s:TitleWindow>
The problem is the label does change from 'test 1' to 'test 2' but the bol variable will not be set, why is that?
The creationComplete event fires when your TitleWindow has been completely created and only fires once (see component lifecycle).
In your case this happens in your Main.mxml file when you add the pop up with PopUpManager.centerPopUp(test);. bol is getting updated, you're just not seeing that from a trace statement because the creationComplete event has already fired.
If you want to to change the value for bol with your current setup you'll need to do that prior to opening the pop up.
In general I feel that a better way of doing this would be by using getters and setters and data binding (or Flex's invalidation methods which is described in that first link).
Note: these links provided are for Flex 3 but so far as I know all this holds true in Flex 4.
NoobsArePeople2 is 100% correct about what's going on with the lifecycle. A quick and dirty workaround for this is to use PopUpManager.addPopUp() instead of createPopUp():
var test:TestWindow = new TestWindow();
test.testText = 'test 2';
test.bol = true;
PopUpManager.addPopUp(test, this, true);
PopUpManager.centerPopUp(test);
This should allow you to set the values on TestWindow before it actually gets initialized.
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/managers/PopUpManager.html

Data Grid not displaying data in array collection

My data grid is displaying stale data, rather than the real time data available in it's data provider (array collection). I've tried refeshing the data in the collection, but that has no effect. Below is my code, does anyone see what could be the problem?
<mx:Accordion/>
<fx:Script>
<![CDATA[
private var _gridData:ArrayCollecton = new ArrayCollection;
[Bindable] public function get gridData():ArrayCollection { return _gridData; }
public function set gridData(value:ArrayCollection):void { _gridData = value; }
public function loadGridData():void {
// imgCollection is the data returned from the server
var tempCollection:ArrayCollection = new ArrayCollection();
for (var i:int = 0; i < imgCollection.length; i++)
{
var img:Object = new Object();
img.id = imgCollection.getItemAt(i).imgId;
img.url = "http://..." + imgCollection.getItemAt(i).imgId;
img.caption = (imgCollection.getItemAt(i).imgCaption == null) ? "": imgCollection.getItemAt(i).imgCaption;
img.group = images;
tempCollection.addItem(new ObjectProxy(img));
}
gridData = tempCollection;
<!-- Use http service to get data and save it in grid data array collection, this is run on accordion create completion and whenever data is added or removed from the array collection -->
}
]]>
</fx:Script>
<!-- NOTE: There is a cyclic binding between the data grid and the gridData array collection -->
<fx:Binding source="dg.dataProvider as ArrayCollection" destination="gridData"/>
...
...
<s:NavigatorContent>
<s:Panel>
<mx:DataGrid dataProvider="{gridData}" ...>
...
...
</mx:DataGrid>
</s:Panel>
</s:NavigatorContent>
UPDATE:
I tried the suggestions mentioned below, however, they do not resolve the issue. The data grid has custom item renderers, could that be the problem?
<?xml version="1.0" encoding="utf-8"?>
<s:MXDataGridItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
focusEnabled="true">
<mx:Image id="image" source="{data.url}" height="65" maintainAspectRatio="true" scaleContent="true"/>
</s:MXDataGridItemRenderer>
You don't need "cyclical" binding, because in your datagrid you do not change the collection, but you change its items. The collection stays intact. the dataprovider of the DataGrid and your _gridData point to the same collection.
If I'm not mistaking you should have [Bindable] on the setter as well because the datagrid has not other way of knowing when your data has changed.
Regards, Alin
Looks to me like you are overthinking this. Since you aren't doing anything in your getter/setters you could get rid of them and just mark your ArrayCollection as Bindable, then set it as the dataProvider for the DataGrid and be done:
<fx:Script>
<![CDATA[
[Bindable]
public var gridData:ArrayCollecton = new ArrayCollection;
public function loadGridData():void {
// Whenever you change the gridData, the DataGrid will update appropriately.
}
]]>
</fx:Script>
<mx:DataGrid dataProvider="{gridData}"></mx:DataGrid>
The problem with your existing code is likely that you are not dispatching a change event in your setter. Getting rid of the getter/setters allows the ArrayCollection to handle dispatching that event for you. Hope that helps.
EDIT: Based on the updated question, you may want to try changing your renderer to look like this, which would help if your custom data object is not bindable.
<?xml version="1.0" encoding="utf-8"?>
<s:MXDataGridItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
focusEnabled="true">
<fx:Script>
<![CDATA[
override public function set data(value:Object):void {
super.data = value;
image.source = value.url;
}
]]>
</fx:Script>
<mx:Image id="image" source="{data.url}" height="65" maintainAspectRatio="true" scaleContent="true"/>

Resources