Po dłuższym utęsknieniu i znalezieniu czasu pomiędzy pracą inżynierską, graniem a przeklinaniem na notebook, znalazłem czas oraz chęci na kontynuowanie kursu programowania na platformę Android. Tym razem obiektem mojego kursu zostały listy oraz wg sondaży czytnik rss (przykro mi, bazy będą w innej części).
Jako, że lotto nie ma oficjalnego czytnika rss , użyję rss z mojego serwisu. (https://szymonmotyka.pl/feed/)
Zacznijmy więc od stworzenia layoutu dla naszego czytnika ( oczywiście, layout będzie fragmentem poprzednio stworzonego layoutu:
< ?xml version="1.0" encoding="utf-8"?> <linearlayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <textview android:id="@+id/TextView08" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#0C5687" android:text="@string/rss" android:textAppearance="?android:attr/textAppearanceLarge" android:textColor="#FFD11C" android:textStyle="bold"></textview> <listview android:id="@id/android:list" android:layout_width="match_parent" android:layout_height="match_parent" > </listview> </linearlayout>
Jest to prosty layout z listview z nagłówkiem znanym z innych fragmentów. Urodziwe to nie jest, ale działa. Reszta zależy od was czytelnicy
Kolejnym krokiem jest też dodanie layoutu dla wierszy naszej linii, by adapter wiedział, co gdzie umieścić.
< ?xml version="1.0" encoding="utf-8"?> <linearlayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <textview android:id="@+id/title" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Large Text" android:textAppearance="?android:attr/textAppearanceLarge"></textview> <textview android:id="@+id/content" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Medium Text" android:textAppearance="?android:attr/textAppearanceMedium"></textview> <textview android:id="@+id/date" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Small Text" android:textAppearance="?android:attr/textAppearanceSmall"></textview> </linearlayout>
Kolejnym krokiem jest utworzenie nowego fragmentu, tym razem dziedziczącego po listfragment
public class RSS extends ListFragment {
ArrayList<rssmodel> rsslist=new ArrayList</rssmodel><rssmodel>();
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View mainView = inflater.inflate(R.layout.rsslayout, container, false);
//Tworzenie przykładowej arraylisty, którą potem uzupełnimy wpisami z rss
rsslist.add(new RSSModel("Test", "testskontent", "http://developer.android.com/reference/android/app/ListFragment.html","10-10-2012"));
<pre>
//Tworzenie obiektu rssAdapter
RSSAdapter rssAdapter=new RSSAdapter(getActivity(), rsslist);
//PRzypisanie jej do listy
setListAdapter(rssAdapter);
return mainView;
}
@Override
public void onListItemClick (ListView l, View v, int position, long id)
{
super.onListItemClick(l, v, position, id);
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(rsslist.get(position).getLink()));
startActivity(intent);
}
}
Jest to prosty fragment dziedziczący po listFragment. Dodatkowo dzięki metodzie onListItemClick można zaimplementować zdarzenie po kliknięciu w element listy.
Dodatkowo do naszej metody trzeba zaimplementować klasy RSSModel
class RSSModel
{
private String Title;
private String Link;
private String Date;
public String getTitle() {
return Title;
}
public void setLink(String string) {
Link=string;
}
public void setDate(String string) {
Date=string;
}
public void setTitle(String string) {
Title=string;
}
public String getLink() {
return Link;
}
public String getDate() {
return Date;
}
public RSSModel() {
}
}
oraz najważniejsze w przypadku listy. czyli adapter:
class RSSAdapter extends ArrayAdapter<rssmodel>{
private final Activity context;
private ArrayList</rssmodel><rssmodel> rssy;
/*
* Konstruktor pobierający listę RSS, ustawiający layout dla linijek naszego rss
*/
public RSSAdapter(Activity context, ArrayList</rssmodel><rssmodel> lista) {
super(context, R.layout.rssrow, lista);
this.context = context;
this.rssy=lista;
}
static class ViewHolder {
public TextView tytul;
public TextView date;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
View rowView = convertView;
if (rowView == null) {
LayoutInflater inflater = context.getLayoutInflater();
rowView = inflater.inflate(R.layout.rssrow, null, true);
holder = new ViewHolder();
holder.tytul= (TextView) rowView.findViewById(R.id.title);
holder.date=(TextView) rowView.findViewById(R.id.date);
rowView.setTag(holder);
} else {
holder = (ViewHolder) rowView.getTag();
}
//Przypisanie elementów z arraylist do wierszy naszej listy
holder.tytul.setText(rssy.get(position).getTitle());
holder.date.setText(rssy.get(position).getDate());
return rowView;
}
}
Takim oto sposobem, nasz fragment powinien wyglądać tak:
Teraz zabierzmy się za nasz prosty czytnik RSS. Ze względów estetycznych. Utworzę do niego osobną metodę, która zwracać będzie ArrayList<RSSModel>. Uwierzcie. Dawanie wszystkich instrukcji do głównej metody utrudnia nam potem wrócenie do tego kodu 😉
I teraz zaczyna się zabawa:
RSS:
private ArrayList</rssmodel><rssmodel> getRSS()
{
String url="https://szymonmotyka.pl/feed/";
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser;
RssParseHandler handler = new RssParseHandler();
try {
saxParser = factory.newSAXParser();
saxParser.parse(url, handler);
} catch (ParserConfigurationException e1) {
e1.printStackTrace();
} catch (SAXException e1) {
e1.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return handler.getItems();
}
Wywołujemy metodę,
rsslist=getRSS();
w onCreateView.
a na końcu dodajemy klasę :
class RssParseHandler extends DefaultHandler {
private ArrayList</rssmodel><rssmodel> rssItems;
private RSSModel currentItem;
private boolean parsingTitle;
private boolean parsingLink;
private boolean parsingDate;
public RssParseHandler() {
rssItems = new ArrayList</rssmodel><rssmodel>();
}
public ArrayList</rssmodel><rssmodel> getItems() {
return rssItems;
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
if ("item".equals(qName)) {
currentItem = new RSSModel();
} else if ("title".equals(qName)) {
parsingTitle = true;
} else if ("link".equals(qName)) {
parsingLink = true;
} else if ("pubDate".equals(qName))
parsingDate=true;
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if ("item".equals(qName)) {
rssItems.add(currentItem);
currentItem = null;
} else if ("title".equals(qName)) {
parsingTitle = false;
} else if ("link".equals(qName)) {
parsingLink = false;
} else if ("pubDate".equals(qName)) {
parsingDate = false;
}
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
if (parsingTitle) {
if (currentItem != null)
currentItem.setTitle(new String(ch, start, length));
} else if (parsingLink) {
if (currentItem != null) {
currentItem.setLink(new String(ch, start, length));
parsingLink = false;
}
} else if (parsingDate) {
if (currentItem != null) {
currentItem.setDate(new String(ch, start, length));
parsingDate = false;
}
}
}
}
za pomocą tej klasy parsujemy nasz xml z RSS, dzięki czemu otrzymujemy ArrayListę z obiektami typu RSSModel potrzebnymi do naszego adaptera. Oczywiście nic nie stoi na przeszkodzie, by pobrać jeszcze obrazki. Ale to juz zależy od was.
Zostało już tylko dodanie fragmentu RSS w MainActivity:
fragments.add(Fragment.instantiate(this, RSS.class.getName()));
Na końcu:
Jeżeli nie dodaliście reklam, pominęliście itp to prawdopodobnie nie dodaliście jeszcze pozwolenia na używanie internetu.
W tym celu wchodzimy do manifestu. Osobiście preferuję edycję xml, więc przechodzimy do zakładki AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="pl.szymonmotyka.tutorialrandomizer" android:versionCode="2" android:versionName="1.1"> <uses -sdk android:minSdkVersion="8"></uses> <uses -permission android:name="android.permission.INTERNET"></uses> <uses -permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses> <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme"> <activity android:name=".MainActivity" android:label="@string/app_name" android:screenOrientation="portrait"> <intent -filter> <action android:name="android.intent.action.MAIN"></action> <category android:name="android.intent.category.LAUNCHER"></category> </intent> </activity> </application> </manifest>
Poza pozwoleniami <uses-permission> dodałem jeszcze atrybut do activitity android:screenOrientation=”portrait”
Źródło: https://dl.dropbox.com/u/14815030/prog6zip.zip
Aplikacja również w markecie: https://play.google.com/store/apps/details?id=pl.szymonmotyka.tutorialrandomizer
Czynik RSS oparty o : http://www.itcuties.com/android/how-to-write-android-rss-parser/ . Lista pokazana na własnym przykładzie
Jeżeli jeszcze was nie zanudziłem, zapraszam do oczekiwania na kolejne części. W planach : SQLite, zewnętrzne biblioteki. Zapraszam również do polubienia i częstego odwiedzania: https://www.facebook.com/SzymonMotykapl

