Smarthome App #4: Menüpunkte auswählen


25.10.2016  |  Tutorial, Smarthome App

Im letzten Teil des Tutorials wurde sich um das Hauptmenü der App gekümmert. Dabei wurde das Hauptmenü erstellt und mit den einzelnen Menüpunkten gefüllt. Klicks auf einzelne Menüpunkte wurden jedoch noch nicht behandelt. Unter anderem darum wird es heute gehen. Außerdem werden noch Ressourcendateien für Ganzzahlen und Animationen angelegt, der Header des NavigationDrawers angepasst, sowie eine neue Methode in der MainActivity implementiert.

Dieses Tutorial gibt es auch als Video

Kleine Ergänzungen in der MainActivity

Als erstes wird in der Methode "onCreate()" der Datei mobile -> java -> de.smarthome_blogger.smarthome -> MainActivity.java der Titel gesetzt, der in der sogenannten ActionBar unter der Benachrichtigungsleiste des Smartphones angezeigt wird. Das machst du mit der folgenden Zeile:
setTitle("Smarthome");
Danach werden der Klasse zwei neue finale statische Variablen hinzugefügt. Dazu fügst du über der Methode "onCreate()", aber unter der Variable "EXTRA_ROOMS" die folgenden zwei Zeilen ein:
final static String EXTRA_TITLE = "EXTRA_TITLE";
final static String EXTRA_LOCATION = "EXTRA_LOCATION";
Zu den Variablen "drawerMenu" und "drawerItemList" unter dem Kommentar "//NavigationDrawer" fügst du außerdem die folgenden 2 neuen Variablen hinzu:
DrawerLayout drawerLayout;
FragmentTransaction fragmentTransaction;

DrawerLayout in "onCreate" verwenden

In der Methode "onCreate" befindet sich der folgende Code:
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
        this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
Dieser wird nun mit diesem leicht abgewandelten Code ersetzt:
drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
        this, drawerLayout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawerLayout.setDrawerListener(toggle);
toggle.syncState();

Die Methode "onNavigationItemSelected" bearbeiten

Als nächstes muss die Methode "onNavigationItemSelected" bearbeitet werden. Dazu werden die folgenden Zeilen entfernt:
// Handle navigaion view clicks here
int post_id = item.getItemId();

DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
Anschließend kommt an die Stelle der eben gelöschten Zeilen der folgende Code:
ArrayList menuItemArray = new ArrayList();
for(int i = 0; i < drawerMenu.size(); i++){
    menuItemArray.add(drawerMenu.getItem(i));
    drawerMenu.getItem(i).setChecked(false);
}
item.setChecked(true);
drawerLayout.closeDrawers();
fragmentTransaction = getSupportFragmentManager().beginTransaction();
int position = menuItemArray.indexOf(item);
Bundle bundle;
try{
    bundle = new Bundle();
    bundle.putString(MainActivity.EXTRA_TITLE, drawerItemList.get(position).getName());
    bundle.putString(MainActivity.EXTRA_LOCATION, drawerItemList.get(position).getLocation());
    bundle.putString(MainActivity.EXTRA_ROOMS, roomData);
    setTitle(drawerItemList.get(position).getName());
    drawerItemList.get(position).getFragment().setArguments(bundle);
    fragmentTransaction.replace(R.id.frame, drawerItemList.get(position).getFragment());
    fragmentTransaction.commit();
}
catch(IllegalStateException ise){
    ise.printStackTrace();
}
Dieser Code behandelt Klicks auf das Menü des NavigationDrawers. Wird ein Menüpunkt angeklickt, so wird dieser als aktiv markiert und das entsprechende Fragment mit den entsprechenden Daten aufgerufen.

content_main.xml bearbeiten

Im vorherigen Code-Block wird in der vorletzten Zeile des try-Blocks die ID "R.id.frame" verwendet. Diese muss nun dem entsprechenden Layout zugewiesen werden. Dazu öffnest du die Datei mobile -> res -> layout -> content_main.xml und fügst dort dem öffnenden RelativeLayout-Tag das folgende Attribut zu:
android:id="@+id/frame"

Bei Programmstart den ersten Menüpunkt auswählen

Damit der erste Menüpunkt bei Programmstart automatisch ausgewählt wird, wird der Methode "onCreate" der Klasse MainActivity am Ende der folgende Code hinzugefügt:
//Das erste DrawerItem ausw&auml;hlen
try{
    onNavigationItemSelected(drawerMenu.getItem(0));
}
catch(NullPointerException npe){
    npe.printStackTrace();
}

Den Header des NavigationDrawers setzen

Damit der Header des NavigationDrawers mit eigenen Daten bestückt werden kann (als Text soll der Name des eingeloggten Nutzers angezeigt werden), müssen über der Methode "onCreate" die folgenden Variable hinzugefügt werden:
//Header
ImageView headerImage;
TextView headerName;
View headerLayout;
Anschließend wird am unteren Ende der Methode "onCreate" der folgende Code eingefügt, um den Header dem NavigattionDrawer hinzuzufügen und ihn mit Daten zu füllen:
//Header laden
headerLayout = navigationView.inflateHeaderView(R.layout.nav_header_main);
headerName = (TextView) headerLayout.findViewById(R.id.username);
headerName.setText(SaveData.getUsername(getApplicationContext()));
Als nächstes wird das Layout des Headers angepasst, da nur eine statt zwei Textzeilen benötigt wird. Dazu wird die Datei mobile -> res -> layout -> nav_header_main.xml geöffnet und der Code mit dem folgenden ersetzt:
<?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="@dimen/nav_header_height"
    android:background="@drawable/side_nav_bar"
    android:gravity="bottom"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:theme="@style/ThemeOverlay.AppCompat.Dark">

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingTop="@dimen/nav_header_vertical_spacing"
        android:src="@mipmap/ic_launcher" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingTop="@dimen/nav_header_vertical_spacing"
        android:text="Android Studio"
        android:textAppearance="@style/TextAppearance.AppCompat.Body1"
        android:textColor="#FFFFFF"
        android:id="@+id/username"/>

