diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index f547fb9..de239e8 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -18,9 +18,11 @@
+
-
-
+
+
+
\ No newline at end of file
diff --git a/res/layout/news_list_row.xml b/res/layout/news_list_row.xml
new file mode 100644
index 0000000..a6fc8e9
--- /dev/null
+++ b/res/layout/news_list_row.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/layout/news_view.xml b/res/layout/news_view.xml
new file mode 100644
index 0000000..dfaa979
--- /dev/null
+++ b/res/layout/news_view.xml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/com/studentersamfundet/app/DataHandler.java b/src/com/studentersamfundet/app/DataHandler.java
index baa57de..3e48c8f 100644
--- a/src/com/studentersamfundet/app/DataHandler.java
+++ b/src/com/studentersamfundet/app/DataHandler.java
@@ -1,13 +1,17 @@
package com.studentersamfundet.app;
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.LinkedHashSet;
import java.util.LinkedList;
-import java.util.List;
import java.util.Set;
import java.util.TreeSet;
-public class DataHandler {
- private List events = new LinkedList();
- private List news = new LinkedList();
+public class DataHandler implements Serializable {
+ private static final long serialVersionUID = 6787541405689146002L;
+
+ private Collection events = new LinkedHashSet();
+ private Collection news = new LinkedList();
private Set eventCategories = new TreeSet();
public void insertEvent(String id,
@@ -22,8 +26,6 @@ public class DataHandler {
String priceMem,
String ticketUriStr) {
int intId = Integer.parseInt(id);
- if (getEvent(intId) != null)
- return;
Event event = new Event(intId, title, description, date, location, text, category, imageUri);
diff --git a/src/com/studentersamfundet/app/Event.java b/src/com/studentersamfundet/app/Event.java
index 505f0b9..c379843 100644
--- a/src/com/studentersamfundet/app/Event.java
+++ b/src/com/studentersamfundet/app/Event.java
@@ -8,11 +8,11 @@ import java.util.Date;
import android.net.Uri;
public class Event implements Serializable {
- private static final long serialVersionUID = 1L;
- public static final String ALL = "Alle";
-
+ private static final long serialVersionUID = -5222901012434000257L;
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
+ public static final String ALL = "Alle";
+
public final int id;
public final String title;
private String description;
@@ -118,4 +118,16 @@ public class Event implements Serializable {
this.memberPrice = memberPrice;
this.ticketUriStr = ticketUri;
}
+
+ public int hashCode() {
+ return this.id;
+ }
+
+ public boolean equals(Object o2) {
+ if (o2 instanceof Event) {
+ Event e2 = (Event)o2;
+ return this.id == e2.id;
+ }
+ return false;
+ }
}
diff --git a/src/com/studentersamfundet/app/FeedFetcher.java b/src/com/studentersamfundet/app/FeedFetcher.java
index e83b84c..ddf1cbf 100644
--- a/src/com/studentersamfundet/app/FeedFetcher.java
+++ b/src/com/studentersamfundet/app/FeedFetcher.java
@@ -5,6 +5,7 @@ import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.io.Serializable;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
@@ -19,15 +20,14 @@ import org.xml.sax.SAXException;
import android.content.Context;
-public class FeedFetcher {
- private final String LOCAL_FILENAME = "dns_events";
-
- private Context context;
+public class FeedFetcher implements Serializable {
+ private static final long serialVersionUID = 3408406671996232103L;
+ private final String localFilename;
private String url;
- public FeedFetcher(Context context, String url) {
- this.context = context;
+ public FeedFetcher(String url, String localFilename) {
this.url = url;
+ this.localFilename = localFilename;
}
private InputStream openHttpConnection() throws IOException {
@@ -61,58 +61,71 @@ public class FeedFetcher {
* @throws IOException Is thrown if the app cannot download the file from
* the internet and there is no local copy.
*/
- public NodeList fetch(boolean forcedUpdate) throws IOException {
- InputStream in = null;
- NodeList itemNodes = null;
-
- /* Update the local file if possible. */
- try {
- if (forcedUpdate || doesFileNeedUpdate(context)) {
- in = openHttpConnection();
- saveFile(in, context);
- }
-
- } catch(IOException e) {
- /* OK, so we failed to update it. It doesn't matter yet, because we can try to... */
- } finally {
- if (in != null)
- in.close();
- }
-
- /* ...load local file: */
- in = loadFile(context); // if we fail here, we fail ultimately. Throw the Exception!
-
- Document doc = null;
- DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
- DocumentBuilder db;
-
- try {
- db = dbf.newDocumentBuilder();
- doc = db.parse(in);
- } catch (ParserConfigurationException e) {
- /* This should never happen. */
- } catch (SAXException e) {
- /* This shouldn't happen unless the xml returned by the server
- * is somehow invalid. If it happens, the best course of action
- * is to pretend we failed to download the event list (it's
- * close enough and it simplifies exception-handling). */
- throw new IOException("Bad response from server.");
- }
-
- doc.getDocumentElement().normalize();
-
- // Retrieve all the - nodes.
- itemNodes = doc.getElementsByTagName("item");
- in.close();
-
- return itemNodes;
+ public NodeList fetch(Context context, boolean forcedUpdate) throws IOException {
+ NodeList itemNodes = null;
+ InputStream in = null;
+
+ /* Update the local file if possible. */
+ try {
+ if (forcedUpdate || doesFileNeedUpdate(context)) {
+ in = openHttpConnection();
+ saveFile(in, context);
+ }
+
+ } catch(IOException e) {
+ /* OK, so we failed to update it. It doesn't matter yet, because we can try to... */
+ } finally {
+ if (in != null)
+ in.close();
+ }
+
+ /* ...load local file: */
+ in = loadFile(context); // if we fail here, we fail ultimately. Throw the Exception!
+ itemNodes = parseInputStream(in);
+ in.close();
+
+ return itemNodes;
+ }
+
+ public NodeList loadLocalData(Context c) throws IOException {
+ NodeList nodes;
+
+ InputStream is = loadFile(c);
+ nodes = parseInputStream(is);
+ is.close();
+
+ return nodes;
+ }
+
+ private static NodeList parseInputStream(InputStream iStream) throws IOException {
+ Document doc = null;
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+ DocumentBuilder db;
+
+ try {
+ db = dbf.newDocumentBuilder();
+ doc = db.parse(iStream);
+ } catch (ParserConfigurationException e) {
+ /* This should never happen. */
+ } catch (SAXException e) {
+ /* This shouldn't happen unless the xml returned by the server
+ * is somehow invalid. If it happens, the best course of action
+ * is to pretend we failed to download the event list (it's
+ * close enough and it simplifies exception-handling). */
+ throw new IOException("Bad response from server.");
+ }
+
+ doc.getDocumentElement().normalize();
+
+ // Retrieve all the
- nodes.
+ return doc.getElementsByTagName("item");
}
private boolean doesFileNeedUpdate(Context c) throws IOException {
/** Maximum amount of time before the file needs updating, in ms: */
final long maxInterval = 1000 * 60 * 60; // one hour
- File file = c.getFileStreamPath(LOCAL_FILENAME);
+ File file = c.getFileStreamPath(localFilename);
if (! file.exists()) return true;
long now = System.currentTimeMillis();
@@ -124,7 +137,7 @@ public class FeedFetcher {
private void saveFile(InputStream in, Context c) throws IOException, FileNotFoundException {
final int BUFFER_SIZE = 128;
- OutputStream os = c.openFileOutput(LOCAL_FILENAME, Context.MODE_PRIVATE);
+ OutputStream os = c.openFileOutput(localFilename, Context.MODE_PRIVATE);
byte[] inputBuffer = new byte[BUFFER_SIZE];
int bytes = 0;
@@ -136,6 +149,6 @@ public class FeedFetcher {
}
private InputStream loadFile(Context c) throws FileNotFoundException {
- return c.openFileInput(LOCAL_FILENAME);
+ return c.openFileInput(localFilename);
}
}
diff --git a/src/com/studentersamfundet/app/IRSSParser.java b/src/com/studentersamfundet/app/IRSSParser.java
new file mode 100644
index 0000000..60223be
--- /dev/null
+++ b/src/com/studentersamfundet/app/IRSSParser.java
@@ -0,0 +1,9 @@
+package com.studentersamfundet.app;
+
+import java.io.Serializable;
+
+import org.w3c.dom.NodeList;
+
+public interface IRSSParser extends Serializable {
+ public DataHandler parse(NodeList nodes);
+}
diff --git a/src/com/studentersamfundet/app/News.java b/src/com/studentersamfundet/app/News.java
index 68f16b6..a78aef6 100644
--- a/src/com/studentersamfundet/app/News.java
+++ b/src/com/studentersamfundet/app/News.java
@@ -1,17 +1,18 @@
package com.studentersamfundet.app;
+import java.io.Serializable;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
-import android.net.Uri;
-
-public class News {
- public String title;
- public String description;
- public String content;
- public Uri link;
- public Date pubDate;
+public class News implements Serializable {
+ private static final long serialVersionUID = 4015441794784305793L;
+
+ private String title;
+ private String description;
+ private String content;
+ private String link;
+ private Date pubDate;
private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@@ -19,7 +20,7 @@ public class News {
this.title = title.trim();
this.description = description.trim();
this.content = content.trim();
- this.link = Uri.parse(link.trim());
+ this.link = link.trim();
try {
this.pubDate = sdf.parse(pubDate.trim());
@@ -27,4 +28,24 @@ public class News {
this.pubDate = null;
}
}
+
+ public String getTitle() {
+ return this.title;
+ }
+
+ public String getDescription() {
+ return this.description;
+ }
+
+ public String getContent() {
+ return this.content;
+ }
+
+ public String getLink() {
+ return this.link;
+ }
+
+ public Date getPubDate() {
+ return this.pubDate;
+ }
}
diff --git a/src/com/studentersamfundet/app/RSSParserNews.java b/src/com/studentersamfundet/app/RSSParserNews.java
index 562d98e..52b3cd6 100644
--- a/src/com/studentersamfundet/app/RSSParserNews.java
+++ b/src/com/studentersamfundet/app/RSSParserNews.java
@@ -4,7 +4,8 @@ import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
-public class RSSParserNews {
+public class RSSParserNews implements IRSSParser {
+ private static final long serialVersionUID = -2654591623794449527L;
private final DataHandler dh;
public RSSParserNews() {
@@ -37,7 +38,7 @@ public class RSSParserNews {
NodeList titleNodes = (itemElement).getElementsByTagName("title");
NodeList descriptionNodes = (itemElement).getElementsByTagName("description");
NodeList linkNodes = (itemElement).getElementsByTagName("link");
- NodeList textNodes = (itemElement).getElementsByTagName("content");
+ NodeList textNodes = (itemElement).getElementsByTagName("content:encoded");
NodeList dateNodes = (itemElement).getElementsByTagName("pubDate");
// Convert a Node into an Element.
diff --git a/src/com/studentersamfundet/app/RSSParserProgram.java b/src/com/studentersamfundet/app/RSSParserProgram.java
index 7accb81..eaff858 100644
--- a/src/com/studentersamfundet/app/RSSParserProgram.java
+++ b/src/com/studentersamfundet/app/RSSParserProgram.java
@@ -4,7 +4,8 @@ import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
-public class RSSParserProgram {
+public class RSSParserProgram implements IRSSParser {
+ private static final long serialVersionUID = 3364287016121595334L;
private final DataHandler dh;
public RSSParserProgram() {
diff --git a/src/com/studentersamfundet/app/ui/BaseDnsActivity.java b/src/com/studentersamfundet/app/ui/BaseDnsActivity.java
index 2b6ac5a..8dbe4e8 100644
--- a/src/com/studentersamfundet/app/ui/BaseDnsActivity.java
+++ b/src/com/studentersamfundet/app/ui/BaseDnsActivity.java
@@ -1,6 +1,7 @@
package com.studentersamfundet.app.ui;
import com.studentersamfundet.app.R;
+import com.studentersamfundet.app.ui.lists.EventListActivity;
import android.app.Activity;
import android.content.Intent;
@@ -11,30 +12,21 @@ public abstract class BaseDnsActivity extends Activity {
protected Handler handler = new Handler();
public void clickHandler(View v) {
- Intent intent = new Intent();
+ Intent intent = null;
/* Program button was pushed: */
if (v.getId() == R.id.main_menu_program) {
- intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT
- | Intent.FLAG_ACTIVITY_SINGLE_TOP);
-
- intent.setClass(this, EventListActivity.class);
+ intent = setupNewIntent(EventListActivity.class);
startActivity(intent);
/* Join button was pushed: */
} else if (v.getId() == R.id.main_menu_join) {
- intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY
- | Intent.FLAG_ACTIVITY_SINGLE_TOP);
-
- intent.setClass(this, JoinUsActivity.class);
+ intent = setupNewIntent(JoinUsActivity.class);
startActivity(intent);
/* The header was pushed: */
} else if (v.getId() == R.id.header) {
- intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
- | Intent.FLAG_ACTIVITY_SINGLE_TOP);
-
- intent.setClass(this, DnsActivity.class);
+ intent = setupNewIntent(DnsActivity.class);
startActivity(intent);
}
}
@@ -42,4 +34,13 @@ public abstract class BaseDnsActivity extends Activity {
public void doNothing(View v) {
/* As promised. */
}
+
+ protected Intent setupNewIntent(Class> cl) {
+ Intent intent = new Intent();
+ intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
+ | Intent.FLAG_ACTIVITY_SINGLE_TOP);
+ intent.setClass(this, cl);
+
+ return intent;
+ }
}
diff --git a/src/com/studentersamfundet/app/ui/DnsActivity.java b/src/com/studentersamfundet/app/ui/DnsActivity.java
index 1c038ce..cd86274 100644
--- a/src/com/studentersamfundet/app/ui/DnsActivity.java
+++ b/src/com/studentersamfundet/app/ui/DnsActivity.java
@@ -10,12 +10,23 @@ import android.view.View.OnTouchListener;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.widget.TextView;
-import android.widget.Toast;
+import com.studentersamfundet.app.FeedFetcher;
import com.studentersamfundet.app.R;
+import com.studentersamfundet.app.RSSParserNews;
+import com.studentersamfundet.app.RSSParserProgram;
+import com.studentersamfundet.app.ui.lists.EventListActivity;
+import com.studentersamfundet.app.ui.lists.EventListTicketsActivity;
+import com.studentersamfundet.app.ui.lists.NewsListActivity;
public class DnsActivity extends BaseDnsActivity {
- String[] openingHoursHouse = {
+ public static final String eventFeedURL = "http://studentersamfundet.no/rss/robert_program_feed.php";
+ public static final String newsFeedURL = "http://studentersamfundet.no/rss/nyheter_feed.php";
+
+ private FeedFetcher eventFeedFetcher;
+ private FeedFetcher newsFeedFetcher;
+
+ private String[] openingHoursHouse = {
"10.00 - 01.00",
"10.00 - 01.00",
"10.00 - 01.00",
@@ -24,7 +35,7 @@ public class DnsActivity extends BaseDnsActivity {
"12.00 - 03.00",
"12.00 - 20.00"};
- String[] openingHoursGB = {
+ private String[] openingHoursGB = {
"13.00 - 01.00",
"13.00 - 01.00",
"13.00 - 01.00",
@@ -33,7 +44,7 @@ public class DnsActivity extends BaseDnsActivity {
"16.00 - 03.00",
"Stengt"};
- String[] openingHoursBC = {
+ private String[] openingHoursBC = {
"19.00 - 00.00",
"19.00 - 00.00",
"19.00 - 00.00",
@@ -48,6 +59,10 @@ public class DnsActivity extends BaseDnsActivity {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
+ /* Initialize necessary variables: */
+ eventFeedFetcher = new FeedFetcher(eventFeedURL, "local_events");
+ newsFeedFetcher = new FeedFetcher(newsFeedURL, "local_news");
+
/* Set opening hours: */
TextView tvNeuf = (TextView)findViewById(R.id.main_menu_hours_neuf);
TextView tvBC = (TextView)findViewById(R.id.main_menu_hours_bc);
@@ -138,36 +153,28 @@ public class DnsActivity extends BaseDnsActivity {
}
public void programButton(View v) {
- Intent intent = new Intent();
-
- intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT
- | Intent.FLAG_ACTIVITY_SINGLE_TOP);
- intent.setClass(this, EventListActivity.class);
-
+ Intent intent = setupNewIntent(EventListActivity.class);
+ intent.putExtra("feed", eventFeedFetcher);
+ intent.putExtra("parser", new RSSParserProgram());
startActivity(intent);
}
public void ticketButton(View v) {
- Intent intent = new Intent();
-
- intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT
- | Intent.FLAG_ACTIVITY_SINGLE_TOP);
- intent.setClass(this, EventListTicketsActivity.class);
-
+ Intent intent = setupNewIntent(EventListTicketsActivity.class);
+ intent.putExtra("feed", eventFeedFetcher);
+ intent.putExtra("parser", new RSSParserProgram());
startActivity(intent);
}
public void newsButton(View v) {
- Toast.makeText(this, "Not implemented (yet!)", Toast.LENGTH_SHORT).show();
+ Intent intent = setupNewIntent(NewsListActivity.class);
+ intent.putExtra("feed", newsFeedFetcher);
+ intent.putExtra("parser", new RSSParserNews());
+ startActivity(intent);
}
public void joinButton(View v) {
- Intent intent = new Intent();
-
- intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
- intent.setClass(this, JoinUsActivity.class);
-
+ Intent intent = setupNewIntent(JoinUsActivity.class);
startActivity(intent);
-
}
}
\ No newline at end of file
diff --git a/src/com/studentersamfundet/app/ui/EventListTicketsActivity.java b/src/com/studentersamfundet/app/ui/EventListTicketsActivity.java
deleted file mode 100644
index fd8f268..0000000
--- a/src/com/studentersamfundet/app/ui/EventListTicketsActivity.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package com.studentersamfundet.app.ui;
-
-import android.content.Intent;
-import android.net.Uri;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.View.OnLongClickListener;
-
-import com.studentersamfundet.app.Event;
-
-public class EventListTicketsActivity extends EventListActivity {
-
- class TicketListCreator extends ListCreator {
- public TicketListCreator(String category, boolean forcedUpdate) {
- super(category, forcedUpdate);
- }
-
- @Override
- protected Event[] getEvents() {
- return dataHandler.getEventsWithTickets();
- }
- }
-
- @Override
- protected ListCreator getListCreator(String category, boolean forcedUpdate) {
- return new TicketListCreator(category, forcedUpdate);
- }
-
- protected OnClickListener getShortClickListener (final Event e) {
- return new OnClickListener() {
- public void onClick(View v) {
- Uri webDestination = e.getTicketUri();
-
- Intent webIntent = new Intent(Intent.ACTION_VIEW, webDestination);
- startActivity(webIntent);
-
- }
- };
- }
-
- protected OnLongClickListener getLongClickListener (final Event e) {
- return new OnLongClickListener() {
- public boolean onLongClick(View v) {
- return false;
- }
- };
- }
-}
diff --git a/src/com/studentersamfundet/app/ui/NewsViewActivity.java b/src/com/studentersamfundet/app/ui/NewsViewActivity.java
new file mode 100644
index 0000000..9e5a474
--- /dev/null
+++ b/src/com/studentersamfundet/app/ui/NewsViewActivity.java
@@ -0,0 +1,53 @@
+package com.studentersamfundet.app.ui;
+
+import java.text.SimpleDateFormat;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.text.Html;
+import android.text.util.Linkify;
+import android.widget.TextView;
+import com.studentersamfundet.app.News;
+import com.studentersamfundet.app.R;
+
+public class NewsViewActivity extends BaseDnsActivity {
+ News article;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.news_view);
+
+ Intent intent = getIntent();
+ this.article = (News)intent.getSerializableExtra("news");
+ final News a = this.article;
+
+ if (a == null) {
+ throw new Error("This should NEVER happen");
+ }
+
+ TextView title = (TextView) findViewById(R.id.news_view_title);
+ TextView description = (TextView) findViewById(R.id.news_view_description);
+ TextView datetime = (TextView) findViewById(R.id.news_view_datetime);
+
+ title.setText(Html.fromHtml(a.getTitle()));
+
+ SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
+ datetime.setText(a.getPubDate() != null ? dateFormat.format(a.getPubDate()) : "");
+
+ StringBuilder sb = new StringBuilder();
+
+ if (a.getDescription().length() > 0) {
+ sb.append("");
+ sb.append(a.getDescription());
+ sb.append("
");
+ }
+
+ if (a.getContent().length() > 0) {
+ sb.append(a.getContent());
+ }
+
+ description.setText(Html.fromHtml(sb.toString()));
+ Linkify.addLinks(description, Linkify.ALL);
+ }
+}
diff --git a/src/com/studentersamfundet/app/ui/lists/BaseListActivity.java b/src/com/studentersamfundet/app/ui/lists/BaseListActivity.java
new file mode 100644
index 0000000..7c6824f
--- /dev/null
+++ b/src/com/studentersamfundet/app/ui/lists/BaseListActivity.java
@@ -0,0 +1,149 @@
+package com.studentersamfundet.app.ui.lists;
+
+import java.io.IOException;
+
+import org.w3c.dom.NodeList;
+
+import com.studentersamfundet.app.DataHandler;
+import com.studentersamfundet.app.Event;
+import com.studentersamfundet.app.FeedFetcher;
+import com.studentersamfundet.app.IRSSParser;
+import com.studentersamfundet.app.R;
+import com.studentersamfundet.app.ui.BaseDnsActivity;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.widget.ListAdapter;
+import android.widget.ListView;
+import android.widget.ProgressBar;
+import android.widget.Toast;
+
+public abstract class BaseListActivity extends BaseDnsActivity {
+ private DataHandler datahandler;
+ private FeedFetcher feed;
+ private IRSSParser parser;
+
+ private boolean isUpdated = false;
+
+
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ /* Fetch the feed fetcher: */
+ Intent i = getIntent();
+ this.feed = (FeedFetcher)i.getExtras().get("feed");
+ if (this.feed == null)
+ throw new RuntimeException("This activity must be fed a feed feeder.");
+
+ /* Create the parser: */
+ this.parser = (IRSSParser)i.getExtras().get("parser");
+ if (this.parser == null)
+ throw new RuntimeException("This activity requires feed parser");
+
+ /* DataHandler will be set later. */
+ }
+
+ protected final DataHandler getDataHandler() {
+ if (!isUpdated && datahandler == null)
+ throw new RuntimeException("You have to create and run list creator first!");
+
+ return this.datahandler;
+ }
+
+ /**
+ * Creates list adapter used by listview.
+ * @param objects
+ * @return
+ */
+ protected abstract ListAdapter createAdapter(T[] objects);
+
+ protected abstract class ListCreator extends AsyncTask {
+ private String category = Event.ALL;
+ private boolean forcedUpdate = false;
+
+ private final Context context;
+ private final int idList;
+ private final int idProgressBar;
+
+ public ListCreator(Context context, int idList, int idProgressBar) {
+ this.context = context;
+ this.idList = idList;
+ this.idProgressBar = idProgressBar;
+ }
+
+ protected String getCategory() {
+ return this.category;
+ }
+
+ protected void setCategory(String category) {
+ this.category = category;
+ }
+
+ protected boolean getForcedUpdate() {
+ return this.forcedUpdate;
+ }
+
+ protected void setForcedUpdate(boolean forcedUpdate) {
+ this.forcedUpdate = forcedUpdate;
+ }
+
+ @Override
+ protected void onPreExecute() {
+ if (forcedUpdate) {
+ datahandler = null;
+ }
+
+ ListView list = (ListView)findViewById(idList);
+ list.setVisibility(View.GONE);
+
+ ProgressBar pb = (ProgressBar)findViewById(idProgressBar);
+ if (pb != null)
+ pb.setVisibility(View.VISIBLE);
+ }
+
+ @Override
+ protected Boolean doInBackground(Void ... v) {
+ // Do we have intarwebs?
+ // YAY = Fetch the feed.
+ // NAY = Inform about no connection.
+ try {
+ if (datahandler == null) {
+ NodeList itemNodes = feed.fetch(BaseListActivity.this, this.forcedUpdate);
+ datahandler = parser.parse(itemNodes);
+ }
+ return true;
+
+ } catch (IOException e) {
+ return false;
+ }
+ }
+
+ @Override
+ protected void onPostExecute(Boolean result) {
+ isUpdated = true;
+
+ if (result) {
+ ListView list = (ListView)findViewById(idList);
+ T[] objects = getObjects();
+
+ Log.i("DNSapp", "Showing " +objects.length +" objects.");
+ ListAdapter adapter = createAdapter(objects);
+ list.setAdapter(adapter);
+ list.setVisibility(View.VISIBLE);
+
+ ProgressBar pb = (ProgressBar)findViewById(idProgressBar);
+ if (pb != null)
+ pb.setVisibility(View.GONE);
+ } else {
+ Toast toast = Toast.makeText(context, R.string.error_noconnection_noupdate, Toast.LENGTH_LONG);
+ toast.show();
+ }
+ }
+
+ abstract protected T[] getObjects();
+ }
+}
diff --git a/src/com/studentersamfundet/app/ui/EventListActivity.java b/src/com/studentersamfundet/app/ui/lists/EventListActivity.java
similarity index 57%
rename from src/com/studentersamfundet/app/ui/EventListActivity.java
rename to src/com/studentersamfundet/app/ui/lists/EventListActivity.java
index 860a618..cafc7bb 100644
--- a/src/com/studentersamfundet/app/ui/EventListActivity.java
+++ b/src/com/studentersamfundet/app/ui/lists/EventListActivity.java
@@ -1,13 +1,10 @@
-package com.studentersamfundet.app.ui;
+package com.studentersamfundet.app.ui.lists;
-import java.io.IOException;
import java.text.SimpleDateFormat;
-import org.w3c.dom.NodeList;
-
import android.app.Dialog;
+import android.content.Context;
import android.content.Intent;
-import android.os.AsyncTask;
import android.os.Bundle;
import android.text.Html;
import android.view.LayoutInflater;
@@ -15,31 +12,23 @@ import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
-import android.view.View.OnClickListener;
import android.view.ViewGroup;
+import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
-import android.widget.ListView;
-import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
-import com.studentersamfundet.app.DataHandler;
import com.studentersamfundet.app.Event;
-import com.studentersamfundet.app.FeedFetcher;
import com.studentersamfundet.app.R;
-import com.studentersamfundet.app.RSSParserProgram;
import com.studentersamfundet.app.network.ImageLoader;
+import com.studentersamfundet.app.ui.ChooseCategoryDialog;
+import com.studentersamfundet.app.ui.EventViewActivity;
import com.studentersamfundet.app.ui.ChooseCategoryDialog.Callback;
-public class EventListActivity extends BaseDnsActivity {
- public static final String feedURL = "http://studentersamfundet.no/rss/lars_program_feed.php";
+public class EventListActivity extends BaseListActivity {
public static final int imageSize = 80;
- protected FeedFetcher feed;
- protected RSSParserProgram parser;
- protected DataHandler dataHandler;
-
private String currentCategory = Event.ALL;
@Override
@@ -47,10 +36,7 @@ public class EventListActivity extends BaseDnsActivity {
super.onCreate(savedInstanceState);
setContentView(R.layout.event_list);
- this.feed = new FeedFetcher(this, feedURL);
- this.parser = new RSSParserProgram();
-
- ListCreator lc = getListCreator(Event.ALL, false);
+ ListCreator> lc = getListCreator(this, R.id.event_list, R.id.event_list_progress_bar);
lc.execute();
}
@@ -66,7 +52,8 @@ public class EventListActivity extends BaseDnsActivity {
switch (item.getItemId()) {
case R.id.menu_refresh:
- ListCreator lc = getListCreator(Event.ALL, true);
+ ListCreator> lc = getListCreator(this, R.id.event_list, R.id.event_list_progress_bar);
+ lc.setForcedUpdate(true);
lc.execute();
return true;
@@ -84,13 +71,13 @@ public class EventListActivity extends BaseDnsActivity {
if (currentCategory.equals(Event.ALL)) {
super.onBackPressed();
} else {
- ListCreator lc = getListCreator(Event.ALL, false);
+ ListCreator> lc = getListCreator(this, R.id.event_list, R.id.event_list_progress_bar);
lc.execute();
}
}
-
-
- protected ListAdapter createAdapter(Event[] events) {
+
+ protected ListAdapter createAdapter(T[] objects) {
+ Event[] events = (Event[])objects;
ListAdapter adapter = new ArrayAdapter(this, R.layout.event_list_row, R.id.event_list_row_text, events) {
@Override
@@ -149,84 +136,30 @@ public class EventListActivity extends BaseDnsActivity {
if (message.length < 1)
message = new String[] { Event.ALL };
- ListCreator lc = getListCreator(message[0], false);
+ ListCreator> lc = getListCreator(EventListActivity.this, R.id.event_list, R.id.event_list_progress_bar);
+ lc.setCategory(message[0]);
lc.execute();
}
};
- if (dataHandler != null) {
- Dialog dialog = new ChooseCategoryDialog(this, callback, dataHandler.getEventCategories());
+ if (getDataHandler() != null) {
+ Dialog dialog = new ChooseCategoryDialog(this, callback, getDataHandler().getEventCategories());
dialog.show();
} else {
Toast.makeText(this, R.string.error_loading, Toast.LENGTH_SHORT);
}
}
- protected class ListCreator extends AsyncTask {
- protected String category;
- protected boolean forcedUpdate;
-
- public ListCreator(String category, boolean forcedUpdate) {
- this.category = category;
- this.forcedUpdate = forcedUpdate;
- }
-
- @Override
- protected void onPreExecute() {
- if (forcedUpdate) {
- dataHandler = null;
- }
-
- ListView list = (ListView)findViewById(R.id.event_list);
- list.setVisibility(View.GONE);
-
- ProgressBar pb = (ProgressBar)findViewById(R.id.event_list_progress_bar);
- pb.setVisibility(View.VISIBLE);
- }
-
- @Override
- protected Boolean doInBackground(Void ... v) {
- // Do we have intarwebs?
- // YAY = Fetch the feed.
- // NAY = Inform about no connection.
- try {
- if (dataHandler == null) {
- NodeList itemNodes = feed.fetch(this.forcedUpdate);
- dataHandler = parser.parse(itemNodes);
- }
- return true;
-
- } catch (IOException e) {
- return false;
- }
- }
-
- @Override
- protected void onPostExecute(Boolean result) {
- if (result) {
- ListView list = (ListView)findViewById(R.id.event_list);
- Event[] events = getEvents();
- ListAdapter adapter = createAdapter(events);
- list.setAdapter(adapter);
- list.setVisibility(View.VISIBLE);
-
- ProgressBar pb = (ProgressBar)findViewById(R.id.event_list_progress_bar);
- pb.setVisibility(View.GONE);
-
- currentCategory = category;
- } else {
- Toast toast = Toast.makeText(EventListActivity.this, R.string.error_noconnection_noupdate, Toast.LENGTH_LONG);
- toast.show();
- }
- }
-
- protected Event[] getEvents() {
- return dataHandler.getEvents(this.category);
- }
- }
+
- protected ListCreator getListCreator(String category, boolean forcedUpdate) {
- return new ListCreator(category, forcedUpdate);
+ protected ListCreator getListCreator(Context context, int idList, int idProgressBar) {
+ return new ListCreator(context, idList, idProgressBar) {
+
+ @Override
+ protected Event[] getObjects() {
+ return getDataHandler().getEvents(Event.ALL);
+ }
+ };
}
protected OnClickListener getShortClickListener (final Event e) {
diff --git a/src/com/studentersamfundet/app/ui/lists/EventListTicketsActivity.java b/src/com/studentersamfundet/app/ui/lists/EventListTicketsActivity.java
new file mode 100644
index 0000000..51d1fc1
--- /dev/null
+++ b/src/com/studentersamfundet/app/ui/lists/EventListTicketsActivity.java
@@ -0,0 +1,34 @@
+package com.studentersamfundet.app.ui.lists;
+
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.view.View;
+import android.view.View.OnClickListener;
+
+import com.studentersamfundet.app.Event;
+
+public class EventListTicketsActivity extends EventListActivity {
+ @Override
+ protected ListCreator getListCreator(Context context, int idList, int idProgressBar) {
+ return new ListCreator(context, idList, idProgressBar) {
+ @Override
+ protected Event[] getObjects() {
+ return getDataHandler().getEventsWithTickets();
+ }
+ };
+ }
+
+ @Override
+ protected OnClickListener getShortClickListener (final Event e) {
+ return new OnClickListener() {
+ public void onClick(View v) {
+ Uri webDestination = e.getTicketUri();
+
+ Intent webIntent = new Intent(Intent.ACTION_VIEW, webDestination);
+ startActivity(webIntent);
+
+ }
+ };
+ }
+}
diff --git a/src/com/studentersamfundet/app/ui/lists/NewsListActivity.java b/src/com/studentersamfundet/app/ui/lists/NewsListActivity.java
new file mode 100644
index 0000000..79bfbd1
--- /dev/null
+++ b/src/com/studentersamfundet/app/ui/lists/NewsListActivity.java
@@ -0,0 +1,78 @@
+package com.studentersamfundet.app.ui.lists;
+
+import java.text.SimpleDateFormat;
+
+import com.studentersamfundet.app.News;
+import com.studentersamfundet.app.R;
+import com.studentersamfundet.app.ui.NewsViewActivity;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ListAdapter;
+import android.widget.TextView;
+
+public class NewsListActivity extends BaseListActivity {
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.event_list);
+
+ ListCreator> lc = new ListCreator(this, R.id.event_list, R.id.event_list_progress_bar) {
+
+ @Override
+ protected News[] getObjects() {
+ return getDataHandler().getNews();
+ }
+ };
+ lc.execute();
+ }
+
+
+ @Override
+ protected ListAdapter createAdapter(T[] objects) {
+ final News[] news = (News[])objects;
+ ListAdapter adapter = new ArrayAdapter(this, R.layout.news_list_row, R.id.news_list_row_desc, news) {
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ ViewGroup row;
+
+ if (null == convertView) {
+ LayoutInflater inflater = getLayoutInflater();
+ row = (ViewGroup)inflater.inflate(R.layout.news_list_row, null);
+ } else {
+ row = (ViewGroup)convertView;
+ }
+
+ final News article = news[position];
+
+ TextView title = (TextView)row.findViewById(R.id.news_list_row_title);
+ TextView description = (TextView)row.findViewById(R.id.news_list_row_desc);
+ TextView footer = (TextView)row.findViewById(R.id.news_list_row_byline);
+
+ title.setText(article.getTitle());
+ description.setText(article.getDescription());
+
+ SimpleDateFormat sdf = new SimpleDateFormat("HH:mm, d. MMMM y");
+ footer.setText(sdf.format(article.getPubDate()));
+
+ row.setOnClickListener(new OnClickListener() {
+ public void onClick(View v) {
+ Intent intent = new Intent(NewsListActivity.this, NewsViewActivity.class);
+ intent.putExtra("news", article);
+
+ startActivity(intent);
+ }
+ });
+
+ return row;
+ }
+ };
+
+ return adapter;
+ }
+}