Android Question How add value to an int within a time range (MS)

Douglas Farias

Expert
Licensed User
Longtime User
Hello everyone, this question may be simple for many of you, but I can't think very well about it, maybe I need some sleep :)

I have a panel and inside it is a centered label with a value ranging from 0 to 255 depending on the touch on the panel.

Ok, it's already working to touch the panel and show the value on the label, values from 0 to 255.

My question is as follows.
When the user drops his finger on the panel.
Case Activity.ACTION_UP

I need to go from the current value to the maximum value which is 255, but this speed should be based on an animation time.

An example:
At this point I am doing the following, when the user drops the panel finger I simply go from the current value to 255. If the user is at 50 I jump from 50 to 255.

I would like to do something like go from 50 to 255 at (x ms time)

I want to show the user something like (in 2000ms for example, 50 to 255 in 2000ms)
50
51
52
...
255

and not simply jump from 50 to 255.
How can I make this calculation based on an animation time?

make a counter, which adds values in an int up to 255 in a time interval X.

Any tips are welcome, I'm very bad at math.

Thanks.
 

Brandsum

Well-Known Member
Licensed User
The reason why it works slower with step=1 when interval is low may be due to other causes, such as other tasks adding a bit of overhead during the sleep period, as for instance happens in debug mode.
Yes I noticed that the sleep function working unexpectedly with less than 100ms. The increment and decrement functions with sleep(10) and sleep(50) was taking the same time to complete.

Really elegant :)
Thanks :)
 
Upvote 0

Douglas Farias

Expert
Licensed User
Longtime User
Now it's accurate as its based on android valueanimator object.
B4X:
Sub Process_Globals
    Dim initVal = 50, maxVal = 255 As Int
    Dim duration = 2000 As Long
    Dim valueanimator,animatorvalue As JavaObject
End Sub

Sub Activity_Create(FirstTime As Boolean)
    valueanimator.InitializeStatic("android.animation.ValueAnimator")
    valueanimator=valueanimator.RunMethodJO("ofInt",Array(Array As Int(initVal,maxVal)))
    valueanimator.RunMethodJO("setDuration",Array(duration))
   
    Dim event As Object = valueanimator.CreateEvent("android.animation.ValueAnimator.AnimatorUpdateListener","Received","")
    valueanimator.RunMethod("addUpdateListener",Array(event))
End Sub


Private Sub Received_Event (MethodName As String, Args() As Object) As Object
    Select MethodName
        Case "onAnimationUpdate"
            animatorvalue = Args(0)
            Activity.Title = animatorvalue.RunMethod("getAnimatedValue",Null)
    End Select
   
End Sub

Sub Activity_Touch (Action As Int, X As Float, Y As Float)
    Select Action
        Case Activity.ACTION_DOWN
            valueanimator.RunMethod("start",Null)
        Case Activity.ACTION_UP
            valueanimator.RunMethod("reverse",Null)
    End Select
End Sub
Thank you @Brandsum.
your example is working, i just made one change, you initialize the listener on the activity create, this is initialized with fixed value, the panel will change the value using the touch.
what i found to fix this is made a sub with your code of initialize and just pass the values to this sub.

B4X:
Sub Atualiza_Animacao (inicial As Int, maximo As Int)
    valueanimator.InitializeStatic("android.animation.ValueAnimator")
    valueanimator = valueanimator.RunMethodJO("ofInt",Array(Array As Int(inicial,maximo)))
    valueanimator.RunMethodJO("setDuration",Array(tempoAnimacao))
    Dim event As Object = valueanimator.CreateEvent("android.animation.ValueAnimator.AnimatorUpdateListener","Animacao","")
    valueanimator.RunMethod("addUpdateListener",Array(event))
End Sub

To use this sub i use this code
B4X:
        'SOLTOU O DEDO
        Case Activity.ACTION_UP
            podeMover = False
            Atualiza_Animacao(0,lbForca.Text)
            valueanimator.RunMethod("reverse",Null)

The code is working perfectly, but I have a question about the sub.

It is possible to see that the sub adds a listener, I'll call the sub several times, is it a problem she keep adding listeners every time I call her? this is a problem ? can there be a crash while doing this?

Do I need to remove the listener before adding another one or is it not necessary to do this?
 
Upvote 0

Brandsum

Well-Known Member
Licensed User
Yes. That might cause some problem in animation. Remove all the listener like below.
B4X:
Sub Atualiza_Animacao (inicial As Int, maximo As Int)
    valueanimator.InitializeStatic("android.animation.ValueAnimator")
    valueanimator = valueanimator.RunMethodJO("ofInt",Array(Array As Int(inicial,maximo)))
    valueanimator.RunMethodJO("setDuration",Array(tempoAnimacao))
    Dim event As Object = valueanimator.CreateEvent("android.animation.ValueAnimator.AnimatorUpdateListener","Animacao","")
    valueanimator.RunMethod("removeAllUpdateListeners",null)
    valueanimator.RunMethod("addUpdateListener",Array(event))
End Sub

And call Atualiza_Animacao only in Action_down event.
 
Upvote 0

Brandsum

Well-Known Member
Licensed User
This is the correct way to remove listeners.
B4X:
Sub Atualiza_Animacao (inicial As Int, maximo As Int)
    if valueanimator.isInitialized then valueanimator.RunMethod("removeAllUpdateListeners",Null)
    valueanimator.InitializeStatic("android.animation.ValueAnimator")
    valueanimator = valueanimator.RunMethodJO("ofInt",Array(Array As Int(inicial,maximo)))
    valueanimator.RunMethodJO("setDuration",Array(tempoAnimacao))
 
    Dim event As Object = valueanimator.CreateEvent("android.animation.ValueAnimator.AnimatorUpdateListener","Received","")
    valueanimator.RunMethod("addUpdateListener",Array(event))
End Sub
 
Last edited:
Upvote 0

Douglas Farias

Expert
Licensed User
Longtime User
This is the correct way to remove listeners.
B4X:
Sub Atualiza_Animacao (inicial As Int, maximo As Int)
    if valueanimator.isInitialized then valueanimator.RunMethod("removeAllUpdateListeners",Null)
    valueanimator.InitializeStatic("android.animation.ValueAnimator")
    valueanimator = valueanimator.RunMethodJO("ofInt",Array(Array As Int(inicial,maximo)))
    valueanimator.RunMethodJO("setDuration",Array(tempoAnimacao))
 
    Dim event As Object = valueanimator.CreateEvent("android.animation.ValueAnimator.AnimatorUpdateListener","Received","")
    valueanimator.RunMethod("addUpdateListener",Array(event))
End Sub
Thank you, its working perfect.
really thanks
 
Upvote 0
Top