</LinearLayout>
Da der NavigationDrawer standardmäßig bereits einen Header enthält, muss dieser zuerst entfernt werden, damit er am Ende nicht zwei Header hat. Dazu wird die Datei mobile -> res -> layout -> activity_main.xml geöffnet und die folgende Zeile aus dem "android.support.design.widget.NavigationView"-Tag entfernt:
app:headerLayout="@layout/nav_header_main"

Die Methode "loadRooms" erstellen

Im letzten Tutorial wurde beim Abfangen des Intents in der Methode "onCreate" der Klasse MainActivity der folgende Code geschrieben:
//Intent abfangen
Bundle extras = getIntent().getExtras();
if(extras != null && extras.containsKey(MainActivity.EXTRA_ROOMS)){
    roomData = extras.getString(MainActivity.EXTRA_ROOMS);
    createRooms(roomData);
}
else{
    //loadRooms();
}
Die Methode "loadRooms()" ist auskommentiert, da sie noch nicht existiert. Du kannst die "//" nun entfernen, da die Methode jetzt implementiert wird. Um dies zu tun, schreibst du den folgenden Code in den Klassen-Block der MainActivity:
/**
 * L&auml;dt auf dem Server angelegte R&auml;ume und f&uuml;hrt dann createRooms() aus
 */
public void loadRooms(){
    Map<String, String> requestData = new HashMap<>();
    requestData.put("action", "getrooms");
    requestData.put("username", SaveData.getUsername(getApplicationContext()));
    requestData.put("password", SaveData.getPassword(getApplicationContext()));
    HTTPRequest.sendRequest(getApplicationContext(), requestData, SaveData.getServerIp(getApplicationContext()), new HTTPRequest.HTTPRequestCallback() {
        @Override
        public void onRequestResult(String result) {
            if(!result.equals("")){
                roomData = result;
                createRooms(result);
            }
            else fehlermeldung("Serverfehler");
        }
        @Override
        public void onError(String msg) {
            fehlermeldung(msg);
        }
    });
}

Ressourcendateien erstellen

Damit beispielsweise veschiedene Spaltenanzahlen von Layouts für veschiedene Bildschirmgrößen verwendet werden können, wird eine Ressourcendatei für ganze Zahlen angelegt, in der die entsprechenden Werte hinterlegt werden. Dazu klickst du mit rechts auf den Ordner (oder eine darin enthaltene Datei) unter dem Pfad mobile -> res -> values und wählst "New -> Values resource file".
Zuerst wird die Datei
In dem Fenster das sich nun öffnet, gibst du als Namen der Datei "integers" ein und klickst auf "OK". Nun öffnet sich die erstellte Datei und du ersetzt den Code mit dem folgenden:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <integer name="grid_columns">2</integer>
</resources>
Anschließend wird ein Verzeichnis für Animations-Ressourcendateien erstellt.
So wird ein neues Verzeichnis für Animationen erstellt.
Dazu klickst du mit rechts auf den Ordner mobile -> res und wählst "New -> Directory". Dort trägst du als Verzeichnisnamen "anim" ein und klickst auf "OK".
Dann wird die Ressourcendatei erstellt.
Danach klickst du mit rechts auf das eben angelegte Verzeichnis und wählst "New -> Animation resource file". Jetzt gibst du als Dateinamen "recycler_animation" ein und klickst auf "OK". In der Datei, die sich nun öffnet, fügst du zwischen die set-Tags den folgenden Code ein:
android:interpolator="@android:anim/linear_interpolator">
<scale android:fromXScale="0.0"
    android:fromYScale="0.0"
    android:toXScale="1.0"
    android:toYScale="1.0"
    android:duration="250"
    android:fillBefore="false" />
<translate android:fromXDelta="50%"
    android:toXDelta="0%"
    android:fromYDelta="50%"
    android:toYDelta="0%"
    android:duration="250" />

Über den Autor


Sascha Huber

Hallo, ich bin Sascha, der Gründer von Smarthome Blogger.

Mit einer Leidenschaft für Technologie und einem Hintergrund als Software Engineer habe ich 2016 Smarthome Blogger gegründet. Mein Ziel war es schon immer, innovative Lösungen zu entdecken, die unser Leben einfacher und intelligenter gestalten können. In meinem beruflichen Leben arbeite ich täglich mit Software und Technik, aber auch in meiner Freizeit bin ich stets auf der Suche nach neuen technischen Spielereien und Möglichkeiten, mein Zuhause zu automatisieren und zu verbessern.

Auf Smarthome Blogger teile ich mein Wissen, meine Erfahrungen und meine Begeisterung für alles rund um das Thema Smarthome.



Dieser Beitrag hat dir gefallen?

Dann abonniere doch unseren Newsletter!