Weekend Coder: Using ListView to create an RSS feed

By Brian Scheirer on 8 Sep 2013 05:35 pm EDT
-
loading...
-
loading...
-
loading...

Way back at my first conference, BlackBerry Jam Americas 2012, I heard an interesting statistic: 80% of all apps contain lists. And if you think about it's not that surprising of a statistic considering most of the social network apps (Twitter, Facebook, etc) and everyone's favorite app, CB10, are a list of items. Because of that BlackBerry made sure to have a very good feature for lists, and they do called ListView. So this tutorial will mainly focus on ListView but will have a few other features to make the sample application a bit more full featured.

A bit more back story about this tutorial (feel free to skip this part if you just want to learn coding stuff), I wrote this example app very quickly (given a 2 day deadline) for a friend who lives in Trinidad and Tobago and wanted to show it off at a local developer meet up. So the feed is for a local newspaper there. But since RSS feeds usually follow the same .xml format you should be able to replace the source with any feed of your choosing. Finally, this tutorial may not be the best one to read if you are completely new to Cascades because I skip some explanations for the sake of length. On to the tutorial...

Before we set up our ListView, since we know we are going to use certain imports and libraries let's call those in first. So at the top of the page along with bb.cascades 1.0 we need to import in the data library.

import bb.cascades 1.0 import bb.data 1.0

Then in our .pro file we need the following libraries.

LIBS += -lbbdata -lbbsystem -lscreen

ListView

Now let's set up the ListView.  The basic components are ListItemComponent {} which holds the display of the list items, GroupDataModel {} which sorts the data, and DataSource which is exactly what it sounds like, the source of your data. So that general setup would look something like the following

import bb.cascades 1.0 import bb.data 1.0 Page { id: newsPane Container { ListView { id: myListView dataModel: myDataModel listItemComponents: [ ListItemComponent { type: "header" }, ListItemComponent { type: "item" } ] onTriggered: { } } } attachedObjects: [ GroupDataModel { id: myDataModel }, DataSource { id: myDataSource source: "" query: "" type: DataSourceType.Xml onDataLoaded: { } } ] onCreationCompleted: { myDataSource.load(); } }

Now that we have the framework of our ListView we can start filling in our information. First the The DataSource, we need the source: "" and query: "" and then onDataLoaded: {} we want to clear the list then populate it from our source.

DataSource { id: myDataSource source: "http://newsday.co.tt/rss.xml" query: "/rss/channel/item" type: DataSourceType.Xml onDataLoaded: { myDataModel.clear(); myDataModel.insertList(data) } }

Next the GroupDataModel has sortingKeys which we'll want to sort by date, and the tag in the .xml file is "pubdate"

GroupDataModel { id: myDataModel sortingKeys: [ "pubDate" ] sortedAscending: false grouping: ItemGrouping.ByFullValue }

Finally the display of the actual list. For both the header and item let's use custom compoents (rather than StandardListIem) to exactly control the look of components. In this example I didn't want any "header" to show so the easiest way to have that is to have the header as a Container with a blank Label

ListItemComponent { type: "header" Container { Label { text: "" } } }

Then for the "item" compoenent with a stack of Labels with the article title, date, and description. To help separate the feed items, I've inserted a Divider at the bottom of my custom component.

