Friday, May 25, 2012

Flex: Custom Preloader for Flex

Preloaders, something that you can never escape from. Hence I decided to share one of the ways to create a Flex Web Application Preloader.

Some Codings for the fancy preloader swf file.
//This variable will be shown on the screen...
var currentValue:int = 0;
//This variable stores the precentage loaded...
var newValue:int = 0;

//Add a ENTER_FRAME Event so that the preloader will
//animate from the currentValue to the newValue
this.addEventListener(Event.ENTER_FRAME, enterFrameEvent);

//This function will handle the calculation
//between the 2 variables 'currentValue' and 'newValue'
function enterFrameEvent(event:Event):void
{
 if(currentValue < newValue)
 {
  currentValue = newValue;
  updateContent();
 }else if(currentValue == 100)
 {
  this.removeEventListener(Event.ENTER_FRAME, 
     enterFrameEvent);
 }
}

//Update the Progress of the Preloader
//and the Progress Text
function updateContent():void
{
 preloader_mc.gotoAndStop(currentValue);
 percent_txt.text = currentValue + "%";
}

//This function will be called from the 
//Flex Application.
function setPreloader(value:int):void
{
 newValue = value;
}

Main Application File - FlexCustomPreloader.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" 
    layout="absolute" width="100%" height="100%"
    preloader="com.zcs.CustomPreloader">
 <mx:Script>
  <![CDATA[
   //Embed a heavy dummy asset
   [Embed(source="../resources/music.swf")]
   public var contentClass:Class;
  ]]>
 </mx:Script>
 <mx:VBox width="100%" height="100%" 
    verticalAlign="middle"
    horizontalAlign="center">
  <mx:Label text="Hello World..."/>
 </mx:VBox>
</mx:Application>

Custom Preloader File - CustomPreloader.as
package com.zcs
{
 import flash.display.MovieClip;
 import flash.display.Sprite;
 import flash.events.Event;
 import flash.events.ProgressEvent;
 import flash.events.TimerEvent;
 import flash.text.TextField;
 import flash.utils.Timer;
 
 import mx.containers.VBox;
 import mx.controls.SWFLoader;
 import mx.events.FlexEvent;
 import mx.preloaders.DownloadProgressBar;

 public class CustomPreloader extends DownloadProgressBar
 {  
  //Embed a swf that will be used as a preloader
  [Embed(source="../resources/loading2.swf")]
  public var preloaderClass:Class;
  
  private var preloadMovieClip:MovieClip;
  
  //Like the Flash file, _currentPercent will be
  //shown as the current loading progress
  private var _currentPercent:int = 0;
  
  //_maxPercent will be the precentage of the file
  //that has been loaded
  private var _maxPercent:int = 0;
  
  public function CustomPreloader()
  {
   super();
   //Add the preloader swf to the Stage
   preloadMovieClip = new preloaderClass();
   addChild(preloadMovieClip);
  }
  
  // Define the event listeners for the preloader events.
  override public function set preloader(preloader:Sprite):void {
   preloader.addEventListener(
    ProgressEvent.PROGRESS, myHandleProgress);   
   preloader.addEventListener(
    Event.COMPLETE, myHandleComplete);
   
   preloader.addEventListener(
    FlexEvent.INIT_PROGRESS, myHandleInitProgress);
   preloader.addEventListener(
    FlexEvent.INIT_COMPLETE, myHandleInitEnd);
   
   preloader.addEventListener(Event.ENTER_FRAME,
    enterFrameEvent);
  }
  
  //This function will be used to access the content in the swf
  private function getSWFLoaderContent(tempSWF:MovieClip):*
  {
   var tempSWFContent:*;
   var tempSWFContent1:*;
   tempSWFContent = tempSWF.getChildAt(0);
   tempSWFContent = tempSWFContent.content;
   return tempSWFContent;
  }  

  private function enterFrameEvent(event:Event):void
  {
   //If the swf haven't beenn added to the stage 
   //yet, then we will not be doing anything
   if(getSWFLoaderContent(preloadMovieClip))
   {
   }else{
    return;
   }
   
   //Compare _currentPercent and _maxPercent...
   if(_currentPercent < _maxPercent)
   {
    _currentPercent ++;
   }
   
   //And pass it into the preloader swf file
   getSWFLoaderContent(preloadMovieClip).
    setPreloader(_currentPercent);
   
   //Once the flex app has been loaded completely...
   //Trigger a timer for 2 sec and execute 
   //dispatchComplete function after that
   if(_currentPercent == 99)
   {
    var timer:Timer = new Timer(2000,1);
    timer.addEventListener(TimerEvent.TIMER, 
     dispatchComplete);
    timer.start(); 
   }
  }
  
  // Event listeners for the ProgressEvent.PROGRESS event.
  private function myHandleProgress(event:ProgressEvent):void {
   _maxPercent = Math.floor((event.bytesLoaded / event.bytesTotal) * 98);
  }
  
  // Event listeners for the Event.COMPLETE event.
  private function myHandleComplete(event:Event):void {
  }
  
  // Event listeners for the FlexEvent.INIT_PROGRESS event.
  private function myHandleInitProgress(event:Event):void {
  }
  
  // Event listeners for the FlexEvent.INIT_COMPLETE event.
  // When everything is loaded, set _maxPercent to 99
  private function myHandleInitEnd(event:Event):void {
   _maxPercent = 99;
  }
  
  // Event listener for the Timer to pause long enough to 
  // read the text in the download progress bar.
  private function dispatchComplete(event:TimerEvent):void {
   //Pass 100 into the preloader.swf
   getSWFLoaderContent(preloadMovieClip).setPreloader(100);
   dispatchEvent(new Event(Event.COMPLETE));
  }
 }
}
* Click here for the demo.
^ Click here for the source files.

