Actionscript 3 - fl.controls.UIScrollBar - setting scrollPosition does not work - actionscript

I have a scroll bar ( fl.controls.UIScrollBar ), which i create dynamically in a class, and add it to the stage.
public class Slider extends Sprite
{
private var scroll:UIScrollBar = new UIScrollBar();
// etc.
// constructor
addChild(scroll);
scroll.setSize(15.75, 205.3);
scroll.direction = ScrollBarDirection.HORIZONTAL;
scroll.setScrollProperties(150, minScrollPos, maxScrollPos,snapInterval);
scroll.addEventListener(ScrollEvent.SCROLL, scrollHandler);
}
Then, I try to call
scroll.scrollPosition = 30;
My method call will not update the scroll thumb.Any ideas why?

Salut Mihai,
I found that odd at first. I expected setting the value would suffice.
If I set scrollPosition in an enter frame loop, it works, but not if I use the setter straight away. This probably means that if you make the calls right after creating/setting up the component, internally, it's not ready yet. UIComponents(like UIScrollBar) have a whole lifecycle to deal with. Jeff Kamerer has a nice set of devnet articles on this, if you're interested.
Long story short, the component is not ready right away, so the best bet is to wait for it to be ready by listening to the RENDER event:
scroll.addEventListener(Event.RENDER,rendered);
function rendered(event:Event):void {
scroll.removeEventListener(Event.RENDER,rendered);
scroll.scrollPosition = 30;
}

Related

Pagination Of ListView On Scrolling In Xamarin.Android

Can Any one help Me on How to Implement on Handling Pagination on Scrolling of listview in xamarin.android .any link or any sample wil be helpful
Well, Android pagination is quite easy in comparison to iOS and can be done as follows:
public class EndlessScrollListener : Java.Lang.Object, Android.Widget.AbsListView.IOnScrollListener
{
private int visibleThreshold = 5;
private int currentPage = 0;
private int previousTotal = 0;
private bool loading = true;
public EndlessScrollListener()
{
}
public EndlessScrollListener(int visibleThreshold)
{
this.visibleThreshold = visibleThreshold;
}
public void OnScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount)
{
if (loading)
{
if (totalItemCount > previousTotal)
{
loading = false;
previousTotal = totalItemCount;
currentPage++;
}
}
if (!loading && (totalItemCount - visibleItemCount) <= (firstVisibleItem + visibleThreshold))
{
// I load the next page of gigs using a background task,
// but you can call any function here.
//new LoadGigsTask().execute(currentPage + 1);
loading = true;
}
}
public void OnScrollStateChanged(AbsListView view, [GeneratedEnum] ScrollState scrollState)
{
// throw new NotImplementedException();
}
}
Then set it to the listview as follows:
List.SetOnScrollListener(new EndlessScrollListener());
Working of code:
visibleThreshold – The minimum amount of items to have below your current scroll position, before loading more.
currentPage – The current page of data you have loaded.
previousTotal – The total number of items in the dataset after the last load.
loading – True if we are still waiting for the last set of data to load.
Next, we have a couple of constructors that allow us to set the visibleThreshold inline if we want.
The first overridden method we have is called every time the list is scrolled. This happens many times a second during a scroll, so be wary of the code you place here. We are given a few useful parameters to help us work out if we need to load some more data, but first, we check if we are waiting for the previous load to finish.
If it’s still loading, we check to see if the dataset count has changed, if so we conclude it has finished loading and update the current page number and total item count.
If it isn’t currently loading, we check to see if we have breached the visibleThreshold and need to reload more data. If we do need to reload some more data, we execute a background task and set the loading flag to true. Thus solving the problem forever!
The last method in the class we do not need, however, if you’re interested, it is primarily used for tracking changes in the scroll action itself via the scrollState parameter.
Finally, the code to call the class creates a new instance of EndlessScrollListener and bind’s it to a ListView of mine. Of course, put your own ListView in place of List.

Double tap using Appium Java 2.0

