Android Example [B4X] RSS Viewer using xCustomListView

After having used the RSS Viewer library in the past, and now finding that it won't function with my secure sites, I decided to start with Erel's XUI CustomListView example and then integrate that with using the XML2MAP library to write a RSS viewer. The attached example is for B4A, but it would probably be easy enough to adapt to b4i as well.

One thing that I do that the RSS viewer library did not do, is dynamically adjust the card size based on the amount of text content. This example also has a browser activity that will load the website URL and allow the user to share the link.

Edit: Updated on 2/19/2019 for better handling of panel resizing.

upload_2019-2-13_16-1-27.png
 

Attachments

  • RSS Example.zip
    20.7 KB · Views: 1,002
Last edited:

Metalika

Member
hi @Jack Cole i use b4a v 9.8 .
i want to use this source but i cant find lable extras lib
this lib is a internal lib and i think that remove from internal lib in new version b4a!
 

jchal

Active Member
Licensed User
Longtime User
unfortunately i tried to run the code but i got the following error
Logger connected to: Xiaomi Redmi Note 5A Prime
--------- beginning of main
Copying updated assets files (17)
*** Service (starter) Create ***
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
*** Service (httputils2service) Create ***
** Service (httputils2service) Start **
Error occurred on line: 24 (Xml2Map)
org.apache.harmony.xml.ExpatParser$ParseException: At line 2, column 0: XML or text declaration not at start of entity
at org.apache.harmony.xml.ExpatParser.parseFragment(ExpatParser.java:515)
at org.apache.harmony.xml.ExpatParser.parseDocument(ExpatParser.java:474)
at org.apache.harmony.xml.ExpatReader.parse(ExpatReader.java:316)
at org.apache.harmony.xml.ExpatReader.parse(ExpatReader.java:279)
at anywheresoftware.b4a.objects.SaxParser.parse(SaxParser.java:80)
at anywheresoftware.b4a.objects.SaxParser.Parse(SaxParser.java:73)
at b4a.example.xml2map._parse2(xml2map.java:259)
at b4a.example.xml2map._parse(xml2map.java:94)
at b4a.example.main._parserssandloadtocustomlistview(main.java:751)
at b4a.example.main$ResumableSub_FillList.resume(main.java:512)
at anywheresoftware.b4a.shell.DebugResumableSub$DelegatableResumableSub.resumeAsUserSub(DebugResumableSub.java:48)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:732)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:351)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:144)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:193)
at anywheresoftware.b4a.shell.DebugResumableSub$DelegatableResumableSub.resume(DebugResumableSub.java:43)
at anywheresoftware.b4a.BA.checkAndRunWaitForEvent(BA.java:267)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:137)
at anywheresoftware.b4a.BA$2.run(BA.java:387)
at android.os.Handler.handleCallback(Handler.java:754)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:163)
at android.app.ActivityThread.main(ActivityThread.java:6393)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:933)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)
 

Nino Caminiti

