Android Question CLV Individually Rounded Corners

Mike1970

Well-Known Member
Licensed User
Longtime User
Hi everyone,
I need to achieve this result with a CLV (only 2 corners are rounded)

Screenshot 2024-05-18 alle 12.33.24.png


I already tried these two approaches
Approach 1:
Dim jo As JavaObject = clvProducts.AsView
jo.RunMethod("setClipToOutline", Array(True))
clvProducts.AsView.SetColorAndBorder(clvProducts.AsView.Color, 2dip, 0xDBDBDB, 20dip)
This works but it rounds all the corners and it does not set the border color/width...

Approach 2:
Dim jo As JavaObject = clvProducts.AsView
jo.RunMethod("setClipToOutline", Array(True))
General.setCornerRadii(clvProducts.AsView, 20dip, 0dip, 0dip, 20dip)

'General Module
Sub setCornerRadii(v As View, TopLeft As Float, TopRight As Float, BottomRight As Float, BottomLeft As Float)
    Dim jo As JavaObject = v.Background
    If v.Background Is ColorDrawable Or v.Background Is GradientDrawable Then
        jo.RunMethod("setCornerRadii", Array As Object(Array As Float (TopLeft, TopLeft, TopRight, TopRight, BottomRight, BottomRight, BottomLeft, BottomLeft)))
    End If
End Sub
This does not work at all :(

Thanks in advance
 

Sagenut

Expert
Licensed User
Longtime User
I did it with a trick.
But hopefully someone will teach us a better way, like applying correctly the method you was trying.
In the meanwhile you can try this.
 

Attachments

  • CLV_Rounded.zip
    67.3 KB · Views: 20
Upvote 0

Mike1970

Well-Known Member
Licensed User
Longtime User
I did it with a trick.
But hopefully someone will teach us a better way, like applying correctly the method you was trying.
In the meanwhile you can try this.
Wow this is very intricate ahaha. Congrats.
Actually I was hoping for something more direct, in my case I cannot use this approach because the clv could possibly change size D:
 
Upvote 0

Sagenut

Expert
Licensed User
Longtime User
You need to change CLV size at runtime?
 
Upvote 0

Sagenut

Expert
Licensed User
Longtime User
I made some changes to try to make it more user friendly.
It can manage resize, if I have intended it in the right way.
You need to resize the covering panel the same as the CLV.
Then recall the Sub.
In the example I made only an height change, because resizing the CLV even on the width will need to modify all the added elements.
If you can manage it then it should work.
In the example the CLV will change it's height after 4 seconds.
The limit now is that it's based on a background image.
If you will not need it then it should be simple to modify it to use a solid color.
I did what I can. ;)
NOTE = I changed the package name. Earlier I forgot about it.
 

Attachments

  • CLV_Rounded.zip
    67.4 KB · Views: 24
Upvote 0

Mike1970

Well-Known Member
Licensed User
Longtime User
I made some changes to try to make it more user friendly.
It can manage resize, if I have intended it in the right way.
You need to resize the covering panel the same as the CLV.
Then recall the Sub.
In the example I made only an height change, because resizing the CLV even on the width will need to modify all the added elements.
If you can manage it then it should work.
In the example the CLV will change it's height after 4 seconds.
The limit now is that it's based on a background image.
If you will not need it then it should be simple to modify it to use a solid color.
I did what I can. ;)
NOTE = I changed the package name. Earlier I forgot about it.
Thank you very much for the effort, unfortunately also the background image can change because it will reflect weather conditions šŸ˜‚
Sorry if I did not specify it in the post, but I was not expecting such creative approach!

It is very frustrating that setClipToOutline does not work... it was the right choice... as far as I know it should clip ALL the childs of a parent view, I hope for some trick to get it working
 
Upvote 0

Sagenut

Expert
Licensed User
Longtime User
Thank you very much for the effort, unfortunately also the background image can change because it will reflect weather conditions
In the parameter you have to pass the background image, you can call the sub passing the new image every time.
Anyway I will not disturb you more. :)
Let's hope that someone will bring us a better solution.
 
Upvote 0

Mike1970

Well-Known Member
Licensed User
Longtime User
Anyway I will not disturb you more. :)
You are absolutely not disturbing me, in fact different approaches are also useful for learning.
I will definitely use your method in case a Java expert doesn't come along to solve this mystery
 
Upvote 0

PaulMeuris

