org.symbian.tools.wrttools.doc.WRTKit/html/WRTKit_RSS_Reader_user_interface-GUID-1083a0c4-a953-4b6e-a4d0-45a031e51c35.html
changeset 230 7848c135d915
equal deleted inserted replaced
229:716254ccbcc0 230:7848c135d915
       
     1 <?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
       
     2 <html lang="en" xml:lang="en">
       
     3 <head>
       
     4 <meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
       
     5 <meta name="copyright" content="(C) Copyright 2005" />
       
     6 <meta name="DC.rights.owner" content="(C) Copyright 2005" />
       
     7 <meta content="concept" name="DC.Type" />
       
     8 <meta name="DC.Title" content="RSS Reader user interface" />
       
     9 <meta scheme="URI" name="DC.Relation" content="WRTKit_RSS_Reader_Tutorial-GUID-678d197f-c7b0-4e5e-85e2-f8549c75bbe8.html" />
       
    10 <meta content="XHTML" name="DC.Format" />
       
    11 <meta content="GUID-1083A0C4-A953-4B6E-A4D0-45A031E51C35" name="DC.Identifier" />
       
    12 <meta content="en" name="DC.Language" />
       
    13 <link href="commonltr.css" type="text/css" rel="stylesheet" />
       
    14 <title>
       
    15 RSS Reader user interface</title>
       
    16 </head>
       
    17 <body id="GUID-1083A0C4-A953-4B6E-A4D0-45A031E51C35"><a name="GUID-1083A0C4-A953-4B6E-A4D0-45A031E51C35"><!-- --></a>
       
    18 
       
    19 
       
    20 
       
    21     <h1 class="topictitle1">
       
    22 RSS Reader user interface</h1>
       
    23 
       
    24     <div>
       
    25 
       
    26         <div class="section"><h2 class="sectiontitle">
       
    27 Preferences</h2>
       
    28 
       
    29             
       
    30             <p>
       
    31 
       
    32                 Now it's time to write some code so let's open up RSSReader.js. The first thing
       
    33                 we will do is implement the init() function that gets called when the widget has
       
    34                 loaded. We will begin by setting up the timer-based updating mechanism for the
       
    35                 feed updates by declaring four variables that we'll need for that:
       
    36             </p>
       
    37 
       
    38 <pre>
       
    39 
       
    40 // Feed update timer identifier.
       
    41 var updateTimerId = null;
       
    42 
       
    43 // Feed URL and update frequency (in milliseconds; -1 if no auto update).
       
    44 var feedURL = null;
       
    45 var feedUpdateFrequency = -1;
       
    46 
       
    47 // Next scheduled update time; -1 if never.
       
    48 var feedUpdateTime = -1;
       
    49 </pre>
       
    50 
       
    51             <p>
       
    52 
       
    53                 We know that we'll need to get some working values for the feed URL and feed update
       
    54                 frequency variables and we know that they will be configurable values so let's write
       
    55                 the code for this:
       
    56             </p>
       
    57 
       
    58 <pre>
       
    59 
       
    60 // Called from the onload event handler to initialize the widget.
       
    61 function init() {
       
    62     // load preferences
       
    63     loadPreferences();
       
    64 
       
    65     // start feed update timer (called once every second)
       
    66     updateTimerId = setInterval(updateFeedTimerFunc, 1000);
       
    67 }
       
    68 
       
    69 // Loads widget preferences.
       
    70 function loadPreferences() {
       
    71     if (window.widget) {
       
    72         // read feed URL and update frequency from the widget settings
       
    73         feedURL = widget.preferenceForKey("FeedURL");
       
    74         var feedUpdateFrequencyStr = widget.preferenceForKey("FeedUpdateFrequency");
       
    75         feedUpdateFrequency = (feedUpdateFrequencyStr == null) ? -1 : parseInt(feedUpdateFrequencyStr);
       
    76     }
       
    77 }
       
    78 
       
    79 // Timer function for feed updates - called once every second.
       
    80 function updateFeedTimerFunc() {
       
    81     
       
    82 }
       
    83 </pre>
       
    84 
       
    85             <p>
       
    86 
       
    87                 The init() function does two things at this point. First it calls our newly created
       
    88                 loadPreferences() function that takes care of reading some values for the feedURL
       
    89                 and feedUpdateFrequency variables. After this it starts up an interval timer that
       
    90                 calls updateFeedTimerFunc() once every second. The function doesn't do anything
       
    91                 yet but we'll get to that in a bit. The timer identifier is stored in the updateTimerId 
       
    92                 variable. If no configuration is found, feedURL will have a value of null and
       
    93                 feedUpdateFrequency will have a value of -1. Note that all preferences are stored
       
    94                 as strings so we need to parse the string value to an integer. Also note that we
       
    95                 wrapped the preference loading code in an if-clause that checks if we are in the
       
    96                 S60 Web Runtime environment. This allows us to run the code in a PC browser without
       
    97                 getting an error message about the widget -related methods that don't exist outside
       
    98                 of the S60 Web Runtime.
       
    99             </p>
       
   100 
       
   101             <p>
       
   102 
       
   103                 While we're on the topic of preferences we'll write a save counterpart for the
       
   104                 loadPreferences() function.
       
   105             </p>
       
   106 
       
   107 <pre>
       
   108 
       
   109 // Saves widget preferences.
       
   110 function savePreferences() {
       
   111     if (window.widget) {
       
   112         // save settings in widget preferences store
       
   113         widget.setPreferenceForKey(feedURL, "FeedURL");
       
   114         widget.setPreferenceForKey(feedUpdateFrequency.toString(), "FeedUpdateFrequency");
       
   115     }
       
   116 }
       
   117 </pre>
       
   118 
       
   119             <p>
       
   120 
       
   121                 We're now almost done with the timer mechanism that will update the RSS feed but
       
   122                 we are missing one thing: a way to manually schedule an immediate update of the
       
   123                 feeds. Let's add a flag that we can use to track if an update was triggered
       
   124                 automatically or manually:
       
   125             </p>
       
   126 
       
   127 <pre>
       
   128 
       
   129 // Flag that tracks if a feed update is commanded or automatic.
       
   130 var feedUpdateCommanded = false;
       
   131 </pre>
       
   132 
       
   133             <p>
       
   134 
       
   135                 And now let's add a function that can be called to schedule an immediate update:
       
   136             </p>
       
   137 
       
   138 <pre>
       
   139 
       
   140 // Schedules an immediate feed update.
       
   141 function updateFeed() {
       
   142     feedUpdateTime = 0;
       
   143     feedUpdateCommanded = true;
       
   144 }
       
   145 </pre>
       
   146 
       
   147             <p>
       
   148 
       
   149                 The function just sets the next update time to 0 so that the next time the
       
   150                 timer function runs it will notice that it's time to schedule a feed update.
       
   151                 The function also sets the feedUpdateCommanded flag to true so that the
       
   152                 updating mechanism will know that this was a manual update.
       
   153             </p>
       
   154 
       
   155         </div>
       
   156 
       
   157         <div class="section"><h2 class="sectiontitle">
       
   158 Creating the user interface</h2>
       
   159 
       
   160             
       
   161             <p>
       
   162 
       
   163                 Now let's create the user interface. We'll start by declaring three variables
       
   164                 where we will hold references to the user interface manager, main view and settings
       
   165                 view. Note that these should be outside the init() function.
       
   166             </p>
       
   167 
       
   168 <pre>
       
   169 
       
   170 // References to the WRTKit user interface manager and views.
       
   171 var uiManager;
       
   172 var mainView;
       
   173 var settingsView;
       
   174 </pre>
       
   175 
       
   176             <p>
       
   177 
       
   178                 We want our user interface to be in tab navigation mode and we want the softkey
       
   179                 bar to be visible. The code for this is the same as in the Hello World example.
       
   180                 Next we create the user interface manager, main view and settings view by adding
       
   181                 the following code to the init() function:
       
   182             </p>
       
   183 
       
   184 <pre>
       
   185 
       
   186 if (window.widget) {
       
   187     // set tab-navigation mode and show softkeys
       
   188     widget.setNavigationEnabled(false);
       
   189     menu.showSoftkeys();
       
   190 }
       
   191 
       
   192 // create UI manager
       
   193 uiManager = new UIManager();
       
   194 
       
   195 // create main view
       
   196 mainView = new ListView();
       
   197 
       
   198 // create settings view
       
   199 settingsView = new ListView(null, "Settings");
       
   200 </pre>
       
   201 
       
   202             <p>
       
   203 
       
   204                 You might have noticed that we didn't supply any arguments to the ListView constructor
       
   205                 when the main view was created. The reason for this is that we will set the view caption
       
   206                 dynamically depending on the news feed we are following. And since we don't need the
       
   207                 unique identifier for the main view we don't even have to pass null to it. Remember: in
       
   208                 JavaScript if you don't pass an argument it will be undefined, which is equal to null.
       
   209             </p>
       
   210 
       
   211             <p>
       
   212 
       
   213                 The main view will not get populated with controls until we have some news feed items
       
   214                 to display, but we can go ahead and create the settings view. Again, we will first
       
   215                 declare variables to hold references to the controls and again, they should be declared
       
   216                 outside the init() method so that they are accessible elsewhere in the widget code:
       
   217             </p>
       
   218 
       
   219 <pre>
       
   220 
       
   221 // Reference to settings controls.
       
   222 var feedSelection;
       
   223 var feedUpdateFrequencySelection;
       
   224 var settingsSaveButton;
       
   225 var settingsCancelButton;
       
   226 </pre>
       
   227 
       
   228             <p>
       
   229 
       
   230                 Now that we have variables to receive the control references we can go ahead and create
       
   231                 them and add them to the settings view. We will create a SelectionMenu control to let
       
   232                 the user select the RSS feed to show, a SelectionList control to allow selection of
       
   233                 the feed update frequency and two form buttons: "Save" and "Cancel". The SelectionMenu
       
   234                 and SelectionList controls are identical from a developer's point of view but look
       
   235                 very different. The SelectionMenu takes up very little space in the view but when clicked
       
   236                 it pops up a list of options that the user can select from. This is good if theres a lot
       
   237                 of options and we don't want to use up a lot of space from the view. The SelectionList
       
   238                 is the exact opposite and shows all the options right there in the view. This is good
       
   239                 if the widget is in pointer navigation mode or if there are very few options.
       
   240             </p>
       
   241 
       
   242             <p>
       
   243 
       
   244                 Options for the SelectionMenu and SelectionList controls are defined as an array of
       
   245                 JavaScript objects that have two properties: value and text. The value property contains
       
   246                 the actual data of the option and the text property contains the string to display to
       
   247                 the user. Before we create the controls we need to create the option arrays for the
       
   248                 RSS feed options and update frequency options. These will simply be hard coded arrays
       
   249                 that are defined using JavaScript object notation (JSON) and we'll place them at the top
       
   250                 of the widget code so that they can be easily customized later on:
       
   251             </p>
       
   252 
       
   253 <pre>
       
   254 
       
   255 // Feed source options.
       
   256 var feedOptions = [
       
   257     { value: "http://www.womworld.com/nseries/feed/", text: "Nseries WOM World" },
       
   258     { value: "http://feeds.feedburner.com/N958GB", text: "N95 8GB News" },
       
   259     { value: "http://feeds.feedburner.com/N95", text: "N95 News" },
       
   260     { value: "http://feeds.feedburner.com/N93", text: "N93 News" },
       
   261     { value: "http://feeds.feedburner.com/N91", text: "N91 News" },
       
   262     { value: "http://feeds.feedburner.com/N82", text: "N82 News" },
       
   263     { value: "http://feeds.feedburner.com/N81", text: "N81 News" },
       
   264     { value: "http://feeds.feedburner.com/N810", text: "N810 News" },
       
   265     { value: "http://feeds.feedburner.com/N800", text: "N800 News" },
       
   266     { value: "http://feeds.feedburner.com/N76", text: "N76 News" }
       
   267 ];
       
   268 
       
   269 // Feed update frequency.
       
   270 var updateFrequencyOptions = [
       
   271     { value: -1, text: "never" },
       
   272     { value: (1000 * 60 * 5), text: "every 5 min" },
       
   273     { value: (1000 * 60 * 15), text: "every 15 min" },
       
   274     { value: (1000 * 60 * 60), text: "every 60 min" },
       
   275 ];
       
   276 </pre>
       
   277 
       
   278             <p>
       
   279 
       
   280                 The RSS feeds are all from the Nokia Nseries WOM World website but you could put any
       
   281                 RSS feed URLs here that you like. However it is probably a good idea to stick with
       
   282                 these for now since we know that they work. Later when the widget is completed you can try
       
   283                 with other feeds. Note how the value is a URL but the text to display is a human readable
       
   284                 name for the RSS feeds.
       
   285             </p>
       
   286 
       
   287             <p>
       
   288 
       
   289                 The update frequency options are defined in milliseconds and there is one option with a
       
   290                 magic value of -1 for "never". Here too you'll notice the difference between the value
       
   291                 (an integer in this case) and the human readable text.
       
   292             </p>
       
   293 
       
   294             <p>
       
   295 
       
   296                 Now that we have the option arrays we can create the controls for the settings view by
       
   297                 adding the following code to the init() function:
       
   298             </p>
       
   299 
       
   300 <pre>
       
   301 
       
   302     // feed selection control
       
   303     feedSelection = new SelectionMenu(null, "Select feed", feedOptions);
       
   304     settingsView.addControl(feedSelection);
       
   305     
       
   306     // feed update frequency selection control
       
   307     feedUpdateFrequencySelection = new SelectionList(null, "Check for updates", updateFrequencyOptions);
       
   308     settingsView.addControl(feedUpdateFrequencySelection);
       
   309     
       
   310     // save settings button
       
   311     settingsSaveButton = new FormButton(null, "Save");
       
   312     settingsView.addControl(settingsSaveButton);
       
   313     
       
   314     // cancel settings button
       
   315     settingsCancelButton = new FormButton(null, "Cancel");
       
   316     settingsView.addControl(settingsCancelButton);
       
   317 </pre>
       
   318 
       
   319             <p>
       
   320 
       
   321                 The two first arguments for the SelectionMenu and SelectionList constructors are the
       
   322                 same as for most other controls: a unique identifier and a control caption. The third 
       
   323                 argument points to the array of options that the controls should display. You could
       
   324                 also have omitted that argument from the constructor and instead called setOptions()
       
   325                 later on, but why do it in two steps when you can do it in one?
       
   326             </p>
       
   327 
       
   328             <p>
       
   329 
       
   330                 The user interface views are now done (minus the actual news items to display in the main
       
   331                 view of course) but we still have some things to implement for the user interface. The
       
   332                 buttons in the settings view don't do anything yet so let's fix that.
       
   333             </p>
       
   334 
       
   335             <p>
       
   336 
       
   337                 The cancel button should take the user to the main view and the save button should
       
   338                 start using the newly configured settings, save them, and then go to the main view.
       
   339                 Our plan to implement this is to create a function for showing the main view, called
       
   340                 "showMainView()", a similar function for showing the settings view that we will call
       
   341                 "showSettings()", and a function that will be called when the save button is clicked
       
   342                 called "saveSettingsClicked()". We will then add event listeners to the two buttons
       
   343                 so that clicking the save button will result in a call to the saveSettingsClicked()
       
   344                 function and clicking the cancel button will result in a call to the showMainView()
       
   345                 function. Let's create empty placeholders for the functions first:
       
   346             </p>
       
   347 
       
   348 <pre>
       
   349 
       
   350 // Callback for settings view save button.
       
   351 function saveSettingsClicked() {
       
   352 }
       
   353 
       
   354 // Show main view.
       
   355 function showMainView() {
       
   356 }
       
   357 
       
   358 // Show settings view.
       
   359 function showSettings() {
       
   360 }
       
   361 </pre>
       
   362 
       
   363             <p>
       
   364 
       
   365                 Now that we have those functions let's register the event listeners to the form
       
   366                 buttons by adding these two lines of code immediately after where the buttons
       
   367                 are created:
       
   368             </p>
       
   369 
       
   370 <pre>
       
   371 
       
   372 settingsSaveButton.addEventListener("ActionPerformed", saveSettingsClicked);
       
   373 settingsCancelButton.addEventListener("ActionPerformed", showMainView);
       
   374 </pre>
       
   375 
       
   376             <p>
       
   377 
       
   378                 We are now ready to implement the functions to show the main view, settings view
       
   379                 and react to the save button click. But we won't implement those just yet because
       
   380                 we want to do one more thing before that. Let's create the custom Options menu.
       
   381                 The Options menu isn't using any WRTKit code but rather the standard S60 Web Runtime
       
   382                 widget menu functionality. We'll have two menu items: "Refresh" to schedule an immediate
       
   383                 news feed update and "Settings" to go to the settings view. The Web Runtime Options
       
   384                 menu works so that a callback function gets called when the user selections an Options
       
   385                 menu item. In order to recognize which menu item was selected we'll need a unique
       
   386                 identifier for each of them. Let's create those:
       
   387             </p>
       
   388 
       
   389 <pre>
       
   390 
       
   391 // Constants for menu item identifiers.
       
   392 var MENU_ITEM_SETTINGS = 0;
       
   393 var MENU_ITEM_REFRESH = 1;
       
   394 </pre>
       
   395 
       
   396             <p>
       
   397 
       
   398                 Next we'll create the callback function that will be called when the menu items are
       
   399                 selected:
       
   400             </p>
       
   401 
       
   402 <pre>
       
   403 
       
   404 // Callback for when menu items are selected.
       
   405 function menuItemSelected(id) {
       
   406     switch (id) {
       
   407         case MENU_ITEM_SETTINGS:
       
   408             showSettings();
       
   409             break;
       
   410         case MENU_ITEM_REFRESH:
       
   411             updateFeed();
       
   412             break;
       
   413     }
       
   414 }
       
   415 </pre>
       
   416 
       
   417             <p>
       
   418 
       
   419                 This function gets the menu item identifier passed to it when the user selects
       
   420                 a menu item. The switch-case will branch off to call showSettings() if the "Settings"
       
   421                 menu item was selected and updateFeed() if the "Refresh" menu item was selected.
       
   422                 But we haven't actually created the menu yet so let's do that by adding this to the
       
   423                 init() function right after where we show the softkey bar. We want to have this piece
       
   424                 of code inside the if-clause that checks if we're in the S60 Web Runtime because we
       
   425                 don't have the Options menu functionality on a PC browser.
       
   426             </p>
       
   427 
       
   428 <pre>
       
   429 
       
   430 // create menu
       
   431 var settingsMenuItem = new MenuItem("Settings", MENU_ITEM_SETTINGS);
       
   432 settingsMenuItem.onSelect = menuItemSelected;
       
   433 menu.append(settingsMenuItem);
       
   434 var refreshMenuItem = new MenuItem("Refresh", MENU_ITEM_REFRESH);
       
   435 refreshMenuItem.onSelect = menuItemSelected;
       
   436 menu.append(refreshMenuItem);
       
   437 </pre>
       
   438 
       
   439             <p>
       
   440 
       
   441                 The code simply creates two MenuItem objects, gives them a label and a unique
       
   442                 identifier, specifies the callback function to call when selected and then adds
       
   443                 them to the Options menu. The menu object is a global object that automatically
       
   444                 exists in the S60 Web Runtime.
       
   445             </p>
       
   446 
       
   447             <p>
       
   448 
       
   449                 Now let's return to the three functions we created but didn't implement. We will
       
   450                 start with the showMainMenu() function. This function should perform all necessary
       
   451                 steps to show the main menu. This includes the following: setting a caption for
       
   452                 the main view, setting the right softkey to be the default "Exit" label and 
       
   453                 functionality, and then actually showing the main view by calling setView() in the
       
   454                 user interface manager. We'll get the main view caption by checking which of the
       
   455                 RSS feeds the user has currently selected. We do this by looping through the feed
       
   456                 options and looking for the feed URL that is currently in use. If we can't find one
       
   457                 we'll default to "RSS Reader".
       
   458             </p>
       
   459 
       
   460 <pre>
       
   461 
       
   462 // Show main view.
       
   463 function showMainView() {
       
   464     // set main view caption from feed name
       
   465     var feedName = null;
       
   466     for (var i = 0; i &lt; feedOptions.length; i++) {
       
   467         if (feedOptions[i].value == feedURL) {
       
   468             feedName = feedOptions[i].text;
       
   469             break;
       
   470         }
       
   471     }
       
   472     var mainViewCaption = (feedName == null) ? "RSS Reader" : feedName;
       
   473     mainView.setCaption(mainViewCaption);
       
   474     
       
   475     // set right softkey to "exit"
       
   476     if (window.widget) {
       
   477         menu.setRightSoftkeyLabel("", null);
       
   478     }
       
   479     
       
   480     // show the main view
       
   481     uiManager.setView(mainView);
       
   482 }
       
   483 </pre>
       
   484 
       
   485             <p>
       
   486 
       
   487                 When the settings view is shown we first want to place the controls into
       
   488                 a state that reflects the current configuration. In other words we want
       
   489                 the currently configured feed to be the one that's selected in the feed selection
       
   490                 control. In the same way the currently configured feed update frequency should
       
   491                 be selected in the feed update frequency selection control. There is a very
       
   492                 convenient method available for this called getOptionForValue(). Using that
       
   493                 function we can pass the currently configured feed URL and feed update frequency
       
   494                 and get back the options object that corresponds to the configuration value.
       
   495                 After this we can use that options object when we call setSelected() to select
       
   496                 that option.
       
   497             </p>
       
   498 
       
   499             <p>
       
   500 
       
   501                 If there is no valid configuration then we disable the cancel button and make
       
   502                 the right softkey be "Exit". This is useful when the widget is started for the
       
   503                 first time so that user has to enter a valid configuration before starting to
       
   504                 use the widget. If there is a valid configuration we set the right softkey to
       
   505                 "Cancel" and make it call the showMainView() function that we just created. The
       
   506                 "Cancel" button will also be enabled.
       
   507             </p>
       
   508 
       
   509             <p>
       
   510 
       
   511                 Finally we'll switch to the settings view by calling setView() in the user 
       
   512                 interface manager.
       
   513             </p>
       
   514 
       
   515 <pre>
       
   516 
       
   517 // Show settings view.
       
   518 function showSettings() {
       
   519     // URL (use first available feed if null)
       
   520     var feedOption = (feedURL == null) ? feedOptions[0] : feedSelection.getOptionForValue(feedURL);
       
   521     feedSelection.setSelected(feedOption);
       
   522     
       
   523     // frequency
       
   524     var feedUpdateFrequencyOption = feedUpdateFrequencySelection.getOptionForValue(feedUpdateFrequency);
       
   525     feedUpdateFrequencySelection.setSelected(feedUpdateFrequencyOption);
       
   526     
       
   527     if (feedURL == null) {
       
   528         // no valid configuration
       
   529         // disable cancel button - set right softkey to "exit"
       
   530         settingsCancelButton.setEnabled(false);
       
   531         if (window.widget) {
       
   532             menu.setRightSoftkeyLabel("", null);
       
   533         }
       
   534     } else {
       
   535         // we have a valid configuration
       
   536         // enable cancel button - set right softkey to "cancel"
       
   537         settingsCancelButton.setEnabled(true);
       
   538         if (window.widget) {
       
   539             menu.setRightSoftkeyLabel("Cancel", showMainView);
       
   540         }
       
   541     }
       
   542     
       
   543     // show the settings view
       
   544     uiManager.setView(settingsView);
       
   545 }
       
   546 </pre>
       
   547 
       
   548             <p>
       
   549 
       
   550                 The third function to implement is the callback for when the save button is clicked.
       
   551                 First we take the selected options from the feed selection and feed update frequency
       
   552                 selection controls. Those selected values are copied to the feedURL and feedUpdateFrequency
       
   553                 variables that are used by the widget during runtime. Next the settings are saved using
       
   554                 the savePreferences() function that we implemented earlier. And finally we call the
       
   555                 showMainView() method so that the widget shows the main view with the news items.
       
   556             </p>
       
   557 
       
   558 <pre>
       
   559 
       
   560 // Callback for settings view save button.
       
   561 function saveSettingsClicked() {
       
   562     // update feed URL
       
   563     var selectedFeed = feedSelection.getSelected();
       
   564     feedURL = (selectedFeed != null) ? selectedFeed.value : null;
       
   565     
       
   566     // update frequency
       
   567     var selectedFrequency = feedUpdateFrequencySelection.getSelected();
       
   568     feedUpdateFrequency = (selectedFrequency != null) ? selectedFrequency.value : -1;
       
   569     
       
   570     // save preferences
       
   571     savePreferences();
       
   572     
       
   573     // return to main view
       
   574     showMainView();
       
   575 }
       
   576 </pre>
       
   577 
       
   578             <p>
       
   579 
       
   580                 The user interface is now nearly done but the init() function needs one more
       
   581                 thing. We need to show a view after the function is done initializing
       
   582                 the widget. The view to show depeneds on whether we have a valid
       
   583                 configuration or not. If we do then we'll show the main view. If not then
       
   584                 we'll show the settings view. Let's add this code to the end of the init()
       
   585                 function, just before we start the update timer:
       
   586             </p>
       
   587 
       
   588 <pre>
       
   589 
       
   590 // display the main view if a feed has been configured
       
   591 // otherwise show the settings view
       
   592 if (feedURL != null) {
       
   593     showMainView();
       
   594     updateFeed();
       
   595 } else {
       
   596     showSettings();
       
   597 }
       
   598 </pre>
       
   599 
       
   600             <p>
       
   601 
       
   602                 You can now go ahead and try out the widget either on a handset, emulator
       
   603                 or in a PC browser. You should have a working settings view and when clicking
       
   604                 the save button in the settings view you should end up in the main view. From
       
   605                 there you can go to the settings by selecting "Settings" in the Options menu.
       
   606             </p>
       
   607 
       
   608             <p>
       
   609 
       
   610                 There are no news items to show yet but that's our next task.
       
   611             </p>
       
   612 
       
   613             <div class="fignone" id="GUID-1083A0C4-A953-4B6E-A4D0-45A031E51C35__GUID-31A7B99C-BD6B-42E2-8430-631D210FAFC0"><a name="GUID-1083A0C4-A953-4B6E-A4D0-45A031E51C35__GUID-31A7B99C-BD6B-42E2-8430-631D210FAFC0"><!-- --></a><span class="figcap">Figure 1. 
       
   614 RSS Reader settings view</span>
       
   615 
       
   616                 
       
   617                 <br /><img src="RSS_Reader_Settings_Screenshot_1.png" /><br />
       
   618             </div>
       
   619 
       
   620         </div>
       
   621 
       
   622     </div>
       
   623 
       
   624 <div>
       
   625 <div class="familylinks">
       
   626 <div class="parentlink"><strong>Parent topic:</strong> <a href="WRTKit_RSS_Reader_Tutorial-GUID-678d197f-c7b0-4e5e-85e2-f8549c75bbe8.html">RSS Reader</a></div>
       
   627 </div>
       
   628 </div>
       
   629 
       
   630 </body>
       
   631 </html>