Android Question Can CustomListView hold a CustomView?

Widget

Well-Known Member
Licensed User
Longtime User
I modified the CustomListView example and added a LimitBar to each item panel. It displays fine. The problem is when any of the LimitBars is touched, it will call the CustomListView.GetItemFromView and throws an exception.

B4X:
'Returns the index of the item that holds the given view.
Public Sub GetItemFromView(v As View) As Int
    Dim parent = v, current As Object
    Do While (parent Is Panel) = False Or sv.Panel <> parent
        current = parent
        Dim jo As JavaObject = current
        parent = jo.RunMethod("getParent", Null)   '<-- Throws exception
    Loop
    v = current
    Return v.Tag
End Sub

The exception is:
java.lang.RuntimeException: Method: getParent not found in: anywheresoftware.b4a.samples.customlistview.limitbar

That indicates to me the customlistview has no getParent sub to return its parent. So I added a getParent to limitbar and it never executes any line of code in that customlistview.getParent sub. Which means to me it still can't find the limitbar.getParent.

So before I spend too much more time on this, I have to ask:
1) Can a CustomListView contain a CustomView?
2) If yes, how do I get CustomListView.GetItemFromView() to work?

Note: I will be adding LimitBar to the panels dynamically later on instead of using the Designer. So if there is a solution it should work with the Designer and at runtime.

TIA

B4X:
private fParent as Object

public Sub getParent(v As View) As View
  Private jo As JavaObject
    If v.IsInitialized Then
    Return jo.RunMethod("getParent", Null)
    Else
        Return fParent   
    End If
End Sub   


Public Sub DesignerCreateView(Base As Panel, Lbl As Label, Props As Map)
    Private r As Reflector
    r.target = Base
    fParent = r.RunMethod("getParent")
   ....
end sub

Public Sub AddTpParent(Parent As Activity, Left As Int, Top As Int, Width As Int, Height As Int, cColor As Int, cRadius As Int)
    cLeft = Left
    cTop = Top
    cWidth = Width
    cHeight = Height
    fParent = Parent
  ....    
end sub
 

Widget

Well-Known Member
Licensed User
Longtime User
Can you upload the project?

Sure. Here it is. It may be something simple (I hope).

From my Readme file describing the problem:

This app produce 2 different exceptions, depending on whether the CustomListView item panels are built using code or loaded from a layout.
The CustomListView will be built and displayed correctly, or so it seems. But when any of the LimitBar's are resized, one of the exceptions will occur.

1)
'If the CustomListView panels are built at runtime using code, I get this exception when a LimitBar is resized (shown below).
'It appears there is something wrong with Callback that is defined in LimitBar. I'm not sure what is wrong with it.
'Module: LimitBar Line 223 --->
' if a callback routine exists in the calling module we call it
If SubExists(Callback, EventName & "_ValuesChanged") Then '<=== EXCEPTION (Not Using Layout): java.lang.ClassCastException: anywheresoftware.b4a.BALayout cannot be cast to java.lang.String

2)
'If the CustomListView panels are built using a Layout, the following exception occurs when a LimitBar is resized.
'Module: CustomListView Line 216
parent = jo.RunMethod("getParent", Null) '<--- EXCEPTION (Using Designer Layout): java.lang.RuntimeException: Method: getParent not found in: anywheresoftware.b4a.samples.customlistview.limitbar

Any idea what is causing both exceptions?
TIA
 

Attachments

  • CustomListView_CustomView_Bug.zip
    17 KB · Views: 166
Upvote 0

Widget

Well-Known Member
Licensed User
Longtime User
Use layout files to add custom views.

Thanks for your quick response.
The reason I want to use code to populate the item panel is because the app will be using B4A and B4i. I'd rather not recreate layouts for each OS. The recommendations on the forum have been to use code to create and position the views because of the different screen resolutions that have to be handled instead of using layouts.

1) Why can't code be used to add the CustomView "LimitBar" to an item in CustomListView? I don't appear to have a problem adding other non-custom views that way to CustomListView.


That should work, thanks.

2) To help me understand why it failed, I was using:
Private index As Int = clv2.GetItemFromView(Sender) '<--- EXCEPTION If Panels added in code +++++++++++++++++
so it was searching for the CustomListView for LimitView but LimitView is a non-standard view so it couldn't be found?

So I have to use:
Dim lb As LimitBar = Sender
Private index As Int = clv2.GetItemFromView(lb.GetBase)
to search for a standard view like the Panel that contains the LimitView, correct?

Thanks again.
 
Upvote 0

Widget

Well-Known Member
Licensed User
Longtime User
Sorry but I have one more question that I am stuck on. I am trying to wrap my head around how to access a CustomView like LimitBar from a panel that contains an assortment of views. This panel is an item in the CustomListView. Erel's reply #4 uses the Sender within the LimitBar1_ValuesChanged to allow me access to the LimitBar CustomView, which is fine.

