Android Question ScrollPosition + DoEvents + Slowness

Luiz Fernando Orlandini

Active Member
Licensed User
Longtime User
Hi there!

I have an APP with a bunch of HorizontalScroll on many Activities, to emulate a image carrousel.

That said in my main view, I have this carrousel with a bunch of key images (people) that onClick event will fire another Activity to display more details about it. I do that using CallSubDellayed, calling a method Show.

The activity starts, pass through the ActivityCreate and executes the Show method like charm.

So, what happens? In the Show method I used to call my Scroll.ScrollPosition(Index * Activity.Width), where Index it's the image that was clicked before.

After that, I used to call DoEvents. Perfect, it works, although after a while my APP starts to become too slow, and some Samsung devices, send to the user an advice to close the APP once they're consuming too much battery/CPU. Dang... The clients start to call the support complaining about that.

Okay, after a bunch of research, we found out that we should avoid the use of DoEvents at all. And once we're using the Scroll, it's highly recommended to call Scroll.ScrollToNow(parameter) instead of ScrollPosition + DoEvents.

We tried that without success :(

The scroll doest not change to the right position. It moves just a little and does not complete all the rotation that is desired. If we include a DoEvents call on it, it works.

But again, I started to receive those alerts from that Samsung Monitor App.

Any thoughts about how to solve/improve that?

Thanks.
 

Luiz Fernando Orlandini

Active Member
Licensed User
Longtime User
Can you share your code of reproduce it in a little project? So I want to see if i am able to help you to optimiz
Let's try with some piece of code. :)

BTW, when I'm in debug, I can't reproduce that. Only in release mode.

This code it's placed in the Main Activity (first carrousel), and will open the second Activity with another carrousel.
B4X:
Sub PanelStudent_Click
    Dim p As Panel = Sender

    For Each a As View In Scroll.Panel.GetAllViewsRecursive
        If (a Is ImageView) Then
            If (a.Tag <> Null And a.Tag = p.Tag) Then
                Dim index As Int
                For i = 0 To Responsible.studentList.Size - 1
                    Dim s As StudentType = Responsible.studentList.Get(i)
                    If (a.Tag = s.studentId) Then
                        index = i
                        Exit
                    End If
                Next
                CallSubDelayed3(TimelineModule, "Show", index, 0)
                Exit
            End If
        End If
    Next
End Sub


This piece of code it's place inside the TimelineModule.
B4X:
Sub Show(Idx As Int, DateAgenda As Long)
    Log("Show " & Idx)

    PageIndex = Idx
    ScrollStudent.Panel.RemoveAllViews
    Dim width As Long = Activity.width * Main.Responsible.studentList.Size
    ScrollStudent.Panel.width = width
    Dim left As Long = 0dip

    For i=0 To Main.Responsible.studentList.Size - 1
        Dim s As StudentType
        s = Main.Responsible.studentList.Get(i)
        ScrollStudent.Panel.AddView(createStudentPanel(s, left), 30, 10, _
                                                    width, _
                                                    ScrollStudent.Height)
        left = left + Activity.width
    Next
     
    page = 0
    clv.Clear

    DoEvents
    ScrollStudent.ScrollPosition = (PageIndex * Activity.width)

    Log("SHOW actualStudent " & PageIndex)
  
    LoadStudentTimeline(PageIndex) 'call the timeline events (JSON API)
End Sub


Each timeline event, will call another Activity that contains another carrousel.
B4X:
Sub timelineAction_Click
    Dim b As Button = Sender
    Dim t As TimelineType = b.Tag
 
    If (t.timelineType = "AgendaType") Then
        DateTime.DateFormat = "dd/MM/yyyy"
        CallSubDelayed3(AgendaModule, "Show", PageIndex, DateTime.DateParse(t.date))
    Else
    'a bunch of different events
    End If

    CallSubDelayed2(Me, "RegisterTimelineRead", t.id)
End Sub


This is the Show method from AgendaModule
B4X:
Sub Show(Idx As Int, DateAgenda As Long)
    Log("Show " & Idx)

    If (DateAgenda = 0) Then
        If (txtAgendaDay.GetDate = 0) Then
            txtAgendaDay.SetDate(DateTime.Now, True)
        End If
    Else
        txtAgendaDay.SetDate(DateAgenda, True) 
    End If

    PageIndex = Idx
    ScrollStudent.Panel.RemoveAllViews
    Dim width As Long = Activity.width * Main.Responsible.studentList.Size
    ScrollStudent.Panel.width = width
    Dim left As Long = 0dip
 
    Scroll.Panel.RemoveAllViews
    Scroll.Panel.width = Scroll.width

    DoEvents

    For i=0 To Main.Responsible.studentList.Size - 1
        Dim s As StudentType
        s = Main.Responsible.studentList.Get(i)
        ScrollStudent.Panel.AddView(createStudentPanel(s, left), 30, 10, _
                                                    width, _
                                                    ScrollStudent.Height)
        left = left + Activity.width
    Next
 
     
    ScrollStudent.ScrollToNow(PageIndex * Activity.width)
'    DoEvents

    Log("SHOW actualStudent " & PageIndex)
    Log("Activity " & Activity.width)
    LoadStudentData(PageIndex) 
End Sub


If you're interest, this one creates the carrousel into all Activities that needs one.
B4X:
Private Sub createStudentPanel(student As StudentType, left As Long) As View
    Dim p As Panel
    p.Initialize("p")
   
    'left = left + 1dip
    Dim u As Utils
    u.Initialize
       
    Dim photoBorder As ImageView
    photoBorder.Initialize("photoBorder")
    photoBorder.Gravity = Gravity.FILL
    Dim b As Bitmap
    b.Initialize(File.DirAssets, "circulo-medio.png")
    photoBorder.Bitmap = b

    Dim StudentPhoto As ImageView
    StudentPhoto.Initialize("StudentPhoto")
    StudentPhoto.Gravity = Gravity.FILL
    StudentPhoto.Bitmap = u.loadPhoto(student.photo)
    StudentPhoto.Tag = student.studentId
   
    Dim PanelStudent As Panel
    PanelStudent.Initialize("AgendaPanelStudent")
    PanelStudent.Color = Colors.Transparent
    PanelStudent.Tag = 1
           
    Dim StudentName As Label
    StudentName.Initialize("StudentName")
    StudentName.Gravity = Gravity.CENTER
    StudentName.TextColor = Colors.White
    StudentName.Text = student.StudentName
    StudentName.Typeface = Typeface.DEFAULT_BOLD
   
    Dim SchoolClass As Label
    SchoolClass.Initialize("SchoolClass")
    SchoolClass.Gravity = Gravity.left
    SchoolClass.TextColor = Colors.White

    Dim SchoolPin As ImageView
    SchoolPin.Initialize("SchoolPin")
    SchoolPin.Gravity = Gravity.FILL
    Dim pin As Bitmap
    pin.Initialize(File.DirAssets, "icon-pin.png")
    SchoolPin.Bitmap = pin
   
    Dim school As Label
    school.Initialize("School")
    school.Gravity = Gravity.left
    school.TextColor = Colors.White

    If (student.School.schoolName = Null) Then
        school.Text = "Não está matriculado numa escola Schoolastic"
        SchoolClass.Text = ""
    Else
        school.Text = student.School.schoolName
        SchoolClass.Text = student.SchoolClass.schoolClassName
    End If
   
   
    Dim top As Long = (ScrollStudent.Height - 0.90*ScrollStudent.Height - 15dip) / 2
   
    p.AddView(StudentName, left, top, 0.80*Activity.Width-left, 30dip)
    top = top + 30dip

    p.AddView(photoBorder, _
                left, _
                top, _
                0.63*ScrollStudent.Height, 0.63*ScrollStudent.Height)
    left = left + 4dip
    p.AddView(StudentPhoto, left, top+4dip, 0.63*ScrollStudent.Height - 8dip, 0.63*ScrollStudent.Height - 8dip)
    p.AddView(PanelStudent, left, top+4dip, 0.63*ScrollStudent.Height - 8dip, 0.63*ScrollStudent.Height - 8dip)

    left = left + StudentPhoto.Width + 15dip       

    p.AddView(SchoolClass, left, top, 0.60*Activity.Width, 30dip)
    top = top + 25dip
    If (student.School.schoolName <> Null) Then
        p.AddView(SchoolPin, left, top+5, 0.10*ScrollStudent.Height, 0.10*ScrollStudent.Height)
        p.AddView(school, left + 0.10*ScrollStudent.Height + 5dip, top, 0.60*Activity.Width-5dip, 30dip)
    Else
        p.AddView(school, left, top, 0.60*Activity.Width-5dip, 50dip)   
    End If

   
    Return p
End Sub
 
Upvote 0
Top