StaticFloat

Raspberry Pi über SSH mit dem Smartphone steuern

Wir haben bereits unsere Hauptfunktion geschrieben und eine Datenbank im Hintergrund besitzen wir ebenfalls.

Zeit sich um das Aussehen der App zu kümmern.
Auf dieser Seite werden wir uns mit der Startseite unserer App beschäftigen.
Wir werden alles Nötige vorbereiten und Programmieren, damit wir eine Liste von gespeicherten Befehlen angezeigt bekommen.

 

Design:

Bevor wir beginnen können eine Funktion zu schreiben, welche es es uns erlaubt alle gespeicherten Befehle anzuzeigen, ist es von Nöten ein Design zu erstellen, welches alle Befehle anzeigen kann. Klingt logisch. Erst einmal benötigen wir also eine Liste, im Anschluss können wir beginnen diese Liste zu füllen.

Wir öffnen die Datei „MainActivity.xml“ und ersetzen die TextView „Hello World!“ durch eine ListView mit der ID „befehlsliste“:

<?xml version="1.0" encoding="utf-8"?>

<!--
  ~ Copyright 2017 www.staticfloat.de
  ~
  ~ Licensed under the Apache License, Version 2.0 (the „License“);
  ~ you may not use this file except in compliance with the License.
  ~ You may obtain a copy of the License at
  ~
  ~ http://www.apache.org/licenses/LICENSE-2.0
  ~
  ~ Unless required by applicable law or agreed to in writing, software
  ~ distributed under the License is distributed on an „AS IS“ BASIS,
  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  ~ See the License for the specific language governing permissions and
  ~ limitations under the License.
  -->

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="de.staticfloat.quickssh.MainActivity">

    <ListView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/befehlsliste" />
</RelativeLayout>

Anschließend gilt es ein Design für jeden einzelnen Eintrag zu gestalten.
Jeder Eintrag soll einen Namen tragen und einen Knopf, zum Ausführen des Befehls, zeigen.

Wir erstellen eine neue Datei in res -> layout und nennen sie „befehlsliste_eintrag.xml“.
Der Inhalt sähe so oder so ähnlich aus. Euch ist hier jegliche Freiheit gegeben:

<?xml version="1.0" encoding="utf-8"?>
<!--
  ~ Copyright 2017 www.staticfloat.de
  ~
  ~ Licensed under the Apache License, Version 2.0 (the „License“);
  ~ you may not use this file except in compliance with the License.
  ~ You may obtain a copy of the License at
  ~
  ~ http://www.apache.org/licenses/LICENSE-2.0
  ~
  ~ Unless required by applicable law or agreed to in writing, software
  ~ distributed under the License is distributed on an „AS IS“ BASIS,
  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  ~ See the License for the specific language governing permissions and
  ~ limitations under the License.
  -->

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:text="Titel des Befehls"
        android:id="@+id/befehlsTitel" />

    <Button
        style="?android:attr/buttonStyleSmall"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Befehl ausführen"
        android:id="@+id/befehlsButton" />
</LinearLayout>

 

Liste füllen:

Nun haben wir bereits ein Design erstellt.
Befüllen wir es mit Inhalt!

Zum Füllen der eben erstellten Liste (ListeView) benötigen wir 3 Dinge:

  • Einen Adapter, der die Anzeige der einzelnen Einträge übernimmt.
  • Daten, die wir in die Liste „stopfen“ wollen.
  • Eine Funktion, die den Adapter auf das erstellte ListView aufschaltet und die Daten an den Adapter übergibt.

Das klingt im ersten Moment vielleicht etwas konfus. Ich versuche im weiteren Verlauf des Artikels aber Klarheit zu schaffen.

Nun denn, auf gehts mit dem Adapter!
Hier kann ich eigentlich relativ wenig zu erzählen.
Die Grundform des Adapters immer ähnlich aussieht.

Wir erstellen uns eine Klasse „BefehlsAdapter“:

public class BefehlsAdapter extends BaseAdapter {

    private ArrayList<Befehl> befehle;

    public BefehlsAdapter(Context c, ArrayList<Befehl> befehle){
        // Die Liste der übergebenen Befehle in einer Variable speichern
        this.befehle = befehle;
        
        // Hier werden Berechnungen durchgeführt und Variablen vorbereitet, die nur beim Setzen des Adapters von Nöten sind.
    }

    @Override
    public int getCount() {
        return befehle.size();
    }

    @Override
    public Object getItem(int arg0) {
        return null;
    }

    @Override
    public long getItemId(int arg0) {
        return arg0;
    }