I couldn't find an implementation of a double tap for Appium that was straightforward and allowed you to pass in the element locator strategy, so here goes:
public static void doubleTapElementBy(By by) {
WebElement el = getDriver().findElement(by);
MultiTouchAction multiTouch = new MultiTouchAction(getDriver());
TouchAction action0 = new TouchAction(getDriver()).tap(el).waitAction(50).tap(el);
try {
multiTouch.add(action0).perform();
} catch (WebDriverException e) {
logger.info("Unable to do second tap on element, probably because element requieres single tap on this Android version");
}
}
You can also try below approach using tap method in TouchAction class.
TouchAction taction = new TouchAction(driver);
taction.tap(tapOptions().withElement(ElementOption.element(YOUR_WebElement))
.withTapsCount(2)).perform();
You will need to add below static import as well:
import static io.appium.java_client.touch.TapOptions.tapOptions;
This is a workaround in pseudocode and possibly there's a more "official" way to do it, but it should do the work if no other solution is available:
Interpretmessages(){
switch(msg)
{
OnClick:
{ if (lastClicked - thisTime() < 0.2) //if it was clicked very recently
{doubleTapped()} //handle it as a double tap
else{lastClicked = thisTime()} //otherwise keep the time of the tap
} //end of OnClick
} //End of Message Handler
}//End of switch
}//End of messageHandler
If you have access to ready timer functions, you can set a function to be executed 0.2s after the click has gone off:
OnClick: if (!functionWaiting) // has the timer not been set?
{
enableTimer(); // set a function to go off in x time
clicks = 0; //we'll tell it that there's been one click in a couple of lines
} //set it for the first click
clicks++; //if it's already clicked, it'll become 2 (double tap) otherwise it's just one
So, the idea is that when you get a tap, you check if there's been another one recently (a. by checking the relative times, b. by checking if the function is still pending) and you handle it dependingly, only note that you will have to implement a timer so your function fires a bit later so you have time to get a second tap
The style draws upon the Win32's message handling, I'm pretty sure it works there, it should work for you too.
Double tap and hold -- Use below code:
new TouchAction(driver).press(112,567).release().perform().press(112,567).perform();
Double tap -- Use below code:
new TouchAction(driver).press(112,567).release().perform().press(112,567).release().perform();

Loop activated on mouse movement

I'm just going to explain the context so it is clearer.
I made this menu : my menu
I am looking to make an improved and more advanced version of the same menu.
I made an animation of waves on the cofee's surface and am looking to make it loop when the mouse is moving and to stop looping when it's not.
Sorry for the lack of specifications as I am quite new to actionscript, but I hope somebody will be able to help me. :)
Thanks,
Mathieu
Well, you said it - leverage MouseEvent.MOUSE_MOVE to set a conditional in your looping routine.
private var _isMoving:Boolean = false;
stage.addEventListener(MouseEvent.MOUSE_MOVE, checkMouse);
this.addEventListener(Event.ENTER_FRAME, doLoop);
private function checkMouse(e:MouseEvent):void
{
_isMoving = true;
}
private function doLoop(e:Event):void
{
trace("moving =" + _isMoving);
if(_isMoving)
{
// loop animation
}
_isMoving = false;
}
depending on how you want it to work I would do this as follows:
create an animation of wavy coffee
ensure the animation loops
note that clips loop by default, so all you have to do is match the first and last frames!
place the clip at the edge of your current coffee graphic
double click on the graphic to edit it
drag an instance of the looping animation from the library onto the "edge" of the graphic
OR just replace your entire light brown graphic with an animated one that loops
when the mouse is moving, call play on the animated loop clip
when the mouse stops, call stop on the animated loop clip
Some example code would be along the lines of:
public function init():void {
menuClip.addEventListener(MouseEvent.MOUSE_OVER, onMenuRollOver);
menuClip.addEventListener(MouseEvent.MOUSE_OUT, onMenuRollOut);
}
public function onMenuRollOver(event:MouseEvent):void {
stage.addEventListener(MouseEvent.MOUSE_MOVE, onMove);
/* do the stuff you're currently doing to animate the clip here.
something like: coffee graphic height = ease to mouseHeight */
}
public function onMenuRollOut(event:MouseEvent):void {
/* do the stuff you're currently doing to stop the clip here. */
stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMove);
coffeeClip.stop();
}
public function onMove(event:MouseEvent):void {
resetTimer();
coffeeClip.play(); //note: play has no effect when movie is playing (that's ideal in this case)
}
public function resetTimer():void {
if(mouseMovementTimer == null) createTimer();
mouseMovementTimer.reset();
mouseMovementTimer.start();
}
public function createTimer():Timer {
mouseMovementTimer = new Timer(DELAY, 1); //fiddle with the delay variable. Try 500, at first
mouseMovementTimer.addEventListener(TimerEvent.TIMER, stopAnimationLoop);
}
public function stopAnimationLoop(event:TimerEvent):void {
mouseMovementTimer.removeEventListener(TimerEvent.TIMER, stopAnimationLoop); //optional but recommended
mouseMovementTimer = null;
coffeClip.stop();
}
Of course, you would need to do things like call init() and import flash.utils.Timer and initialize variables like mouseMovementTimer, menuClip, coffeeClip and DELAY.
Warning: This code is off the top of my head and untested. So there's likely to be small bugs in it but you should get the general idea:
add a mouse listener when the user mouses over the menu
remove that listener if the user mouses out of the menu
have that listener play the looping movie clip
trigger an event that will stop the looping clip if movement hasn't been detected in a while
once the trigger goes of, stop the clip
The key is in detecting when the mouse stops moving. Flash detects interaction well but does not detect NON-INTERACTION for obvious reasons. One easy way to solve that is to trigger a timer that will go off once too much time has elapsed since the last activity. Then, when the timer triggers, you know action has stopped!
I think that's the key piece to solving your problem. I hope that helps someone in some way.
~gmale

