I need to create the attached jpg, but i'm not sure of the best way to tackle it.
The news posts are loaded from XML and will vary in height so they need to somehow be sorted so that if one is going to come off the page, then it's put into the next page - where the user will click the scroll buttons to view.
Would something like this be a good way to tackle this?
1/ Load article from XML
2/ Create a postMC_0 and add article bits to it (date, title, body)
3/ Record height
4/ Create a newsColumn_0 and add postMC_0 to it
Then a loop:
5/ Load next article
6/ Create a postMC_1 and add article bits to it
7/ If difference between postMC_0 height and newsColumn_0 height is greater than the height of postMC_1, then add postMC_1 to newsColumn_0.
8/ If not, then create newsColumn_1 and add postMC_1 to it.
9/ Loop back to 5 (increasing the numbers each time, so postMC_2, etc)
Then just make the scroll buttons function according to how many columns have been created..
Do not use a naming convention when you really want a collection. That is, don't create postMC_0, postMC_1, etc, but create an array for them instead.
Code:
var posts:Array = [];
posts.push(somepost);
Similarly for the columns. Though I don't think you actually need multiple columns unless they will actually be showing at the same time. You could just move the posts in and out of the column.
Do not use a naming convention when you really want a collection. That is, don't create postMC_0, postMC_1, etc, but create an array for them instead.
Code:
var posts:Array = [];
posts.push(somepost);
Similarly for the columns. Though I don't think you actually need multiple columns unless they will actually be showing at the same time. You could just move the posts in and out of the column.
how would i separate each post each containing 3 elements, if i'm using an array? Wouldn't it then just be a really long array of info, rather than being organised?
Or would i have an array per post?
This is my AS so far... using the post_mc idea..
Actionscript Code:
for(var i:int = 0; i<myXML.news.length(); i++){
var newsPost_mc = newMovieClip(); var newsDate = newTextField(); var newsTitle = newTextField(); var newsBody = newTextField();
The array has nothing to do with the visual representation. It's a logical construct that lets you deal with a collection of items in an easy way.
Well, I'd make a class for NewsPost, but that looks like a decent start. Why are you putting each at i*100? You could put them at the last NewsPost height + last NewsPost y. That would have them follow each other exactly. Are you trying to do the multicolumn thing now or just get one working first?
I was just putting i*100 temporarily to space the posts out while i worked on them.
This is my AS now.. finding it difficult to position them according to the last post's Y, they seem to be spacing themselves a lot further apart than they should.. have i got this all wrong?
Actionscript Code:
for(var i:int = 0; i<myXML.news.length(); i++){
var newsPost_mc = newMovieClip(); newsPost_mc.opaqueBackground = 0xCCCCCC;
var newsDate = newTextField(); var newsTitle = newTextField(); var newsBody = newTextField();
It looks like you did not set autosize on the title or date, but you are explicitly sizing them. Your lastMCh and lastMCy aren't actually the lastMC's anything. You're setting them to the properties of the same ones you're about to manipulate. And you were trying to use the height of newsPost before you'd sized and placed all its content.
Also, you're not even using those names, so don't bother with them. And if you were to bother naming them, do not append the index. You should be putting each newsPost in an array, and then you can just get the post parts from that post.
I would take most of that code which builds the post and put it in a NewsPost class.
Code:
package {
//imports here.
public class NewsPost extends Sprite{
public var newsDate:TextField;
public var newsTitle:TextField;
public var newsBody:TextField;
public function NewsPost(date:String, title:String, body:String, dateFormat:TextFormat){
opaqueBackground = 0xCCCCCC;
newsDate = new TextField();
newsTitle = new TextField();
newsBody = new TextField();
newsDate.embedFonts = true;
newsTitle.embedFonts = true;
newsBody.embedFonts = true;
newsBody.wordWrap = true;
newsBody.autoSize = TextFieldAutoSize.LEFT;
newsDate.antiAliasType = AntiAliasType.ADVANCED;
newsTitle.antiAliasType = AntiAliasType.ADVANCED;
newsBody.antiAliasType = AntiAliasType.ADVANCED;
newsDate.defaultTextFormat = dateFormat;
newsTitle.defaultTextFormat = dateFormat;
newsBody.styleSheet = IStyleSheet(Gaia.api.getPage("index").assets.stylesheet).style;
newsDate.text = date;
newsTitle.text = title;
newsBody.htmlText = body;
addChild(newsDate);
addChild(newsTitle);
addChild(newsBody);
// Positions & Sizing
newsTitle.y = 0;
newsDate.width=100;
newsDate.height=30;
newsTitle.width = 300;
newsTitle.height = 30;
newsTitle.x = 80;
newsDate.x = 0;
newsDate.y= 0;
newsBody.x = 80;
newsBody.y = newsTitle.height;
newsBody.width=350;
}
}
}
And then you can shorten the loop to:
Code:
var posts:Array = [];
var lastY:Number = 0;
for (var i:int = 0; i<myXML.news.length(); i++){
//may have to convert these with toString if they don't just work
var date:String = myXML.news.newsDate[i];
var title:String = myXML.news.newsTitle[i];
var body:String = myXML.news.newsBody[i];
var newsPost:NewsPost = new NewsPost(date, title, body, dateFormat);
posts.push(newsPost);
sectionpage.newsColumn.addChild(newsPost);
newsPost.y = lastY;
lastY += newsPost.height;
}
Thanks so much for that, it works. Now trying to understand why this works and where i was going wrong...I think i get it:
1/ Create an empty array called posts
2/ Then with each loop:
- create a newsPost_mc as a Sprite (why not movieclip?)
- add a newsPost_mc to the posts array
- Set all the styling, assign the xml text to each textfield
- set newsPost_mc.y to y (on first loop will be 0)
- record current newsPost_mc y + height ready for next loop
Just to help me understand - Why is it necessary to use an Array here? Will it help for the next part of only showing posts that fit into the container mc?
The array is not strictly necessary here. But whenever you have a collection of objects that you will want to manipulate together, it's a good idea. Basically, if you were ever going to name something "somename_"+i, you should be using an array instead.
I used Sprite rather than MovieClip because we didn't need anything that MovieClip provides that Sprite doesn't. newsPost does not have frames, and does not need to be dynamic. It does need to be a DisplayObjectContainer, so the thing that most closely suits those requirements is Sprite. Until we build our own NewsPost class.
Yes, you could go through the array after building it like this and move stuff into other columns, but if you're actually creating separate columns, you could have partitioned the posts in the first loop. Let's say sectionpage can have an arbitrary number of columns that are at most columnHeight tall. We'll store these columns in an array property of sectionpage called columns. It's up to you how you want to show them, whether they are all displayed at once or you replace the showing one as you move through. I'll write code assuming they're all showing at once.
Code:
var posts:Array = [];
var lastY:Number = 0;
//assume sectionpage.columns is an array containing one empty column.
//assume columnHeight is a Number and is already set.
var column:DisplayObjectContainer = sectionpage.columns[0];
for (var i:int = 0; i<myXML.news.length(); i++){
//may have to convert these with toString if they don't just work
var date:String = myXML.news.newsDate[i];
var title:String = myXML.news.newsTitle[i];
var body:String = myXML.news.newsBody[i];
var newsPost:NewsPost = new NewsPost(date, title, body, dateFormat);
posts.push(newsPost);
if (lastY + newsPost.height > columnHeight){
var nextX:Number = column.x + column.width;
column = new Sprite();
column.x = nextX;
sectionpage.columns.push(column);
sectionpage.addChild(column);
lastY = 0;
}
column.addChild(newsPost);
newsPost.y = lastY;
lastY += newsPost.height;
}
For extra credit, what happens when a single post is taller than columnHeight?
Again, we are not using these arrays yet, but we're setting them up because we almost certainly will want easy access to columns and posts. You may want to change posts from its current scope to each column having its own array of posts. Or you may want both. It depends on what you will be doing with them later.
The news posts shouldn't be longer than the columnHeight, will just place a word limit on it for now.
So currently the news posts are loading into newsColumn movieclip which is placed on the stage.. so to make way for the columns, this needs to be scrapped?
And in its place, i create an array here, and columnHeight var:
code:
var posts:Array = [];
var lastY:Number = 0;
var columns:Array = [];
var columnHeight:Number = 330;
It's giving me an error like this, i guess i've got the columns array part wrong?
If you do that from within code on sectionpage, replace "sectionpage" with "this". If you have created your own class for sectionpage... no, you haven't done that.
Then sectionpage doesn't exist yet where you put that code. It might be best to put it on sectionpage itself, or just after you create sectionpage (in the frame where it shows up).
This is invalid syntax. It should have resulted in a compile error before you ever had a chance to get the runtime 1009 error. Remove that line since the next one down does it the right way.
I was assuming that newsColumn was a child of sectionpage, since it made sense to me that a section would have columns. That does not appear to be the case, so you can try to put columns on the NewsPage itself. Where you have sectionpage.columns above, replace it with just columns. And declare a columns array variable in NewsPage. Also, obviously, add the new column to "this" rather than sectionpage.
Then the new columns SHOULD be added to sectionpage. And sectionpage.newsColumn should be put in columns rather than the unused newsColumn property you seem to have declared in NewsPage.
Gaia Framework (AS3) v3.2.3
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at com.thefactory.pages::NewsPage/transitionIn()
at com.gaiaframework.assets::PageAsset/transitionIn()
at com.gaiaframework.core::TransitionController/pageIn()
at com.gaiaframework.core::TransitionController/onTransitionInComplete()
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at com.gaiaframework.assets::PageAsset/onTransitionInComplete()
at com.gaiaframework.assets::PageAsset/transitionIn()
at com.gaiaframework.core::TransitionController/pageIn()
at com.gaiaframework.core::TransitionController/onTransitionInComplete()
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at com.gaiaframework.assets::PageAsset/onTransitionInComplete()
at com.gaiaframework.assets::PageAsset/transitionIn()
at com.gaiaframework.core::TransitionController/pageIn()
at com.gaiaframework.core::TransitionController/transitionIn()
at com.gaiaframework.core::SiteController/onTransitionIn()
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at com.gaiaframework.core::GaiaHQ/beforeTransitionInDone()
at com.gaiaframework.core::GaiaHQ/onEvent()
at com.gaiaframework.core::GaiaHQ/beforeTransitionIn()
at com.gaiaframework.flow::FlowManager$/transitionIn()
at com.gaiaframework.flow::NormalFlow$/afterPreloadDone()
at com.gaiaframework.flow::FlowManager$/afterPreloadDone()
at com.gaiaframework.core::GaiaHQ/afterPreloadDone()
at com.gaiaframework.core::GaiaHQ/onEvent()
at com.gaiaframework.core::GaiaHQ/afterPreload()
at com.gaiaframework.flow::FlowManager$/preloadComplete()
at com.gaiaframework.core::SiteController/preloaderEnterFrame()