    @Override
    public View getView(int arg0, View arg1, ViewGroup arg2) {
        // Hier behandeln wir die Anzeige der einzelnen Einträge.
    }

}

 

Und schon steht unser Grundgerüst für den Adapter.
Erfüllen wir die Klasse mit Leben!

Unter „private ArrayList<Befehl> befehle;“ fügen wir ein paar benötigte Variablen ein. Sie sollen uns später die Arbeit erleichtern, nach den Verbindungsdaten des Raspberry Pi zu suchen.

private LayoutInflater eintragInflater;
private String nutzername;
private String passwort;
private String ip;
private int port;
private SharedPreferences pref;
private Context cxt;

 

Anschließend befüllen wir die variablen mit ihrem benötigten Inhalt. Wir fügen an die Stelle „// Hier werden Berechnungen durchgeführt und Variablen vorbereitet, die nur beim Setzen des Adapters von Nöten sind.“ ein:

// Bekomme das ListView übergeben, in dass die Einträge geschreiben werden sollen
eintragInflater = LayoutInflater.from(c);

// Den Context benötigen wir für diverse Funktionsaufrufe.
cxt = c;

//shared data vorbereiten
pref = c.getSharedPreferences("QuickSSH", 0);

//Verbindungsdaten laden
nutzername = pref.getString("nutzername", "");
passwort = pref.getString("passwort", "");
ip = pref.getString("ip", "");
port = pref.getInt("port", 22);

 

Alles ist vorbereitet, um die Klasse „BefehlsAdapter“ die Befehle anzeigen zu lassen.
Wir ersetzen „// Hier behandeln wir die Anzeige der einzelnen Einträge.“ durch:

// Lese das richtige Design der ListeView Einträge aus.
LinearLayout befehlsLayout = (LinearLayout) eintragInflater.inflate(R.layout.befehlsliste_eintrag, arg2, false);

// Lese die zu verändernden Elemente eines Eintrages aus.
TextView befehlsTitel   = (TextView) befehlsLayout.findViewById(R.id.befehlsTitel);
TextView befehlsButton  = (Button) befehlsLayout.findViewById(R.id.befehlsButton);

// Lese den Befehl an der Stelle "arg0" aus.
final Befehl momentanerBefehl = befehle.get(arg0);

// Beschreibe das Element des Titels mit dem Titel des momentanen Befehls.
befehlsTitel.setText(momentanerBefehl.titel);

// Reagiere auf einen Klick und führe unsere hauptfunktion aus, welche in der Klasse "MainActivity" steht.
befehlsButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        if(!nutzername.equals("") && !passwort.equals("") && !ip.equals(""))
            MainActivity.executeBefehl(nutzername, passwort, ip, port, momentanerBefehl.befehl);
        else
            Toast.makeText(cxt, "Es wurden keine Verbindungsdaten angegeben.", Toast.LENGTH_SHORT).show();
    }
});

// Vollende die Anzeige
befehlsLayout.setTag(arg0);
return befehlsLayout;

 

Supi, fast haben wir es geschafft.
Unser Adapter ist vollendet und auf unsere Datenbank sollten wir uns auch verlassen können. Nun wechseln wir zurück ind die Klasse „MainActivity“ und füge die Funktion hinzu, welche es uns erlaubt den Adapter einer ListView zuzuordnen und den Adapter mit den Daten der Datenbank füttert.

Wir schreiben in die Funktion „onCreate“:

// Datenbank initialisieren.
DB_Befehle DB_b = new DB_Befehle(this);

// Alle Befehle aus der Datenbak auslesen und in eine Variable schreiben.
ArrayList<Befehl> befehlsListe = DB_b.getAlle();

// Adapter mit allen gefundenen Befehlen der Datenbank füttern.
BefehlsAdapter befehlsAdapter = new BefehlsAdapter(this, befehlsListe);

// Adapter auf das ListView aufschalten.
ListView liedListView = (ListView)findViewById(R.id.befehlsliste);
liedListView.setAdapter(befehlsAdapter);

Melvin

Ich bin 23 Jahre jung und studiere zurzeit Wirtschaftsinformatik an der Georg-August-Universität in Göttingen. Ich bin ein Mensch, der sich neben der Programmierung noch für tausend andere Dinge interessiert, die mal mehr und mal weniger verrückt sind. Vor allem aber bin ich Feuer und Flamme mit der Programmierung von eigenen kleinen Apps und Programmen, die mein Leben bereichern.

Schreibe den ersten Kommentar

*Pflichtfeld

3D Drucker – Die häufigsten Probleme

Du hast Probleme mit deinem Drucker?
Vielleicht hilft dir diese Seite, mit Problemen und Lösungen zum Druck von Modellen.

Auf geht's!