Android Question GifViewer & Panel Reference

Marcos Alves

Well-Known Member
Licensed User
Hi,

I'm trying to use GifViewer as an object loaded inside many panels. But when recovering the reference, I'm getting the error:

chat.java:1409: error: incompatible types: View cannot be converted to gifviewer
_gifviewer1 = (com.comten.nexphone.gifviewer)(_pnlmessage.GetView((int) (4)).getObject());

Calling the reference of the GifViewer:

B4X:
    Dim GifViewer1 As GifViewer = PnlMessage.GetView(4)

How can I add many gifviewers in panels and later get the references ? I already realized that gifviewer is not really a view as it's implemented, but if I need to show gifs on panels (like in a listview or in a ULV for example), I couldn't find any other technique...

Does anybody have any suggestion?
 

Erel

Administrator
Staff member
Licensed User
like in a listview or in a ULV for example
The exact terms are important. You cannot use any view with listview. You probably meant CustomListView.

1. Add this line to DesignerCreateView:
B4X:
mBase.Tag = Me

2.
B4X:
Dim GifViewer1 As GifViewer = PnlMessage.GetView(4).Tag
 
Upvote 0

Marcos Alves

Well-Known Member
Licensed User
The exact terms are important. You cannot use any view with listview. You probably meant CustomListView.

1. Add this line to DesignerCreateView:
B4X:
mBase.Tag = Me

2.
B4X:
Dim GifViewer1 As GifViewer = PnlMessage.GetView(4).Tag

First... sorry, you're right: the exact terms are important. The exact phrase is: "I notice that I cant add a customview in a panel inside other customview - in this specific situation, I'm trying to add a GifPLayer (B4AGifViewer Library) to a ULV (UltimateListView) panel".


About your answer @Erel ... I really didn't realized some things (sorry, please help!):

- What's "mBase" ?
- DesignerCreateView - where?I really didn't understand, sorry.
B4X:
Dim GifViewer1 As GifViewer = PnlMessage.GetView(4).Tag

This is correct - it's what I'm doing. I did some tests changing the index in GetView and got that first error. But the error message that I'm getting for any customview inside a ULV panel is:

java.lang.NullPointerException: Attempt to invoke virtual method 'void com.tillekesoft.b4agifview.GifView.setGifPath(java.lang.String)' on a null object reference

The Code:
B4X:
Sub ImgMsgSent_Filler(ItemID As Long,LayoutName As String,LayoutPanel As Panel,Position As Int)

    Dim ImgLeftChat As ImageView = LayoutPanel.GetView(0)
    Dim PnlMessage As Panel = LayoutPanel.GetView(1)
...
    Dim GifPlayer2 As GifPlayer = PnlMessage.GetView(4)
...
                GifPlayer2.SetGifPath("/storage/emulated/0/Android/data/com.comten.nexphone/files/targetfile.gif")
...

The line of the error is the last above.

The designer:

upload_2018-5-31_13-43-5.png


GifPlayer is correctly referenced...

That is exactly my problem... I think that @Erel solution could fix the problem for all the times when I need to add a customview inside an ULV panel, but I really didn't understand how to do... Please @Erel ... help!
Thanks @Informatix ... I'll test the animatedGifView...
 
Upvote 0

DonManfred

Expert
Licensed User
Upvote 0

Marcos Alves

Well-Known Member
Licensed User
Check the Class code of GifViewer.

Again; check the Class code

And you did understand that it is a Class which is a Module in you app? Just open the module and edit it.

Hi Don,

thanks for answering. The GifPlayer that I'm talking about is an object of B4AGifViewer library (This: https://www.b4x.com/android/forum/threads/b4agifviewer.77416/#content)

It's newer than GifPlayer Class from @Erel (this lib was created by @monster67 in march/2017) ... this is not a class. It's a library.
 
Upvote 0

DonManfred

Expert
Licensed User
The GifPlayer that I'm talking about is an object of B4AGifViewer library
But Erel was talking about the Class and you answered with your question to his post.

It is possible that the author of the lib you mentioned is using a customview.
But it is not implemented as a Class so you wont be able to edit it.

BTW:
Date jul 2017
https://www.b4x.com/android/forum/threads/custom-view-gifviewer.82104/

Date March 2017
https://www.b4x.com/android/forum/threads/b4agifviewer.77416/#content

It's newer than GifPlayer Class from @Erel (this lib was created by @monster67 in march/2017) ... this is not a class. It's a library.
Right. But Erels Class is the newer one.
 
Last edited:
Upvote 0

Marcos Alves

