Android Question Reverse scrollview?

kostefar

Active Member
Licensed User
Longtime User
Dear all,

If you have a scrollview that will load 50 items sorted by time they wered added, it will take a while, but at the end it´s going to look nice with the most recent item at the bottom.
Now, if the scrollview would be loading the most recent item first, so all in opposite order - that one is easy of course - BUT start showing the items from the bottom of the screen and add each item on top of eachother, without scrolling up, instead of each item below the previous one the way it is now, then you´d never have to wait a while to see the most recent items, and watch the screen loading the whole list.

This would be really convenient, so I´m wondering if there´s a way to make the scrollview behave this way?

I could image setting it up manually: First load all items into a list holding their height, which summed together would tell the scrollview how high it should be. Afterwards you´d load the last, say, 15 items, and while making sure that the scrollview won´t be scrolling, load the remaining 35 entries.
But that´s quiet some work, that probably takes some time to do before it´s succesful.

Ideas appreciated, thanks in advance!
 

kostefar

Active Member
Licensed User
Longtime User
I recommend you to use CustomListView instead of ScrollView.

You can add 50 empty items and scroll to the last one. As the results arrive (assuming that you are downloading something as otherwise it will be very fast) you can fill the items.

Thanks Erel, I think that´s the way to go then!
 
Upvote 0

kostefar

Active Member
Licensed User
Longtime User
I recommend you to use CustomListView instead of ScrollView.

You can add 50 empty items and scroll to the last one. As the results arrive (assuming that you are downloading something as otherwise it will be very fast) you can fill the items.

So since these items have different heights, for this to work the height will later need to be changed after 50 items with a fixed height are being added. But so far I have no succes in doing this. For instance:

B4X:
clv_messages.Add(Pnl1,20dip,"")
Pnl1.Height = 58

Creates the item with a height of 20dip, and it does not change with the next line.
 
Upvote 0

kostefar

Active Member
Licensed User
Longtime User
Never specify dimensions without using 'dip' or percentage.

You can use CLV.ReplaceAt to reset the item's height.

Thanks, but here´s the thing. This would work in scrollview, though with more parameters as required, using reflector:

B4X:
clv_messages.Add(Pnl1,20dip,"")
Pnl1.AddView(lbl1,0%x,0,80%x,-2)
Reflect.Target=lbl1
l1h=Reflect.RunMethod("getHeight")
Pnl1.Height = l1h


Getheight will be 0 if I have not added the label to the panel first, so I´ll have to do it in that order. But since with customlistview I can´t change the height after that the panel has been added, then I´ll need to use replaceat instead, adding the same item one more time with the correct height, but this gives me an error.

B4X:
clv_messages.Add(Pnl1,20dip,"")
Pnl1.AddView(lbl1,0%x,0,80%x,-2)
Reflect.Target=lbl1
l1h=Reflect.RunMethod("getHeight")
Pnl1.Height = l1h
clv_messages.ReplaceAt(clv_messages.GetSize-1,Pnl1,PnlHeight,"")

throws:

B4X:
Error occurred on line: 169 (CustomListView)
java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.

So if I use removeat instead of replace:

B4X:
clv_messages.RemoveAt(clv_messages.GetSize-1)

I get
B4X:
Error occurred on line: 142 (CustomListView)
java.lang.ArrayIndexOutOfBoundsException: length=12; index=-1

But I think I´m doing something wrong in the first place that could be done in a smarter way...
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
You shouldn't use -2 for the panel height. You can use CLV.AddText to create an item with the correct height based on the text.

You can add this sub to the class:
B4X:
Public Sub ResizeItem(Index As Int, ItemHeight As Int)
   Dim p As Panel = GetPanel(Index)
   Dim value As Object = items.Get(Index)
   Dim parent As Panel = p.Parent
   p.Background = parent.Background
   p.RemoveView
   ReplaceAt(Index, p, ItemHeight, value)
End Sub
 
Upvote 0

kostefar

Active Member
Licensed User
Longtime User
You shouldn't use -2 for the panel height. You can use CLV.AddText to create an item with the correct height based on the text.

