Android Question Resize child panels within a ScrollView

Discussion in 'Android Questions' started by DavidRa, Feb 2, 2015.

  1. DavidRa

    DavidRa New Member Licensed User

    I have a ScrollView for the main window of an app, and I have created a layout for the child items which is about 60dip high. When I init the app, I load a series of these layouts into panels, then add the panels to the ScrollView. In each case I have to explicitly set the top margin to be the appropriate height (for the Xth panel, (X-1) * 60dip) so that the panels appear to be in a list (this could be issue one in a long list of issues, so please be gentle).

    When I tap on an item in the list, I would like to resize that panel - because I'd like to display more information. My intent is eventually to show and hide extra fields in the layout rather than trying to switch layouts for a particular panel. To that end I have the following handler:

    Code:
    ' Event handler for main activity panels
    Sub Panel_Click (Sender as Object)
      
    Dim P as Panel : P = Sender
      
    ToastMessageShow("Resizing " & P.Tag)
      
    If (P.Height = 60dipThen
        P.Height = 
    90dip
      
    Else
        P.Height = 
    60dip
      
    End If
    End Sub
    Tapping the panel does correctly show the Toast (debugging) message, but the panel height does not appear to change at all. Even if it ended up "behind" the next panel in the scrollview, I'd expect to see the bottom-aligned labels disappear or move. No exception appears in the LogCat output.

    Assistance appreciated (though I cannot post the full project code until much later today - about 8 hours from timestamp of this post).
     
  2. Erel

    Erel Administrator Staff Member Licensed User

    Note that you can write:
    Code:
    Dim P As Panel = Sender
    Your code looks correct. Try to add P.BringToFront.
     
  3. eurojam

    eurojam Well-Known Member Licensed User

    and you should move the following panels down if you don't want to hide them. something like this:
    Code:
    Dim P As Panel : P = Sender
      
    ToastMessageShow("Resizing " & P.Tag, True)
      
    Dim m As Int
      
    If (P.Height = 60dipThen
      P.Height = 
    90dip
       m = 
    30dip
      
    Else
      P.Height = 
    60dip
       m = (-
    1)*30dip   
       
      
    End If
      
    If i < 5 Then '5 is the last panel for example
          For i = P.Tag+1 To 5 'number of panels
             Dim panelmove As Panel
             panelmove =  Scrollview1.Panel.GetView(i)
             panelmove.Top = panelmove.Top + m
          
    Next   
      
    End If
     
  4. DavidRa

    DavidRa New Member Licensed User

    Thanks - I'll try both of these tonight (oh what a dreaded comment to make). It seems a bit of a kludge to have to manually update each panel's location, and I'm guessing that will also mean updating the panel height within the ScrollView.

    Does a ListView make any of this ... easier? I should have asked - am I even using the right objects? Or is this just one of those things where XAML and flow layout just "got it right" and Android is a little bit more manual?
     
  5. udg

    udg Expert Licensed User

    If I understood you correctly, an option could be a distinct superimposed panel made up of the complete layout and showed on original sv panel tap. When done with the new panel, a tap on it will destroy it and the sv will come back in full view.
    that way no resizing is necessary at all.

    udg
     
  6. Erel

    Erel Administrator Staff Member Licensed User

    You should use CustomListView class. You will need to remove the panel with RemoveAt and insert it again (with the correct size) with InsertAt.
     
  7. DavidRa

    DavidRa New Member Licensed User

    OK I've tested adding P.BringToFront(). I do see a change in the value of P.Height, but the layout only alters by about 2dip (even if I triple the height), so I'm going to assume it's probably not the best approach. I could go for the super-imposed larger panel (nice idea BTW), but I think functionally I'd prefer to be able to have more than one item expanded, so I'm going to dig into CustomListView. Since I'm not exactly a pro developer (I'm an infrastructure guy) it's going to take a little while :)

    Edit: It didn't take quite as long as I thought it might, but I converted to CustomListView and have successfully got the resizing to work (though the layout itself needs work it seems).

    For those following along at home:
    Code:
    Sub Panel_Click (Sender as Object)
      
    Dim P as Panel = Sender
      
    Dim iX as Int
      iX = clv.GetItemFromView(
    Sender)
      clv.RemoveAt(iX)
      P.RemoveView()                
    ' Otherwise, CRASH, this was not expected :)
      If P.Height = REGULAR Then    ' My kingdom for ternary expressions ...
        P.Height = EXPANDED         ' Constant
      Else
        P.Height = REGULAR          
    ' Constant
      End If
      clv.InsertAt(iX, P, P.Height, P.Tag)
    End Sub
     
    Last edited: Feb 3, 2015
  8. DavidRa

    DavidRa New Member Licensed User

    Right so I've been muddling through - but I can't get the newly inserted panels to reflow / resize their internal content. If I insert the panels at the small size (60dip) and resize up, the child elements all stay in position relative to the small size. If I insert at the large size, all the content always stays at the right locatons and sizes for THAT panel size.
    I expect I'm missing something obvious.
    Here's the code that inserts at a particular size:
    Code:
    Sub FillMainScroll
      
    Dim X As Int
      
    Dim p As Panel
      
    Dim l As Label
      
    Dim tag As String
      
    For X = 0 To 14 ' This is a dummy loop, data is to be pulled from DB once the layouts work
        tag = "MyObj " & X
        p.Initialize(
    "MyObj")
        clvMyObjs.Add(p, Constants.MyObj_PanelLarge, tag)
        p.Height = Constants.MyObj_PanelLarge
        p.LoadLayout(
    "layoutMyObjItem")
        p.Tag = tag
        
    For Each V As View In p.GetAllViewsRecursive
          
    If V Is Label Then
            l = V
            
    If l.tag = "MyObjName" Then
              l.Text = 
    "MyObj " & X
            
    End If
            
    If l.tag = "LastUpdate" Then l.Text = "Last Updated " & DateTime.GetDayOfMonth(DateTime.Now) & " " & DateTime_Months(DateTime.GetMonth(DateTime.Now)-1) & " " & DateTime.GetYear(DateTime.Now)
          
    End If
          
    If V Is Panel AND V.tag = "MyObjStatus" Then
            
    Select (True)
              
    Case (X Mod 3 = 0): V.Color = Constants.Color_Offline
              
    Case (X Mod 3 = 1): V.Color = Constants.Color_Online
              
    Case (X Mod 3 = 2): V.Color = Constants.Color_Partial
            
    End Select
          
    End If
        
    Next
      
    Next
    End Sub
    That code seems to work perfectly regardless of the size I specify for clvMyObjs.Add and for p.Height.
    When a panel is tapped, this Sub runs:
    Code:
    Sub MyObj_Click
      
    Dim P As Panel = Sender
      
    Dim ix As Int
      ix = clvMyObjs.GetItemFromView(P)
      clvMyObjs.RemoveAt(ix)
      P.RemoveView()
      
    If P.Height = Constants.MyObj_PanelSmall Then
        clvMyObjs.InsertAt(ix, P, Constants.MyObj_PanelLarge, P.Tag)
        P.Height = Constants.MyObj_PanelLarge
        P.SetLayout (P.Left, P.Top, P.Width, Constants.MyObj_PanelLarge)
        
    For Each V As View In P.GetAllViewsRecursive
          
    If V.Tag = "Services" Then V.Visible = True
        
    Next
      
    Else
        clvMyObjs.InsertAt(ix, P, Constants.MyObj_PanelSmall, P.Tag)
        P.Height = Constants.MyObj_PanelSmall
        P.SetLayout (P.Left, P.Top, P.Width, Constants.MyObj_PanelSmall)
        
    For Each V As View In P.GetAllViewsRecursive
          
    If V.Tag = "Services" Then V.Visible = False
        
    Next
      
    End If
    End Sub
    In case it's relevant, I've also converted my layout for the dynamic items to use Designer Script:
    Code:
    'All variants script
    AutoScaleAll
    pnlMyObj.SetLeftAndRight(
    0%x100%x)
    pnlMyObj.SetTopAndBottom(
    0%y100%y)
    pnlStatusColour.SetLeftAndRight(
    0dip10dip)
    pnlStatusColour.SetTopAndBottom(
    0%y100%y)
    lblMyObjName.SetLeftAndRight (
    20dip100%x)
    lblMyObjName.SetTopAndBottom (
    5dip5dip+lblMyObjName.Height)
    lblLastUpdate.SetLeftAndRight (
    20dip100%x)
    lblLastUpdate.SetTopAndBottom (
    100%y-5dip-lblLastUpdate.Height, 100%y-5dip)
    lblServices.SetLeftAndRight (
    30dip100%x-10dip)
    lblServices.SetTopAndBottom (
    5dip + lblMyObjName.Bottom, 100%y-lblLastUpdate.Top-5dip)
    TL;DR: Resized panel doesn't adjust positions and sizes of child views.
     
  9. Erel

    Erel Administrator Staff Member Licensed User

    Can you upload a simple project with this code?
     
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice