Android Question HorizontalScrollview showing images inside a CustomListView

José J. Aguilar

Licensed User
Hi everyone:

I have a small app with a CustomListView that shows a text description, with a button to make pictures according this description. I want below this, a small expandable panel to show the pictures made in every description.

I'm trying to merge several examples I've seen in the forum:
TabStrip + xCustomListView + Expandable Panel + Scrollview showing pictures.

What I'm trying to do is when you press the item, the panel expand, a progress circle shows "Loading images" and a carrousel of the images is show, but I get lost trying to reach the HorizontalScrollView (I'm still trying to understand the .getpanel property)

The questions/problems I'm facing are:
- I get an error with the AnimatedArrow: java.lang.NullPointerException: Attempt to invoke virtual method 'anywheresoftware.b4a.objects.B4XViewWrapper b4a.example.customlistview._getpanel(b4a.example.customlistview, int)' on a null object reference

It's called from ExpandItem and CollapseItem, these subs get the sender rigth, but it's seem there's no sender when they call AnimatedArrow. I've tried to pass the panel as object, but I get another error. Anyway, I can live without the animated arrow

- DoEvents 'required for the ProgressDialog animation
It's seem to be deprecated, but the Loadimage use it in the sample I saw. Can I just use Sleep(0) as suggested by IDE?

- But my main problem is get the images into the right panel, I don't know how the reach it in this line:
clv.GetPanel(4).AddView(iv, 5dip + i * 200dip, 5dip, HSVFOTOS.Width - 10dip, 190dip)
(4 is just one of the test I made)

- Once I get it working (I hope), is there a way of releasing memory or something like that, because of the pics loaded?

The project is attached

Thanks in advance

#Region  Project Attributes
    #ApplicationLabel: B4A Example
    #VersionCode: 1
    'SupportedOrientations possible values: unspecified, landscape or portrait.
    #SupportedOrientations: unspecified
    #CanInstallToExternalStorage: False
#End Region

#Region  Activity Attributes
    #FullScreen: False
    #IncludeTitle: True
#End Region

#BridgeLogger: true

Sub Process_Globals
    Dim Bitmaps As List
End Sub

Sub Globals
    Private TabStrip1 As TabStrip
    Private LVGenerales, LVEspecificas  As CustomListView
    Private LbPuntoChk, BtCamera, pnlExpanded, pnlPunto As B4XView
    Private HSVFOTOS As HorizontalScrollView
    Private ExpandedHeight As Int = 240dip
    Private CollapsedHeight As Int = 60dip
End Sub

Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    TabStrip1.LoadLayout("tabgenerales", "Type I Pictures")
    TabStrip1.LoadLayout("tabespecificas", "Type II Pictures")
    For Each lbl As Label In GetAllTabLabels(TabStrip1)
        lbl.Width = 50%x
    For i = 0 To 10
        LVGenerales.Add(CrearItemChk("Item " & i, i, LVGenerales.AsView.Width, 60dip), i)
        LVEspecificas.Add(CrearItemChk("Item " & (i+11), i, LVEspecificas.AsView.Width, 60dip), i+11)
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Public Sub GetAllTabLabels (tabstrip As TabStrip) As List
    Dim jo As JavaObject = tabstrip
    Dim r As Reflector
    r.Target = jo.GetField("tabStrip")
    Dim tc As Panel = r.GetField("tabsContainer")
    Dim res As List
    For Each v As View In tc
        If v Is Label Then res.Add(v)
    Return res
End Sub

Sub CrearItemChk(Text As String, Index As Int, Width As Int, Height As Int) As Panel
    Dim p As Panel
    Activity.AddView(p, 0, 0, 100%x, ExpandedHeight)
    p.SetLayout(0, 0, Width, Height)
    p.RemoveView 'remove from parent
    LbPuntoChk.Text = Text
    BtCamera.Tag = Index
    p.Tag = False 'collapsed
    Return p
End Sub

Sub LVGenerales_ItemClick (Index As Int, Value As String)
    Dim p As Panel = LVGenerales.GetPanel(Index)
    If p.Tag = True Then
    End If
