Android Question HorizontalScrollview showing images inside a CustomListView

josejad

Expert
Licensed User
Longtime 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:
B4X:
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


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

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

#AdditionalJar: com.android.support:support-v4
#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:
    'Activity.LoadLayout("Layout1")
    Activity.LoadLayout("TabDescripciones")
    TabStrip1.LoadLayout("tabgenerales", "Type I Pictures")
    TabStrip1.LoadLayout("tabespecificas", "Type II Pictures")
    For Each lbl As Label In GetAllTabLabels(TabStrip1)
        lbl.Width = 50%x
    Next
    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)
    Next
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
    res.Initialize
    For Each v As View In tc
        If v Is Label Then res.Add(v)
    Next
    Return res
 
End Sub

Sub CrearItemChk(Text As String, Index As Int, Width As Int, Height As Int) As Panel
    Dim p As Panel
    p.Initialize("")
    Activity.AddView(p, 0, 0, 100%x, ExpandedHeight)
    p.SetLayout(0, 0, Width, Height)
    p.LoadLayout("cellPuntosChk")
    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
        CollapseItem(Index)
    Else
        ExpandItem(Index)
    End If
    'LoadImages(Value.SubString2(0,4).Trim)
    LoadImages
  
End Sub

Sub LVEspecificas_ItemClick (Index As Int, Value As String)
    Dim p As Panel = LVEspecificas.GetPanel(Index)
    If p.Tag = True Then
        CollapseItem(Index)
    Else
        ExpandItem(Index)
    End If
    'FiltrarFotos(Value.SubString2(0,4).Trim)
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
    An.Start(iv)
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
    Bitmaps.Initialize
    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)
        Return
    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
    Next
    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
        bd.Initialize(Bitmaps.Get(i))
        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)
    Next
    Log(clv.GetPanel(2))
    ToastMessageShow("Found " & Bitmaps.Size & " images", True)
End Sub
 

Attachments

  • ImageSample.zip
    17.1 KB · Views: 445

josejad

Expert
Licensed User
Longtime User
Hi:

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

B4X:
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:
B4X:
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

Thanks
 
Upvote 0

josejad

Expert
Licensed User
Longtime 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
Top