But what if I want to access the LimitBar customview outside of an event where there is no Sender variable? How do I do it?
Example. I want to access the properties of the LimitBar for each item in CustomListView1.
It will look something like this:

B4X:
Sub TraverseCustomListView
    Private ItemNdx, ViewNdx As Int
   
    For ItemNdx=0 To clv2.GetSize-1
        Private locPanel As Panel
        locPanel = clv2.GetPanel(ItemNdx)

        Private locView     As View
        Private locLimitBar As LimitBar
        locView = locPanel.GetView(3)    'How do I get LimitBar from locPanel?
        Log("Tag="&locView.Tag)
        Private locLimitBar As LimitBar = locView    'Warning: Types do not match. (warning #22)
       
        Log("locLimitBar.Max="&locLimitBar.Max)        '<===Exception java.lang.RuntimeException: Field: ba not found in: anywheresoftware.b4a.BALayout
    Next
End Sub

The CustomView LimitBar is included in the locPanel.NumberOfViews, but I can't get it put into the locLimitBar variable. Whenever I try to reference a property in locLimitBar it throws an exception. The problem is the locPanel.GetView(3) cannot retrieve the CustomView LimitBar.

Does anyone have an idea of how this can be done?
TIA
 
Upvote 0

Widget

Well-Known Member
Licensed User
Longtime User

The saga continues.
I changed the Sub to display the data type of the views in locPanel (Item Panel) to try to shed some light on the problem.

B4X:
Sub TraverseCustomListView
    Private ItemNdx, ViewNdx As Int
    For ItemNdx=0 To clv2.GetSize-1
        Private locPanel As Panel
        locPanel = clv2.GetPanel(ItemNdx)
   
        For ViewNdx=0 To locPanel.NumberOfViews-1
            Private locView   As View
            locView   = locPanel.GetView(ViewNdx)
            Log(GetType(locView)&" Ndx="&ViewNdx&" Tag="&locView.Tag)
        Next   
    Next
End Sub

It turns out locPanel.GetView(3) is returning BALayout for the CustomView LimitBar

Here are the 5 views that are in the item panel retrieved from the CustomListView. I have changed the Tag of the views to the view name so I know what view in the item panel I'm working with. Here are the log results:

android.widget.TextView Ndx=0 Tag=Label1
android.widget.Button Ndx=1 Tag=Button1
android.widget.CheckBox Ndx=2 Tag=CheckBox1
anywheresoftware.b4a.BALayout Ndx=3 Tag=LimitBar1
android.widget.TextView Ndx=4 Tag=lblLimitBar1​

So View #3 is LimitBar1 but GetView(3) returns a "BALayout" data type and not the actual instance of the LimitBar view that was created. From what I can tell the BALayout is a definition layout of the views that make up the CustomView LimitBar1. If so, then this is totally different from what I thought GetView() was suppose to return. I thought GetView() is suppose to return the view, not the layout of the view.
  1. The question remains, how do I use the BALayout to retrieve the actual LimitBar that was created?
  2. Why is GetView(3) returning a BALayout and not the actual LimitBar view? Shouldn't GetView() return the View that was created, and not the Layout of the view? That's how it works for every other view on the panel, just not a CustomView.
TIA
 
Upvote 0

Widget

Well-Known Member
Licensed User
Longtime User
For a sample project, see post #3.
I will try GetAllViewsRecursive and see what happens. Thanks.

I tried GetAllViewsRecursive and here's what I got:

android.widget.TextView Tag=Label1
android.widget.Button Tag=Button1
android.widget.CheckBox Tag=CheckBox1
anywheresoftware.b4a.BALayout Tag=LimitBar1
anywheresoftware.b4a.BALayout Tag=null
android.widget.TextView Tag=lblLimitBar1

So it returns an extra BALayout and that's about it.

Where can I find the properties and methods that are available for BALayout? I don't see any documentation for it anywhere.

TIA
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
My "question" can seems stupid enough (on the other hand, I'm not so smart ) but this time it is so "only" mainly because I have not read this thread carefully.

I understood the question:

1) can I use a Custom View as part - component of another Custom View in the same way as I use other Views

2) why (or how to do) I cannot get the type of the CV component (using getallviewsrecursive).

I undestand that when @Widget gets "anywheresoftware.b4a.BALayout" the reason is because he gets the base panel of the CV component,
but why this my suggestion I wrote here works?
B4X:
[QUOTE="LucaMs, post: 436411, member: 51832"]
For Each v As View In Activity.GetAllViewsRecursive
    If GetType(v) = "com.wrapp.floatlabelededittext.FloatLabeledEditText" Then
        LogColor("si, si, sono una FloatLabeledEditText", Colors.Blue)
    End If
Next[/QUOTE]

(the italian member asked how to recognize a floatlabelededittext view)


P.S. this post shows that I'm not smart: I mixed two questions I read; the first question in this thread is not exactly what I have written here. Anyway, maybe my question is not so stupid.
 
Last edited:
Upvote 0
Cookies are required to use this site. You must accept them to continue using the site. Learn more…