Saturday, May 19, 2012

Android: Queue and Stack

When we talk about Data Structure, the most common terms would most probably be Queue and Stack. A Queue is pretty much the same as a real world Queue (first come first serve theory) and a Stack would be pretty much similar as a Stack of books (first item will be the last to be taken out).

Time to look at my codes. :D
SimpleDataStructureActivity.java
package zcs.dataStructure;

import zcs.utility.dataStructure.Queue;
import zcs.utility.dataStructure.Stack;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class SimpleDataStructureActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        //Grab the TextView first
        TextView txtView;
        txtView = ((TextView)findViewById(R.id.lblView));
        txtView.setText("");
        
        //Following codes shows how to use a Queue
        Queue tmpQueue = new Queue();
        txtView.append("====Queue====\n");
        int tempNum;
        for(int i = 0; i < 5; i ++)
        {
         tempNum = (int) Math.floor(Math.random() * 1000);
            txtView.append("Insert " +
              "" + tempNum + " into Queue\n");
            tmpQueue.push(tempNum);
            txtView.append("Queue has " +
              "" + tmpQueue.length() + " items.\n");
        }
        for(int i = 0; i < tmpQueue.length(); i ++)
        {
         tempNum = ((Integer)tmpQueue.getValue(i));
         txtView.append("Item " + i + "" +
          " has a value of " + tempNum +".\n");
        }
        for(int i = 0; i < 5; i ++)
        {
         tmpQueue.pop();
            txtView.append("Queue has " +
              "" + tmpQueue.length() + " items.\n");
            if(!tmpQueue.isEmpty())
            {
             for(int j = 0; j < tmpQueue.length(); j ++)
             {
              tempNum = ((Integer)tmpQueue.getValue(j));
              txtView.append("Item " + j + "" +
               " has a value of " + tempNum +".\n");
             }
            }
        }
        txtView.append("\n\n");
        
        //Following codes shows how to use a Stack
        Stack tmpStack = new Stack();
        txtView.append("====Stack====\n");
        for(int i = 0; i < 5; i ++)
        {
         tempNum = (int) Math.floor(Math.random() * 1000);
            txtView.append("Insert " +
              "" + tempNum + " into Stack\n");
            tmpStack.push(tempNum);
            txtView.append("Stack has " +
              "" + tmpStack.length() + " items.\n");
        }
        for(int i = 0; i < tmpStack.length(); i ++)
        {
         tempNum = ((Integer)tmpStack.getValue(i));
         txtView.append("Item " + i + "" +
          " has a value of " + tempNum +".\n");
        }
        for(int i = 0; i < 5; i ++)
        {
         tmpStack.pop();
            txtView.append("Stack has " +
              "" + tmpStack.length() + " items.\n");
            if(!tmpStack.isEmpty())
            {
             for(int j = 0; j < tmpStack.length(); j ++)
             {
              tempNum = ((Integer)tmpStack.getValue(j));
              txtView.append("Item " + j + "" +
               " has a value of " + tempNum +".\n");
             }
            }
        }
    }
}

Node.java
package zcs.utility.dataStructure;

public class Node {
 
 //The Next Node
 private Node _nextNode = null;

 public Node nextNode() {
  return _nextNode;
 }

 public void nextNode(Node _tempNode) {
  this._nextNode = _tempNode;
 }
 
 //The Prev Node
 private Node _prevNode = null;

 public Node prevNode() {
  return _prevNode;
 }

 public void prevNode(Node _tempNode) {
  this._prevNode = _tempNode;
 }

 //THe Node data
 private Object _data = null;
 
 public Object data() {
  return _data;
 }

 public void data(Object _data) {
  this._data = _data;
 }
}

List.java
package zcs.utility.dataStructure;

public class List {
 protected Node head = null;

 /**
  * Number of items in the list
  * @return int
  */
 public final int length()
 {
  int count = 0;
  Node tempNode = null;
  tempNode = head;
  if(!isEmpty())
  {
   count = 1;
   while(tempNode.nextNode() != null)
   {
    count ++;
    tempNode = tempNode.nextNode();
   }
  }
  return count;
 }
 
 /**
  * Is the list empty
  * 
* -> true when empty *
* -> false when not empty * @return true or false */ public final boolean isEmpty() { return (head == null); } /** * Get the data of the selected Item in the list * based on count * @return Object */ public Object getValue(int count) { Node tempNode = null; int tempCount = 0; if(isEmpty()) { return null; }else{ if(this.length() < count) { return null; }else{ tempNode = head; while(tempCount != count) { tempCount ++; tempNode = tempNode.nextNode(); } return tempNode.data(); } } } /** * Push a Object into the List */ public void push(Object tempObj) { Node newNode = new Node(); newNode.data(tempObj); Node tempNode; if(!isEmpty()) { tempNode = head; while(tempNode.nextNode() != null) { tempNode = tempNode.nextNode(); } tempNode.nextNode(newNode); newNode.prevNode(tempNode); }else{ head = newNode; } } /** * Pop item from the List * @return Object */ public Object pop() { return null; } }

Queue.java
package zcs.utility.dataStructure;

public class Queue extends List {
 /**
  * Pop first item from the List
  * @return Object
  */
 public Object pop()
 {
  Node tempNode = null;
  Node nextNode = null;
  if(!isEmpty())
  {
   tempNode = head;
   if(tempNode.nextNode() != null)
   {
    nextNode = tempNode.nextNode();
    nextNode.prevNode(null);
   }
   head = nextNode;
   tempNode.nextNode(null);
   return tempNode.data();
  }else{
   return null;
  }
 }
}

Stack.java
package zcs.utility.dataStructure;

public class Stack extends List {
 /**
  * Pop last item from the List
  * @return Object
  */
 public Object pop()
 {
  Node tempNode = null;
  Node prevNode = null;
  if(!isEmpty())
  {
   tempNode = head;
   while(tempNode.nextNode() != null)
   {
    tempNode = tempNode.nextNode();
   }
   prevNode = tempNode.prevNode();
   if(prevNode != null)
   {
    prevNode.nextNode(null);
   }else{
    head = null;
   }
   tempNode.prevNode(null);
   return tempNode.data();
  }else{
   return null;
  }
 }
}

AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="zcs.dataStructure"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="7" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:name=".SimpleDataStructureActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

* Click here for the source files.

Friday, May 11, 2012

Android: Drag And Drop List

I was thinking since Flex has a Drag and Drop List, Android should have 1 too. Hence, my long search for a Drag and Drop List begins... I managed to find one on the blogspot 'TICE' and I decided to enhance it a bit.

Added features:
  • Besides dragging, upon on the other hotspot of the list, a Toast Message Box will be shown indicating the id of the item
  • Upon dropping an item, display a simple Error Log with the new sequence of items
  • Some visual change

* Click here for the blogspot 'TICE'.
^ Click here for the post on drag and drop list on 'TICE'.
~ Click here for the Drag and Drop List that I had enhanced.

Friday, May 4, 2012

Flash as3: Multiple Facebook Image Upload

Someone was asking me how to upload numerous images into Facebook the other day, hence I decided to give it a try. I was trying out Batching using the 'GraphAPI_Web_1_8_1.swc' Library but it seems to be broken for uploading a series of images. Hence, I have created a simple workaround for uploading multiple images.


* Click here to take a look at the example that I had created.
^ Click here for the source files of the example that I had created.