You can add this sub to the class:
B4X:
Public Sub ResizeItem(Index As Int, ItemHeight As Int)
   Dim p As Panel = GetPanel(Index)
   Dim value As Object = items.Get(Index)
   Dim parent As Panel = p.Parent
   p.Background = parent.Background
   p.RemoveView
   ReplaceAt(Index, p, ItemHeight, value)
End Sub

Thank you Erel, that indeed does the height resizing. However, it´ll only work if the height set initially is more than the one to which it resizes:

B4X:
Pnl1.AddView(lbl1,0%x,0,80%x,10dip)

didn´t work for me but

B4X:
Pnl1.AddView(lbl1,0%x,0,80%x,30dip)

did.

In some cases there´ll be images inserted, so to account for that I´ll need the height to be maybe 400dip in the empty list loaded. I´m good with that except for wondering if 100-200 items with that height won´t be a memory problem, even if they´re empty?

Insertion of text is not an option, as I´m using a GradientDrawable as background for each panel item that contains text.
With scrollview I was also able to change the width of each panel, but here they will take of the full screenwidth regardless of whether if I put

B4X:
Pnl1.Width = txtwidth

before or after adding the panel.

txtwidth is calculated with


B4X:
Dim Bmp As Bitmap
    Bmp.InitializeMutable(10Dip,10Dip)
    Dim Cnv As Canvas
    Cnv.Initialize2(Bmp)
    txtwidth = Cnv.MeasureStringWidth(txt1,Typeface.DEFAULT_BOLD,16) + 2%x


Finally, I still get the previously mentioned errors when using RemoveAt/ReplaceAt...
 
Upvote 0

kostefar

Active Member
Licensed User
Longtime User
The height doesn't affect the memory required.

I didn't get any error when I used ResizeItem.

Ok thanks, good to know about the memory! The errors I´m talking about is what I mentioned earlier when using replaceat or removeat - not when resizing:

B4X:
clv_messages.Add(Pnl1,20dip,"")
Pnl1.AddView(lbl1,0%x,0,80%x,-2)
Reflect.Target=lbl1
l1h=Reflect.RunMethod("getHeight")
Pnl1.Height = l1h
clv_messages.ReplaceAt(clv_messages.GetSize-1,Pnl1,PnlHeight,"")

throws:

B4X:
Error occurred on line: 169 (CustomListView)
java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.

So if I use removeat instead of replace:


B4X:
clv_messages.RemoveAt(clv_messages.GetSize-1)

I get

B4X:
Error occurred on line: 142 (CustomListView)
java.lang.ArrayIndexOutOfBoundsException: length=12; index=-1

And there´s still both change of panel width plus using the "left" parameter from scrollview which I need to be able to replicate under customlistview before I can use this instead.
 
Upvote 0

kostefar

Active Member
Licensed User
Longtime User
Ok thanks, good to know about the memory! The errors I´m talking about is what I mentioned earlier when using replaceat or removeat - not when resizing:



And there´s still both change of panel width plus using the "left" parameter from scrollview which I need to be able to replicate under customlistview before I can use this instead.
The height doesn't affect the memory required.

I didn't get any error when I used ResizeItem.

Allright, the errors from the customscrollview.bas I´ve not yet looked into why are happening, but in the meantime I´ve worked on getting width and left added into the resizeitem sub:
B4X:
Public Sub ResizeItem(Left As Int,Width As Int,Index As Int, ItemHeight As Int)
    Dim p As Panel = GetPanel(Index)
    Dim value As Object = items.Get(Index)
    Dim parent As Panel = p.Parent
    sv.Width = Width
    sv.Left = Left
    p.Background = parent.Background
    p.RemoveView
    ReplaceAt(Index, p, ItemHeight, value)
End Sub

Let me know if you think there´s something totally ineffecient about that solution, and that it could be done in a better way.
EDIT: Bad idea, resized all items in the list to the same.. Hoping for a way to have customlistview work with left and width per item so that it´ll be able to replace scrollview which in my project makes use of these parameters.
 
Last edited:
Upvote 0
Top