Member
Licensed User
It should be easy enough to do. Will try to do it this weekend if you still need it.
Hi, Thanks for your reply. It would be appreciated. I'm new to this and to be honest, I'm not very good. I have tried to modify the code for b4I but when I open the app it parses the RSS feed to the view and then crash :( :
 

Nino Caminiti

Member
Licensed User
This is the code

B4X:
#Region Shared Files
#CustomBuildAction: folders ready, %WINDIR%\System32\Robocopy.exe,"..\..\Shared Files" "..\Files"
'Ctrl + click to sync files: ide://run?file=%WINDIR%\System32\Robocopy.exe&args=..\..\Shared+Files&args=..\Files&FilesSync=True
#End Region

'Ctrl + click to export as zip: ide://run?File=%B4X%\Zipper.jar&Args=Project.zip

Sub Class_Globals
    Type RssCardData (Title As String, Content As String, Link As String) 'new Color field
    Private Root As B4XView
    Private xui As XUI
    Private ParsedData As Map
    Private lblTitle As B4XView
    Private lblContent As B4XView
    Private ContentHolderPanel As B4XView
    Private Labelaction1 As B4XView
    Private CLV1 As CustomListView

   
End Sub

Public Sub Initialize
'    B4XPages.GetManager.LogEvents = True
End Sub

'This event will be called once, before the page becomes visible.
Private Sub B4XPage_Created (Root1 As B4XView)
    Root = Root1
    'load the layout to Root
    Root.LoadLayout("2")
    FillList
       
End Sub
Sub FillList
    Dim j As HttpJob
    j.Initialize("job",Me)
    j.Download("https://www.ilsole24ore.com/rss/finanza--quotate-italia.xml")
    Wait For (j) JobDone(j As HttpJob)
   
    If j.Success Then
        'need to populate an XUI custom listview
        ParseRSSAndLoadToCLV1(j.GetString)
        Log(j.GetString)
    End If
    j.Release
    'second request
    Dim j As HttpJob 'redim and initialize
    j.Initialize("", Me)
    j.Download("https://www.morningstar.it/it/news/rss.aspx?lang=it-IT")
    Wait For (j) JobDone(j As HttpJob)
    If j.Success Then
        'need to populate an XUI custom listview
        ParseRSSAndLoadToCLV1(j.GetString)
        Log(j.GetString)
    End If
    j.Release
End Sub

Sub ParseRSSAndLoadToCLV1(rssString As String)
    Dim xm As Xml2Map
    xm.Initialize
    Dim ParsedData = xm.Parse(rssString) As Map
    Dim rss As Map = ParsedData.Get("rss")
    Dim channel As Map = rss.Get("channel")
    Dim items As List = channel.Get("item")
    For Each item As Map In items
        Dim title As String = item.Get("title")
        Dim link As String = item.Get("link")
        Dim description As String = item.Get("description")
        AddCLV1Item(title,link,description)
    Next

End Sub


Sub AddCLV1Item(Title As String, Link As String, Description As String)
    Dim cd As RssCardData
    cd.Initialize
    cd.Title=Title
    cd.Link=Link
    cd.Content=Description
    Dim p As B4XView = xui.CreatePanel("")
    p.SetLayoutAnimated(0, 0, 0, CLV1.AsView.Width, 280dip)
    p.LoadLayout("Card1")
    lblTitle.Text = cd.Title
    Dim su As StringUtils
    LogColor("lblContent.height before: "&lblContent.Height,Colors.red)
    lblContent.Text = cd.Content
    LogColor("lblContent.height after: "&lblContent.Height,Colors.red)
    Labelaction1.Top=lblContent.Height+lblContent.Top
    ContentHolderPanel.Height=Labelaction1.Top+Labelaction1.Height+2dip
    p.Height=Labelaction1.Top+Labelaction1.Height+5dip
    Log("P.height="&p.Height)
    Log("100%y="&100%y)
    CLV1.Add(p,cd)
    Dim p2=CLV1.GetPanel(CLV1.Size-1) As Panel
    Dim parent=p2.Parent As Panel
   
    Log("size in view: "&parent.height)
End Sub

Sub CLV1_ItemClick (Index As Int, Value As Object)
    Log("CLV1_ItemClick Index="&Index&" Value="&Value)
    Dim cd=Value As RssCardData
    CallSubDelayed3("page2","Show",cd.Link,"Article - Shared by This App")
End Sub

Page2:
B4X:
Sub Class_Globals
    Private Root As B4XView 'ignore
    Private xui As XUI 'ignore
    Dim currentUrl As String
    Dim closed As Boolean
    Private WebView1 As WebView
    Dim currentUrl As String
    Dim closed As Boolean
    Private pnlHolder As Panel
    
End Sub

'You can add more parameters here.
Public Sub Initialize As Object
    Return Me
End Sub

'This event will be called once, before the page becomes visible.
Private Sub B4XPage_Created (Root1 As B4XView)

    'load the layout to Root
    
End Sub

'You can see the list of page related events in the B4XPagesManager object. The event name is B4XPage.
Sub Activity_Resume
    Try
        If closed Then WebView1.LoadUrl(currentUrl)
        closed=False
    Catch
    End Try
End Sub


Sub Activity_Pause (UserClosed As Boolean)
    If UserClosed Then closed=True
End Sub
Sub Show(URL As String)
    currentUrl=URL
    If Not(pnlHolder.IsInitialized) Then
        pnlHolder.Initialize("")
        pnlHolder.AddView(pnlHolder,0,0,100%x,100%y)
    End If
    pnlHolder.LoadLayout("WebView1")

    closed=False

    WebView1.LoadUrl(URL)
End Sub

Sub Webview1_OverrideUrl (Url As String) As Boolean
    Log("override url")
    Log(Url)
    Main.App.OpenURL(Url)
    Return True
End Sub
 
Top