End Sub

Sub LVEspecificas_ItemClick (Index As Int, Value As String)
    Dim p As Panel = LVEspecificas.GetPanel(Index)
    If p.Tag = True Then
    End If
End Sub

Sub ExpandItem (index As Int)
    Dim clv As CustomListView = Sender
    clv.ResizeItem(index, ExpandedHeight)
    clv.GetPanel(index).Tag = True
    'AnimatedArrow(index, 0, 180)
End Sub

Sub AnimatedArrow(index As Int, From As Int, ToDegree As Int)
    Dim clv As CustomListView = Sender
    Dim An As AnimationPlus
    pnlPunto = clv.GetPanel(index).GetView(0) 'pnlTitle is the first item
    Dim iv As ImageView = pnlPunto.GetView(1) 'ImageView1 is the second item
    An.InitializeRotateCenter("", From , ToDegree, iv)
    An.Duration = clv.AnimationDuration
    An.RepeatCount = 0
    An.PersistAfter = True
End Sub

Sub CollapseItem(index As Int)
    Dim clv As CustomListView = Sender
    clv.ResizeItem(index, CollapsedHeight)
    clv.GetPanel(index).Tag = False
    'AnimatedArrow(index, 180, 0)
End Sub

Sub LoadImages
    Dim clv As CustomListView = Sender
    Dim files As List
    Dim imagesFolder As String
    imagesFolder = File.DirRootExternal & "/Pictures"
    If File.Exists(imagesFolder, "") = False Then
        ToastMessageShow("Images folder not found: " & CRLF & imagesFolder, True)
    End If
    files = File.ListFiles(imagesFolder) 'get all files in this folder
    For i = 0 To files.Size - 1
        DoEvents 'required for the ProgressDialog animation
        Dim f As String
        f = files.Get(i)
        If f.ToLowerCase.EndsWith(".jpg") Then
            Dim b As Bitmap
            b.InitializeSample(imagesFolder, f, 200dip, 200dip) 'load the jpeg file and subsample it if it is too large.
            Bitmaps.Add(b) 'add the bitmap to the bitmaps list.
            If Bitmaps.Size > 50 Then Exit 'limit it to 50 images
        End If
    HSVFOTOS.Panel.Width = 200dip * Bitmaps.Size 'Set the inner panel height according to the number of images.
    For i = 0 To Bitmaps.Size - 1
        Dim iv As ImageView 'create an ImageView for each bitmap
        iv.Initialize("") 'not interested in any events so we pass empty string.
        Dim bd As BitmapDrawable
        iv.Background = bd 'set the background of the image view.
        'add the image view to the scroll bar internal panel.
        clv.GetPanel(4).AddView(iv, 5dip + i * 200dip, 5dip, HSVFOTOS.Width - 10dip, 190dip)
    ToastMessageShow("Found " & Bitmaps.Size & " images", True)
End Sub


    17.1 KB · Views: 290

José J. Aguilar

Licensed User

After many test, I think I've arrived to the HorizontalScrollView.
With this line:

clv.GetPanel(index).GetView(1).AddView(iv, 15dip + (i * 100dip),5dip,ExpandedHeight, ExpandedHeight)

I've attached the images to the panel, so no scroll. After that, I add a new GetView, and I think I'm attaching the images to the HorizontalScrollView:
clv.GetPanel(index).GetView(1).GetView(0).AddView(iv, 15dip + (i * 100dip),5dip,ExpandedHeight, ExpandedHeight)

Now, the problem is that I get this new error:
java.lang.IllegalStateException: HorizontalScrollView can host only one direct child

Upvote 0

José J. Aguilar

Licensed User
Thanks you both¡¡

XbNnX_507, I've tested the custom HLV, but same error.
Erel, you're rigth, it works¡¡

BTW, you can rotate any view with B4XView.Rotation property or SetRotationAnimated method.
I've learned trying different index to get the rigth element, because I got the labels upside down¡ :)

BTW, how can I know the index of the elements? It's the tree views order?

Thanks again¡¡
Upvote 0