A problem with a randomly coloured background

I use StackOverflow for the first time, so please be friendly and understanding.
Few days ago I got interested in ActionScript. I have downloaded FlashDevelop (a free IDE) and FlexSDK4. Then I have learned the basics from some tutorials.
For now I am not really developing any big project, I'm rather just doing tests.
Anyway, a solution to my problem is really important for me. I have looked for it, but I couldn't find any.
I have just one button and a background in my app. Both the button and the background (below: "bg") are objects of the Sprite class.
When I click the button, the background gets painted with 10x10px squares of random colours.
The problem is that the more times I click the button, the longer time I have to wait until the background changes. And that's not all! I can change the background exactly 54 times! At the 55th time it doesn't change at all.
package {
// some imports here
public class Main extends Sprite {
private var button:Sprite;
private var bg:Sprite;
public function Main ():void {
init();
}
private function init (e:Event=null):void {
addChild (bg);
// in the original code there are some lines here,
// in which the button is created
addChild (button);
button.addEventListener (MouseEvent.CLICK, btnClick);
}
private function btnClick (event:MouseEvent):void {
var x:uint, y:uint, color:uint;
for (y=0; y<30; y++) {
for (x=0; x<40; x++) {
color=Math.round(Math.random()*16777215);
bg.graphics.beginFill (color);
bg.graphics.drawRect (x*10, y*10, 10, 10);
bg.graphics.endFill ();
}
}
}
}
}
The code is so short, because I have removed many void lines. I have left only the important ones.
What is wrong with this code? Please help me.
Thanks in advance.
clear your graphics before the loop
var x:uint, y:uint, color:uint;
bg.graphics.clear();
for (y=0; y<30; y++) {//etc

How do I 'addChild' an DisplayObject3d from another class? (Papervision3d)

Im kind of new in the whole papervision scene.
For a school assignment I'm making a panorama version of my own room using
a cube with 6 pictures in it. It created the panorama, it works great.
But now I want to add clickable objects in it. One of the requirements
is that my code is OOP focused. So that's what I am trying right now.
Currently I got two classes
- Main.as (Here i make the panorama cube as the room)
- photoWall.as (Here I want to create my first clickable object)
Now my problem is: I want to addChild a clickable object from photoWall.as
to my panorama room. But he doesn't show it? I think it has something to do with
the scenes. I use a new scene in Main.as and in photoWall.as. No errors or warnings are reported
This is the piece in photoWall.as were I want to addChild my object (photoList):
private function portret():void
{
//defining my material for the clickable portret
var material : BitmapFileMaterial = new BitmapFileMaterial('images/room.jpg');
var material_list : MaterialsList = new MaterialsList( { front: material, back: material } );
// I don't know if this is nessecary? that's my problem
scene = new Scene3D();
material.interactive = true;
// make the clickable object as a cube
var photoList : DisplayObject3D = new Cube(material_list, 1400, 1400, 1750, 1, 4, 4, 4);
// positioning
photoList.x = -1400;
photoList.y = -280;
photoList.z = 5000;
//mouse event
photoList.addEventListener( InteractiveScene3DEvent.OBJECT_CLICK, onPress);
// this is my problem! I cannot see 'photoList' within my scene!!!
scene.addChild(photoList);
// trace works, so the function must be loaded.
trace('function loaded');
}
Hope you guys can help me out here. Would really be great!
Thanks,
Sandor
you have to render before you can se anything.
missing:
viewport.startRender()
No I already rendered everything in another class.
I figured it out, the answer is: I have to make this class a displayobject3d.
that's it. everything you addchild on the stage now is a displayobject3d.
for details or code..just ask.
view the result of my little project here :
http://www.sandorkerst.com/papervision/bin

Resources