0

I'm trying to use a spark HSlider on a mobile device. I can get the thumb to move just fine in response to the accelerometer. But there are two problems:

1) the thumb flies right off the end of the screen when you tilt it in either direction. I've put in code below to try to stop this but it doesn't work. 2) I've got a little meter needle that is supposed to follow the position of the thumb, i.e. it points at it. This works fine when I drag the thumb -- when the change event is firing -- but not when the accelerometer is making it move. I think (not sure) that this might work if I could force the change event to fire?

Edit: The trace statements show that h.value isn't changing when it's the that accelerometer makes the thumb move. Also I removed a duplicate call to init().

Code:

<?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" title="HomeView" creationComplete="init()">
<fx:Script>
    <![CDATA[
        import flash.sensors.Accelerometer;

        import mx.events.FlexEvent; 

        public var a:Accelerometer = new Accelerometer();
        private var xSpeed:Number = 0;
        private var newX:Number = 0;

        private function init():void
        {
            this.addEventListener( Event.ADDED_TO_STAGE , addedToStageHandler );
        }

        private function addedToStageHandler(e:Event):void
        {
            h.value = h.minimum;
            needle.rotationZ = h.value + 180;

            if(Accelerometer.isSupported)
            {
                a.addEventListener(AccelerometerEvent.UPDATE, readA);
                stage.autoOrients = false;
            }
        }

        private function readA(e:AccelerometerEvent):void
        {
            xSpeed -= e.accelerationX * 5;
            newX = h.thumb.x + xSpeed;
            if(h.thumb.x < 0 )
            {
                newX = 0;
                xSpeed = 0;
            }
            else if (newX > stage.stageWidth - h.thumb.width) //(newX > stage.stageWidth - RADIUS)
            {
                newX = stage.stageWidth - h.thumb.width;
                xSpeed = 0; 
            }
            else
            {
                newX += xSpeed

            }
            h.thumb.x += xSpeed;
            trace("thumb.x = " + h.thumb.x);
            needle.rotationZ = h.value + 180;
            trace("h.value = " + h.value);
            trace("needle.rotationZ = " + needle.rotationZ);
        }

        protected function h_changeHandler(event:Event):void
        {
            // TODO Auto-generated method stub
            needle.rotationZ = h.value + 180;
            trace(needle.rotationZ);
        }
    ]]>
</fx:Script>
<s:HSlider change="h_changeHandler(event)" minimum="-54" maximum="54" id="h" width="300" x="158" y="74"/>
<s:BorderContainer x="158" y="200" width="300" height="1">
    <s:Rect id="needle" x="150" y="0" width="2" height="100" rotation="180">
        <s:fill>
            <s:SolidColor color="#FF0000"/>
        </s:fill>
    </s:Rect>
</s:BorderContainer>
</s:View>
David
  • 703
  • 1
  • 15
  • 31
  • The slider doesnt work for me until you move it with your finger first, then it goes off the screen. Why is init() being called twice? – Drenai Oct 20 '11 at 09:04
  • Hey Brian, Yep, thanks -- that was a mistake. I've removed the second call. It's weird that the component basically falls apart if you use it with the accelerometer. – David Oct 20 '11 at 23:23

1 Answers1

1
  1. Looks like you are moving the thumb's position directly. You should instead be changing the HSlider.value property and letting the component position the thumb accordingly.

  2. The change event only fires if the value of the HSlider is changed via a user interaction (like a drag/click). Sounds like you might want to listen for the valueCommit event which will fire whenever the value of the HSlider changes whether that is programmatically or via user interaction.

sshongru
  • 816
  • 6
  • 6
  • By the way I noticed your View has what appears to be an unnecessary BorderContainer. This component isn't recommended for use in Mobile projects and may lead to performance problems. See this video for more information: http://flexponential.com/2011/10/05/performance-tuning-mobile-flex-applications/ – sshongru Oct 28 '11 at 18:25
  • Hi Steven, yes, I'd noticed that as well and removed it. Thanks. [Note: oddly, it had been suggested by a senior Adobe Flash evangelist at the Blackberry DevCon. Go figure!] – David Nov 12 '11 at 15:39