Active Member
Licensed User
This layout can be accomplished without the use of the JavaObject library.
Only the XUI Views library is used for the CustomListView.
1716173285058.png
1716173375597.png

The layout contains a side panel and inside that panel there's a CLV.
The side panel is anchored on the right with the Right Edge Distance at -25. This hides the 2 rounded corners on the right.
The side panel and CLV can be resized (by typing a max items number and tapping on the Show button.
1716173739025.png
1716173807396.png

The side panel can be hidden by tapping on the Hide button.
You can tap on each view in the CLV to get its tag or item information.
1716173955698.png
1716173996313.png
1716174046052.png
1716174106161.png

You can change the background image or color from the root, from the side panel and from each individual item in the CLV.
Transparant color is used to let the background become visible.
If you set the background of the side panel with bitmap drawable then you loose the rounded corners (and you might have to do some drawing...)
1716174611634.png

So there you have it. Is this a worthy alternative?
The source code is in the attachment (testenvironment53.zip)
 

Attachments

  • testenvironment53.zip
    286.6 KB · Views: 17
Upvote 0

Mike1970

Well-Known Member
Licensed User
Longtime User
Thank you @PaulMeuris for your contribution too, but I just finished implementing the way I decided to go with.

Firstly I usually use CLVs with custom elements following this paradigm (lazy-loading technique)
  1. Create a template layout for one generic element that will be loaded in the CLV
    (NOTE the background i completely transparent and I put a very THIN panel at the bottom to mimic a divider)
    Screenshot 2024-05-20 alle 12.00.24.png


  2. Create the CLV in the page layout you need, and set its divider color and pressed color to transparent

  3. Create a function like fillCustomListView
    fillCustomListView:
    Private Sub FillProducts
        clvProducts.Clear
    
        ' Choose the single element height (could be a function argument)
        Dim elementHeight As Int = 200dip
    
    
        ' Fill the CLV with a number of empty panels equal to the number of element you need
        '(in this case I'm taking the elements from a sample list)'
        For Each t As Tank In Main.tank_list 'Tank is a custom type
            Dim p As B4XView = xui.CreatePanel("")
            p.Color = Colors.Transparent
            p.SetLayoutAnimated(0, 0, 0, clvProducts.AsView.Width, elementHeight)
    
            clvProducts.Add(p, t)
        Next
    
        ' Resize the CLV to show all the element (no need to scroll) and place it vertically centered
        Dim newClvHeight As Int =  elementHeight * clvProducts.Size + (clvProducts.Size * clvProducts.DividerSize) + 2dip
        clvProducts.AsView.SetLayoutAnimated(0, Root.Width, Root.Height/2 - (newClvHeight)/2, clvProducts.AsView.Width, newClvHeight)
        clvProducts.sv.SetLayoutAnimated(0, clvProducts.sv.Left, clvProducts.sv.Top, clvProducts.sv.Width, clvProducts.AsView.Height)
    
       'Show CLV in animated
        Sleep(0)
        clvProducts.AsView.SetLayoutAnimated(200, Root.Width - clvProducts.AsView.Width, clvProducts.AsView.Top, clvProducts.AsView.Width, clvProducts.AsView.Height)
    End Sub

    If you are wondering "why this subject is using a CLV if he does not want to scroll? dumb" it is because I want to exploit the possibility to have a template layout and replicate it as many times I want, and have the benefits of the CLVs to manage the items.
  4. Then you need to load each element's layout in the clv_VisibleRangeChanged callback

  5. At this point, to round the corners I used this method
    B4X:
    setCornerRadii(clv.AsView, 20dip, 0dip, 0dip, 20dip)
    
    
    'function'
    Sub setCornerRadii(v As View, TopLeft As Float, TopRight As Float, BottomRight As Float, BottomLeft As Float)
        Dim jo As JavaObject = v.Background
        If v.Background Is ColorDrawable Or v.Background Is GradientDrawable Then
            jo.RunMethod("setCornerRadii", Array As Object(Array As Float (TopLeft, TopLeft, TopRight, TopRight, BottomRight, BottomRight, BottomLeft, BottomLeft)))
        End If
    End Sub

    IMG_1054-min.jpg

    (I cannot take screenshot easily with this device)

    It works because the elements has transparent background and nothing is in the corners... however my solution as the ones suggested has also some limitations... the final one is to find the way to apply the "setClipToOutline" method in the correct way to round only certain corners with the above function... but I think that @Erel can point us in the correct way knowing how the library is implemented...
 
Last edited:
Upvote 0
Top