Das Einsteigertutorial: Android-Apps selbstgemacht

Layout

Layouts bestehen aus einer Hierarchie von Objekten, die jeweils von den Klassen View bzw. ViewGroup erben. Diese Hierarchien können sowohl programmatisch als auch über XML-Dateien erzeugt werden. Jeder Knoten darin entspricht einer Klasse in Android, für die bei Erzeugung des Layouts ein zugehöriges Objekt erstellt wird. Das Layout für unsere TwitterActivity findet sich in Listing 1.

Listing 1

Wir speichern das Layout im res/layout-Verzeichnis unter dem Namen twitter.xml ab. Insgesamt besteht dieses aus den folgenden drei Objekten:

  • Einem LinearLayout. Mittels LinearLayout können Elemente wahlweise unter- oder nebeneinander angeordnet werden. Zusätzlich lässt sich über das layout_weight-Attribut bestimmen, wie der verfügbare Platz auf die einzelnen Elemente aufgeteilt werden soll. Im aktuellen Beispiel behält der Button seine ursprüngliche Größe, während sich ListView auf die verbleibende Größe ausbreitet. Eine kleine Übersicht der verfügbaren Layout-Klassen findet sich unter [4].
  • Einer ListView. Diese wird später eine Liste all unserer Tweets anzeigen. Die Information, welche Tweets vorhanden sind und wie diese im Einzelnen darzustellen sind, werden wir ihr später über den TweetAdapter zuführen.
  • Einem beschrifteten Button. Anstelle des eigentlichen Textes enthält der Button einen Verweis auf eine Text-Ressource. Derartige Verweise werden Android durch ein führendes @-Zeichen gekennzeichnet, gefolgt vom Typ der Ressource (beispielsweise string, id oder drawable) und einem eindeutigen Bezeichner. Den zugehörigen Text können wir in res/values/strings.xml als string-Knoten hinterlegen, der als name-Attribut „update_button“ und als Inhalt „Update“ enthält.

Beide Elemente enthalten zusätzlich ein ID-Attribut. Über diese IDs können wir die Elemente später in unserer Activity ansprechen. Das Plus-Symbol soll hierbei andeuten, dass wir an dieser Stelle eine neue ID definieren. Zusätzlich verfügen alle Elemente über ein Paar von layout_width- und layout_height-Attributen. Diese geben an, wie breit und hoch das Element in unserem Layout sein soll. Die Werte match_parent bzw. in älteren Versionen fill_parent bewirken, dass Elemente die gleiche Größe wie ihr Elternelement bzw. wie der Bildschirm annehmen. Mittels wrap_content dagegen werden Element gerade so groß, um den eigenen Inhalt darstellen zu können. Zusätzlich kann man eine feste Größe in Form von sogenannten Density Independent Pixels (dp oder dip) angeben. Diese bewirken, dass Elemente auf allen Geräten ungeachtet ihrer Pixeldichte die gleiche physische Größe einnehmen. Mehr Informationen zu Bildschirmunabhängigkeit finden sich unter [5].

Tweet-Klasse

Die in Listing 2 dargestellte Tweet-Klasse ist vergleichsweise simpel. Sie enthält eine kleine Auswahl von Properties, die wir benötigen, um einen einzelnen Tweet darstellen zu können. Der Konstruktor der Klasse erwartet ein Objekt vom Typ JSONObject, welches die JSON-Daten enthält, die wir von dem Twitter-API bekommen. Bei JSON handelt es sich um ein hierarchisches Textformat ähnlich wie XML, welches über eine Android beiliegende JSON-Bibliothek ausgelesen werden kann.

Der komplette Stream lässt sich unter folgender URL im Browser einsehen:

http://api.twitter.com/1/statuses/user_timeline.json?screen_name=InsertE…

Listing 2
public class Tweet {
    private long id;
    private String text;
    private String userName;
    private String source;
    
    public Tweet(JSONObject object) throws JSONException {
        id = object.getLong("id");
        text = object.getString("text");
        source = object.getString("source");
        userName = object.getJSONObject("user").getString("name");
    }
    public long getId() {
        return id;
    }
    public String getText() {
        return text;
    }
    public String getUserName() {
        return userName;
    }
    public String getSource() {
        return source;
    }
}
TweetAdapter

Die TweetAdapter-Klasse implementiert das ListAdapter-Interface. Damit kann die TweetAdapter-Klasse einer ListView als Datenquelle zur Verfügung gestellt werden. Dazu müssen eine Reihe von Methoden implementiert werden, die beispielsweise angeben, wie viele Einträge der Adapter enthält, oder die einen einzelnen Eintrag für eine bestimmte Position zurück geben. Der Quellcode der Klasse ist in Listing 3 dargestellt. Intern arbeitet der Adapter mit einer Liste von Tweet-Objekten, die ihm im Konstruktor übergeben wird. Am wichtigsten ist die getView()-Methode. In ihr erzeugen wir eine View für einen einzelnen Tweet, über die der Tweet dargestellt werden kann. Dazu erstellen wir einfach ein TextView-Objekt und übergeben diesem einen String, der alle benötigten Tweet-Informationen enthält. Aus Performance-Gründen bekommen wir im convertView-Parameter manchmal eine alte, nicht mehr benötigte TextView übergeben, die wir für unsere Zwecke wiederverwenden können. Wenn nicht, erzeugen wir einfach eine neue.

Listing 3
public class TweetAdapter extends BaseAdapter {
    private final List tweets;
    private final Context context;
    
    public TweetAdapter(Context context, List tweets) {
        this.tweets = tweets;
        this.context = context;
    }
    public int getCount() {
        return tweets.size();
    }
    public Object getItem(int position) {
        return tweets.get(position);
    }
    public long getItemId(int position) {
        return tweets.get(position).getId();
    }
    public View getView(int position, View convertView, ViewGroup parent) {
        Tweet tweet = tweets.get(position);		
        TextView textView;
        if(convertView == null) {
            textView = new TextView(context);
            textView.setPadding(10, 10, 10, 10);
        } else
            textView = (TextView) convertView;
        
        textView.setText(tweet.getText());
        return textView;
    }
}
Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.