ListItemComponent { type: "item" // Custom List compoents Container { Label { text: ListItemData.title textStyle.fontWeight: FontWeight.Bold multiline: true } Label { text: ListItemData.pubDate } Label { text: ListItemData.description textStyle.fontSize: FontSize.Small multiline: true } Divider { } } }

Additional Features

A stylized title bar can be added to the top of the page. In this example I use name of the newspaper as the title.

Page { titleBar: TitleBar { title: "Newsday" } ... }

The ListView should now be fully set up, however there will be only the info pulled from the .xml shown. Typically a user expects to be able to click on an item and it brings them to the full article and that can be done using the onTriggered: {} signal and a WebView. The WebView will be added to the attached objects inside of Page. To give the WebView page a full set a features, I have also added a ScollView, and a ProgressIndicator for a loading bar. Additionally for the push/pop navigation to work everything needs to be in a NavigationPane. At this point it is easiest to these all added at once.

import bb.cascades 1.0 import bb.data 1.0 NavigationPane { id: newsPane Page { titleBar: TitleBar { title: "Newsday" } Container { ListView { id: myListView dataModel: myDataModel listItemComponents: [ ListItemComponent { type: "header" Container { ... } }, ListItemComponent { type: "item" // Custom List components Container { ... } } ] onTriggered: { var feedItem = dataModel.data(indexPath); var page = detailsPage.createObject(); page.htmlContent = feedItem.link; newsPane.push(page); } } } } attachedObjects: [ GroupDataModel { id: myDataModel ... }, DataSource { id: myDataSource ... }, ComponentDefinition { id: detailsPage Page { property alias htmlContent: detailsView.url Container { layout: DockLayout { } Container { ScrollView { scrollViewProperties.scrollMode: ScrollMode.Both scrollViewProperties { pinchToZoomEnabled: true maxContentScale: 5 minContentScale: 1 } WebView { id: detailsView settings.zoomToFitEnabled: true settings.activeTextEnabled: true onLoadProgressChanged: { // Update the ProgressBar while loading. progressIndicator.value = loadProgress / 100.0 } onLoadingChanged: { if (loadRequest.status == WebLoadStatus.Started) { // Show the ProgressBar when loading started. progressIndicator.opacity = 1.0 } else if (loadRequest.status == WebLoadStatus.Succeeded) { // Hide the ProgressBar when loading is complete. progressIndicator.opacity = 0.0 } else if (loadRequest.status == WebLoadStatus.Failed) { // If loading failed html = "Check Internet connection?" progressIndicator.opacity = 0.0 } } } } } Container { bottomPadding: 25 horizontalAlignment: HorizontalAlignment.Center verticalAlignment: VerticalAlignment.Bottom ProgressIndicator { id: progressIndicator opacity: 0 } } } } } ] onCreationCompleted: { myDataSource.load(); } }

There are a few more things that can be added/enhanced, such as a more stylized "item" list component, but as I said at the beginning I wrote this sample relatively quickly. This should cover most features that are necessary for an RSS feed as well as uses quite a few other UI elements and design features too... Or just think of it as an RSRSS (Really Simple RSS, haha).

Reader comments

Weekend Coder: Using ListView to create an RSS feed

22 Comments

The term RSS feed is used almost 100% of the time.. I wouldn't consider it really an abbreviation as its used more than the actual term..

- Developer of 'Web Design Cheat Sheet' for BB10 (Posted via CB10)

In this particular case,

If you aren't familiar with the term RSS (which is no longer considered an abbreviation in developer terms) then you probably can't leverage this sample.

Good code bit. A final screen shot of the app in use might help junior devs know if they did it right :)

Posted via CB from my LE

I guess because of the start of the 2013 NFL Season today is a slow day at the office... #Justsayin

#BlueNation #NYFootballGiants #NYFGiants4Ever #NYFGChamps #EliteEli #SalsaCruz #JustinBrickStrongTuck #JPPBeast #DoneDiehl #AllIn #DriveFor5 #BigBlue #GgggMen

I'm MongezaurioBerry

Down day today? Nothing to report !
Tomorrow may be a big news day about BBMforall, channels, or strategic planning. Just hoping.

ChannelX C000D3759 We review channels

It's QML, a declarative language BlackBerry 10 uses for the UI. Cascades is kind of synonymous with QML.

Join the Surge Co. BBM Channel! C001213C9

Otech

Tutorial is written in QML and has a little embedded C++.

I also program in C# (which is close-ish to C++) on Windows and Linux so hope you're having fun with that too!

Powered by Z10 on 10.2.0.1443 via DTAC 3G

Great tutorial for RSS could you make one to show how we can praise JSON data from a Web API using Http requests if you can.

Thanks

Ali,

Posted via CB10

Awesome Brian! Firstly, another super tutorial from you, especially for us up and coming devs. You're one of the guys who have become a great aid to me and I always look forward to more tutorials - well done!

I have an awesome app running now, although not perfect as I have a few niggles to resolve, especially to make the information look as presentable as possible..

1. One of them is the 'description' of the RSS item.. depending on which rss feeds I load, some of them show perfectly, others show html tags too. I'm assuming this is because not all RSS feeds are equal on formatting. Is there a way around this?
2. Also, some descriptions are near perfect except something like the apostrophe " ' " showing up as " ’ " for eg. I'm baffled as where to look, could this be dependent on language or something?

Thank you,
Mario.

Twitter has switched off the RSS feeds and suggested an API, from what I've read. So the sample app that Mattias mentioned above gives an error.. just to mention.