Im letzten Teil des Tutorials habe ich dir erklärt, wie du in Android Studio ein Projekt erstellen und die ersten Aufgaben erledigen kannst. Im heutigen Tutorial wird der Login-Bildschirm der App designed und implementiert. Dazu startest du, falls nicht bereits geschehen, Android Studio und öffnest das Projekt über "File -> Open..." bzw. "File -> Open Recent".
Dieses Tutorial gibt es auch als Video!
Den Login-Bildschirm designen
Als erstes wird das Layout des Login-Bildschirms definiert. Dazu wird die Datei mobile -> res -> layout -> activity_login.xml geöffnet und der Code mit folgendem Code ersetzt (wenn die Datei geöffnet ist, kannst du links unten zwischen Design- und Textansicht umschalten):<?xml version="1.0" encoding="utf-8"?>
<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"
xmlns:app="http://schemas.android.com/apk/res-auto"
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.smarthome_blogger.smarthome.LoginActivity"
android:background="@color/layoutBackground"
android:id="@+id/frame">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_margin="15dp"
app:cardElevation="@dimen/cardViewElevation"
app:cardCornerRadius="@dimen/cardViewCornerRadius"
app:cardUseCompatPadding="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="5dp">
<ImageView
android:layout_width="match_parent"
android:layout_height="120dp"
android:id="@+id/app_logo"
android:layout_margin="10dp"
android:src="@mipmap/ic_launcher"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPersonName"
android:hint="Nutzername"
android:layout_marginBottom="5dp"
android:id="@+id/username"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:hint="Passwort"
android:layout_marginBottom="5dp"
android:id="@+id/password"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textUri"
android:hint="Server-IP"
android:layout_marginBottom="5dp"
android:id="@+id/server_ip"/>
<CheckBox
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Login-Daten speichern"
android:id="@+id/save_login"
android:gravity="center_horizontal|center_vertical"
android:layout_marginBottom="5dp"
android:checked="false"/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/Widget.AppCompat.Button.Colored"
android:background="@color/colorPrimary"
android:textColor="@color/textColorLight"
android:text="Login"
android:layout_alignParentRight="true"
android:id="@+id/login_button"/>
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminate="true"
android:layout_centerInParent="true"
android:visibility="gone"
android:id="@+id/loading_animation"/>
</RelativeLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
</RelativeLayout>
LoginActivity implementieren
Nachdem das Design des Login-Bildschirms definiert worden ist, wird als nächstes die Funktionalität implementiert. Öffne dazu die Datei mobile -> java -> de.smarthome_blogger.smarthome -> LoginActivity.java und füge über der Methode "protected void onCreate(Bundle savedInstanceState)" folgende Variablen ein:private EditText usernameField, passwordField, serverIpField;
private Button loginButton;
private CheckBox saveLogin;
private View loadingAnimation;
//Actionbar verstecken
getSupportActionBar().hide();
//Views deklarieren
usernameField = (EditText) findViewById(R.id.username);
passwordField = (EditText) findViewById(R.id.password);
serverIpField = (EditText) findViewById(R.id.server_ip);
loadingAnimation = findViewById(R.id.loading_animation);
loginButton = (Button) findViewById(R.id.login_button);
saveLogin = (CheckBox) findViewById(R.id.save_login);
//Dem Button eine Aktion zuweisen
loginButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String username = usernameField.getText().toString();
String password = passwordField.getText().toString();
String serverIp = serverIpField.getText().toString();
//Eingaben auf Vollständigkeit prüfen
if(username.equals("")){
fehlermeldung("Bitte gib deinen Nutzernamen ein");
}
else if(password.equals("")){
fehlermeldung("Bitte gib dein Passwort ein");
}
else if(serverIp.equals("")){
fehlermeldung("Bitte gib die Adresse des Servers ein");
}
else{
SaveData.setSaveLoginData(getApplicationContext(), saveLogin.isChecked());
login(username, password, serverIp);
}
}
});
//Haken je nach gespeicherten Daten setzen oder nicht
saveLogin.setChecked(SaveData.getSaveLoginData(getApplicationContext()));
//Bei jeder Änderung neu speichren, ob Login-Daten gespeichert werden sollen
saveLogin.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
SaveData.setSaveLoginData(getApplicationContext(), isChecked);
}
});
//Wenn Nutzerdaten vorhanden: automatisch einloggen
if(SaveData.getSaveLoginData(getApplicationContext())){
String username = SaveData.getUsername(getApplicationContext());
String password = SaveData.getPassword(getApplicationContext());
String serverIp = SaveData.getServerIp(getApplicationContext());
if(username != null && password != null && serverIp != null){
//Textfelder mit gespeicherten Daten füllen
usernameField.setText(username);
passwordField.setText(password);
serverIpField.setText(serverIp);
saveLogin.setChecked(true);
login(username, password, serverIp);
}
}
Erklärung des Codes
Als erstes wird die sogenannte Actionbar (die Titelleiste der App) im Login-Bildschirm ausgeblendet. die UI-Komponenten initialisiert und ihnen die entsprechenden Funktionen (OnClickListener, OnCheckedChangeListener) zugewiesen. Als letztes wird mit einer if-Abfrage geprüft, ob Nutzerdaten vorhanden sind und ob beim letzten Login angegeben wurde, dass sich die App automatisch einloggen soll. Ist dies der Fall, versucht die App, sich mit den vorhandenen Nutzerdaten einzuloggen. Als nächstes fügst du einfach den folgenden Code unter der Methode "onCreate()" ein:/**
* Versucht den Nutzer einzuloggen
* @param username
* @param password
* @param serverIp
*/
public void login(final String username, final String password, final String serverIp){
loadingAnimation.setVisibility(View.VISIBLE);
Map<String, String> requestData = new HashMap<>();
requestData.put("action", "getrooms");
requestData.put("username", username);
requestData.put("password", password);
HTTPRequest.sendRequest(getApplicationContext(), requestData, serverIp, new HTTPRequest.HTTPRequestCallback() {
@Override
public void onRequestResult(String result) {
loadingAnimation.setVisibility(View.GONE);
if(result.equals("wrongdata")){
fehlermeldung("Anmeldung nicht möglich! Bitte überprüfe deine Eingaben");
}
else if(result.equals("unknownuser")){
fehlermeldung("Dieser Nutzer existiert nicht");
}
else{
//gegebenenfalls Login-Daten speichern
if(saveLogin.isChecked()){
SaveData.setLoginData(getApplicationContext(), username, password);
SaveData.setServerIp(getApplicationContext(), serverIp);
}
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
intent.putExtra(MainActivity.EXTRA_ROOMS, result);
startActivity(intent);
}
}
@Override
public void onError(String msg) {
loadingAnimation.setVisibility(View.GONE);
fehlermeldung(msg);
}
});
}
/**
* Zeigt die übergebene Nachricht an
* @param msg
*/
public void fehlermeldung(String msg){
Snackbar.make(findViewById(R.id.frame), msg, Snackbar.LENGTH_SHORT).show();
}
Erklärung des Codes
Die Methode "login()" versucht, sich mit den angegebenen Nutzerdaten auf dem Server einzuloggen. Bei Erfolg wird zur Main-Actvity (sozusagen das Hauptmenü der App) gewechselt und die zurückgegebenen Daten des Servers (in diesem Fall eine Liste der vorhandenen Räume, damit die Menüpunkte im Hauptmenü erstellt werden können) an die Main-Activity übergeben. Bei Scheitern der Verbindung wird eine Fehlermeldung ausgegeben. Die Methode "fehlermeldung()" gibt lediglich den übergebenen Text aus.SaveData anlegen & vorläufig implementieren
Nun muss noch die Klasse SaveData angelegt werden. Dazu klickst du mit der rechten Maustaste auf den Ordner "de.smarthome_blogger.smarthome" oder eine darin enthaltene Klasse und wählst "New -> Java class". Dort gibst du nun als Namen "SaveData" ein. Alles andere lässt du unverändert und klickst "Ok". Jetzt öffnet sich die Klasse und du kannst sie bearbeiten. Vorerst werden nur Platzhalter-Methoden definiert, die beispielsweise vordefinierte Nutzerdaten zurückgeben. Diese Nutzerdaten solltest du noch entsprechend anpassen, indem du den Rückgabewert der Methode "getServerIp" auf die IP-Adresse deines Raspberry und den Nutzernamen und das Passwort in den Methoden "getUsername" und "getPassword" änderst. Den folgenden Code fügst du nun in die Klasse SaveData ein (unter der Zeile "public class SaveData{"):public static String getUsername(Context context){
return "Testnutzer";
}
public static String getPassword(Context context){
return "password";
}
public static String getServerIp(Context context){
return "192.168.178.xyz";
}
public static void setLoginData(Context context, String username, String password){}
public static void setServerIp(Context context, String serverIp){}
public static void setSaveLoginData(Context context, boolean saveLogin){}
public static boolean getSaveLoginData(Context context){
return true;
}
Dieser Beitrag hat dir gefallen?
Dann abonniere doch unseren Newsletter!