Well-Known Member
Licensed User
But Erel was talking about the Class and you answered with your question to his post.
Yes... I tested with many gifviewers classes and got the same error. (null object...). But I thought that could have a more effective result with this last one that I used - even because B4AGifPlayer is newer... Sorry the mistake... I uderstand that if I navigate inside a class of an object I can fix virtually any error - but I'll also spend more time and, at the end of the day, have a project with many non standard classes derived from community development which could be hard to do versioning and maintaining later.
By the way: do you know any way to user B4AGifPlayer "as it is" inside a ULV? Is there anything that I could do to create a "working structure" with this lib?
 
Upvote 0

Marcos Alves

Well-Known Member
Licensed User
I cant help at all with ULV. I´ve donated for it but i do not use it.
Thanks Don... I switched to GifViewer Class (@Erel solution) and I'm testing just now... I think that will work. I'll post the results here. Thanks for all. The B4A community is the best Android Developers Group of the world - and this sense of collaboration and mutual help makes it even better!
 
Upvote 0

Marcos Alves

Well-Known Member
Licensed User
The exact terms are important. You cannot use any view with listview. You probably meant CustomListView.

1. Add this line to DesignerCreateView:
B4X:
mBase.Tag = Me

2.
B4X:
Dim GifViewer1 As GifViewer = PnlMessage.GetView(4).Tag

Hi @Erel ... I did what you recommended... exactly..
The DesignerCreateView:

B4X:
Public Sub DesignerCreateView (Base As Panel, Lbl As Label, Props As Map)
   
    mBase = Base
    mBase.Visible = False
    mBase.Tag = Me
   
End Sub

In my routine:

B4X:
Sub ImgMsgSent_Filler(ItemID As Long,LayoutName As String,LayoutPanel As Panel,Position As Int)
   
    Dim ImgLeftChat As ImageView = LayoutPanel.GetView(0)
    Dim PnlMessage As Panel = LayoutPanel.GetView(1)
    Dim WebViewExtras1 As WebViewExtras
   
   
    Dim WebSent As WebView = PnlMessage.GetView(0)
    Dim LblMessage As Label = PnlMessage.GetView(1)
    Dim LblDataHora As Label = PnlMessage.GetView(2)
    Dim ImgStatus As ImageView = PnlMessage.GetView(3)
    Dim GifViewer1 As GifViewer = PnlMessage.GetView(4).Tag
...

And got the error:

java.lang.ClassCastException: anywheresoftware.b4a.BALayout cannot be cast to android.widget.ImageView

Did I do anything wrong?
 
Upvote 0

Marcos Alves

Well-Known Member
Licensed User
First... sorry, you're right: the exact terms are important. The exact phrase is: "I notice that I cant add a customview in a panel inside other customview - in this specific situation, I'm trying to add a GifPLayer (B4AGifViewer Library) to a ULV (UltimateListView) panel".


About your answer @Erel ... I really didn't realized some things (sorry, please help!):

- What's "mBase" ?
- DesignerCreateView - where?I really didn't understand, sorry.
B4X:
Dim GifViewer1 As GifViewer = PnlMessage.GetView(4).Tag

This is correct - it's what I'm doing. I did some tests changing the index in GetView and got that first error. But the error message that I'm getting for any customview inside a ULV panel is:

java.lang.NullPointerException: Attempt to invoke virtual method 'void com.tillekesoft.b4agifview.GifView.setGifPath(java.lang.String)' on a null object reference

The Code:
B4X:
Sub ImgMsgSent_Filler(ItemID As Long,LayoutName As String,LayoutPanel As Panel,Position As Int)

    Dim ImgLeftChat As ImageView = LayoutPanel.GetView(0)
    Dim PnlMessage As Panel = LayoutPanel.GetView(1)
...
    Dim GifPlayer2 As GifPlayer = PnlMessage.GetView(4)
...
                GifPlayer2.SetGifPath("/storage/emulated/0/Android/data/com.comten.nexphone/files/targetfile.gif")
...

The line of the error is the last above.

The designer:

View attachment 68524

GifPlayer is correctly referenced...

That is exactly my problem... I think that @Erel solution could fix the problem for all the times when I need to add a customview inside an ULV panel, but I really didn't understand how to do... Please @Erel ... help!
Thanks @Informatix ... I'll test the animatedGifView...

### UPDATE ###
Due any reason that I unknown, when I add GifViewer as child of a panel that is already child of ULV panel, the indexes are mistaken... I put the GifViewer on the ULV main panel and "voilá"... worked!!!! See:

upload_2018-5-31_17-45-17.png


The code:

B4X:
Sub ImgMsgSent_Filler(ItemID As Long,LayoutName As String,LayoutPanel As Panel,Position As Int)
    
    Dim ImgLeftChat As ImageView = LayoutPanel.GetView(0)
    Dim PnlMessage As Panel = LayoutPanel.GetView(1)
    Dim WebViewExtras1 As WebViewExtras
    
    
    Dim WebSent As WebView = PnlMessage.GetView(0)
    Dim LblMessage As Label = PnlMessage.GetView(1)
    Dim LblDataHora As Label = PnlMessage.GetView(2)
    Dim ImgStatus As ImageView = PnlMessage.GetView(3)
    Dim GifViewer1 As GifViewer = LayoutPanel.GetView(2).Tag
...

It's working now but I think that there is a bug somewhere when we use customviews inside a child panel in a ULV panel... what do you think @Informatix ?
 
Upvote 0

Marcos Alves

Well-Known Member
Licensed User
### UPDATE ###:

working now BUT considering that it's a list and there is no LoadBitmapSample for gifviewer, I had the error when loading more than one gif:

java.lang.OutOfMemoryError: Failed to allocate a 2560012 byte allocation with 602032 free bytes and 587KB until OOM

What means that unless we have something similar to loadbitmapsample in gifviewer, will not be possible to create giflists in ULV... @Erel ... do you have any solution for this error? It's not secure to show gif in a list before reducing them and there is no command/method to reduce then, there is?
 
Upvote 0

Informatix

Expert
Licensed User
It's working now but I think that there is a bug somewhere when we use customviews inside a child panel in a ULV panel... what do you think @Informatix ?
I'm able to reproduce the problem but it's not related to ULV in any way. In the designer, the only custom view is GifViewer and, in the code, GetView is a function of the Panel class. There's no class, function or property of ULV involved here.

Note also that all custom views that extends ViewWrapper in Java can be retrieved with GetView directly (no need for a reference in Tag). It's not the case of AnimatedGifView, so you can forget my suggestion and continue to use the Erel class.
 
Upvote 0

Informatix

Expert
Licensed User
working now BUT considering that it's a list and there is no LoadBitmapSample for gifviewer, I had the error when loading more than one gif:

java.lang.OutOfMemoryError: Failed to allocate a 2560012 byte allocation with 602032 free bytes and 587KB until OOM

What means that unless we have something similar to loadbitmapsample in gifviewer, will not be possible to create giflists in ULV...
Not exactly. You can modify the GifViewer class to add optimizations (e.g. to load the images in the background, to use the ULV cache, to change the size of all decoded GIF to reduce the memory consumption...).
Animated GIFs in a list need a lot of memory (e.g. a GIF with 30 frames in 400x400 consumes 30x400x400x4 bytes in memory = 18,3 MB). If these images are quite small, the next problem is the proper management of animations (you have to avoid restarting the animation or, worse, reloading the animation each time you call a function that refreshes the list content, e.g. ULV.RefreshContent or any function forcing a call to your ContentFiller sub).
 
Upvote 0

Informatix

Expert
Licensed User
I found a solution:
Replace your GIFViewer view by a WebView and use this code in the ContentFiller sub:
B4X:
Dim WV As WebView = LayoutPanel.GetView(VIEW_INDEX)
WV.LoadURL("file:///android_asset/" & YOUR_IMAGE_NAME_IN_ASSETS)
WebView has already the needed optimizations.
The only problem is that the image is not resized so you see just a part of it when too big but it can be fixed by setting properly the webview.
 
Upvote 0

Marcos Alves

Well-Known Member
Licensed User
Hello
I found a solution:
Replace your GIFViewer view by a WebView and use this code in the ContentFiller sub:
B4X:
Dim WV As WebView = LayoutPanel.GetView(VIEW_INDEX)
WV.LoadURL("file:///android_asset/" & YOUR_IMAGE_NAME_IN_ASSETS)
WebView has already the needed optimizations.
The only problem is that the image is not resized so you see just a part of it when too big but it can be fixed by setting properly the webview.

Hello @Informatix ,

That's exactly what I was doing. But in ULV, a refresh reloads the objects inside the panels. This would not be a problem but when reloading a webview there is an undesirable "flick" in its content, what compromises the user experience.
I also developed a HTML code to reference the image that fixes the scale problem in webview... the unique obstacle to use this is the "refresh flick" - unfortunately. If there wasn't the flick in the content, local and remote objects could have the same exhibition behavior using webviews.
 
Last edited:
Upvote 0
Top