Mobile App Development - Grafische Oberflächen 2 - Inhalt • Dimensionen • Layouting • Menüs • Activities starten • Übung Mobile App Development Dimensionen Dimensionen • Analog zu Strings und Farben können Dimensionen definiert werden • Dimensionen sind Zahlen gefolgt von einer Einheit Mobile App Development Dimensionen • Analog zu Strings und Farben können Dimensionen definiert werden • Dimensionen sind Zahlen gefolgt von einer Einheit res/values/dimens.xml <?xml version="1.0" encoding="utf-8"?>! <resources>! <dimen name="testDim">35pt</dimen>! <dimen name="testDim2">35dp</dimen>! </resources> Mobile App Development Dimensionen • Pixel (px) • entsprechen den tatsächlichen Pixeln auf dem Endgerät • Verwendung wird nicht empfohlen, da die Darstellung von der Pixeldichte des Endgerätes abhängt Mobile App Development Dimensionen • Pixel (px) • Beispiel <Button! android:id="@+id/Button01"! android:text="@string/mybutton"! android:width="320px" /> 2,54 cm 5,08 cm 320 dpi 160 dpi Mobile App Development Dimensionen • Density Independent Pixels (dp, dip) • unabhängig von der Auflösung des Displays • 1dp = 1px (bei 160dpi) • 1px = 1dp * (Auflösung / 160) Mobile App Development Dimensionen • Scale Independent Pixels (sp) • das gleiche wie dp • zusätzlich abhängig von der SchriftgrößeEinstellung des Benutzers Mobile App Development Dimensionen • Pixeldichte-unabhängige Einheiten • Point (pt) • ein Point entspricht 1/72 Zoll • Millimeter (mm) • Inch (in) Mobile App Development Dimensionen • Definition: Dimensionen werden analog zu Farben und Strings in einer ResourcenDatei abgelegt (dimens.xml) • Beispiel: <?xml version="1.0" encoding="utf-8"?>! <resources>! <dimen name="myTextSize">60sp</dimen>! <dimen name="myWidth">25dp</dimen>! <dimen name="myBorder">16px</dimen>! <dimen name="myFontSize">23pt</dimen>! <dimen name="myMargin">5mm</dimen>! <dimen name="mySpace">17in</dimen>! </resources> Mobile App Development Dimensionen • Verwendung in XML res/values/dimens.xml <?xml version="1.0" encoding="utf-8"?>! <resources>! <dimen name="myTextSize">60sp</dimen>! </resources>! res/layout/myactivity.xml <LinearLayout xmlns:android="..."! xmlns:tools="..."! android:id="@+id/linearLayout"! android:orientation="vertical" >! ! ! <TextView! android:id="@+id/textView1"! android:layout_width="wrap_content"! android:layout_height="wrap_content"! android:text="@string/largeText"! android:textSize="@dimen/myTextSize" />! </LinearLayout> Mobile App Development Dimensionen • programmatische Verwendung res/values/dimens.xml <?xml version="1.0" encoding="utf-8"?>! <resources>! <dimen name="myTextSize">60sp</dimen>! </resources>! public class MainActivity extends Activity {! ! ... ! @Override! ! public void onCreate(Bundle savedInstanceState) {! ! ! super.onCreate(savedInstanceState);! ! ! setContentView(R.layout.activity_main);! ! ! ! ! ! ! ! ! float dim = getResources().getDimension(R.dimen.myTextSize);! ! } ! ... } Mobile App Development Layou6ng Layou6ng • Problemstellung • verschiedene Display-Größen • verschiedene Auflösungen • verschiedene Orientierungen Mobile App Development Layou6ng ! ! ! • Beispiel Orientierung Mobile App Development Layou6ng • Beispiel Orientierung • Was fällt auf ?? Mobile App Development Layou6ng ! • Wie wäre es mit verschiedenen Layouts? Mobile App Development Layou6ng • Und was ist mit Display- ... • Auflösung • Größe • Format Bildquelle: http://developer.android.com/guide/topics/resources/providing-resources.html#AlternativeResources Mobile App Development Layou6ng • Android ermöglicht die Erstellung von Layouts für verschiedene DisplayKonfigurationen • Unterscheidbare Eigenschaften • Größe • Orientierung • Pixeldichte Mobile App Development Layou6ng • Mögliche Displaygrößen • klein (ca. 2 - 3,5 Zoll) • normal (3,2 - 4 Zoll) • groß (4 - 7 Zoll) • sehr groß (7 - 10 Zoll) Bildquelle: http://developer.android.com/guide/practices/screens_support.html Mobile App Development Layou6ng • Definition von Layouts für verschiedene Display-Größen • Je Display-Größe wird ein Layout-Ordner angelegt • layout-small • layout-normal • layout-large • layout-xlarge Mobile App Development Layou6ng • Das Layout kann für die verschiedenen Größen verschieden definiert werden • Achtung: Die Layout-Datei muss in jedem Ordner den gleichen Name haben Mobile App Development Layou6ng • Es kann, muss aber nicht, für jede Größe eine Layout-Datei angelegt werden • Android wählt bei Fehlen eines Layouts für eine bestimmte Größe ein anderes aus Mobile App Development Layou6ng • Wie werden die verschiedenen Layouts der Activity zugewiesen? public class MainActivity extends Activity {! ! ... ! ! ! @Override! public void onCreate(Bundle savedInstanceState) {! ! super.onCreate(savedInstanceState); /* ... alles bleibt beim alten Android entscheidet */! setContentView(R.layout.activity_main);! ! }! ! } ...! ! Mobile App Development Layou6ng • Ist es möglich in der einen Layout- Definition andere Views zu definieren, als in einer anderen? Mobile App Development Layou6ng • Ist es möglich in der einen Layout- Definition andere Views zu definieren, als in einer anderen? Name Vorname Name Straße Vorname Hausnummer Mobile App Development Layou6ng • Ist es möglich in der einen Layout- Definition andere Views zu definieren, als in einer anderen? • Ja, es ist möglich! • Es ist zu beachten, dass in der Activity dann Fallunterscheidungen vorgenommen werden müssen Mobile App Development Layou6ng • Fallunterscheidung Display-Größe Configuration conf = getResources().getConfiguration();! switch (conf.screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! } case Configuration.SCREENLAYOUT_SIZE_SMALL: {! /* do your small stuff */! ! ! ! break;! }! case Configuration.SCREENLAYOUT_SIZE_NORMAL: {! /* do your normal stuff */! ! ! ! break;! }! case Configuration.SCREENLAYOUT_SIZE_LARGE: {! /* do your large stuff */!! ! ! break;! }! default : {! /* do your unknown stuff */! ! ! ! break;! }! Mobile App Development Layou6ng • Display-Größe ab Android 3.2 • Problem: generalisierte Größenklassen führen zu Problemen • 5“ und 7“ würden in gleiche Klasse fallen Mobile App Development Layou6ng • Ab Android 3.2 werden neue Qualifier für die Display-Größe verwendet • smallestWidth • screenWidth • screenHeight • Sie geben die minimale Breite/Höhe an, die für das Layout benötigt wird Mobile App Development Layou6ng • smallestWidth • gibt die minimale Breite bzw. Höhe in dp an, die das Layout benötigt • unabhängig von der Orientierung, d.h. es wird sowohl in horizontaler als auch vertikaler Orientierung diese Breite/ Höhe benötigt Mobile App Development Layou6ng • smallestWidth Layout • Anlegen eines Ordners layout-sw<N>dp • <N> steht für die minimale Größe in dp, die horizontal und vertikal benötigt wird (hier: 320dp) Mobile App Development Layou6ng • screen width • gibt die minimale Breite an, die das Layout benötigt • abhängig von der Orientierung, da sich die Breite ändert, wenn das Gerät gedreht wird Mobile App Development Layou6ng • screen width Layout • Anlegen eines Ordners layout-w<N>dp • <N> steht für die minimale Breite in dp, die benötigt wird (hier: 240dp) Mobile App Development Layou6ng • screen height • gibt die minimale Höhe an, die das Layout benötigt • abhängig von der Orientierung, da sich die Höhe ändert, wenn das Gerät gedreht wird Mobile App Development Layou6ng • screen height Layout • Anlegen eines Ordners layout-h<N>dp • <N> steht für die minimale Höhe in dp, die benötigt wird (hier: 480dp) Mobile App Development Layou6ng • Orientierung • Android unterscheidet 2 Qualifier • Portrait (port) • Landscape (land) Mobile App Development Layou6ng • Layouts für Orientierungen anlegen • gleiches Vorgehen wie bei Display-Größen • je Orientierung wird ein Ordner angelegt • für jede Orientierung wird ein Layout angelegt Mobile App Development Layou6ng • Fallunterscheidung Orientierung Configuration conf = getResources().getConfiguration();! switch (conf.orientation) {! ! case Configuration.ORIENTATION_PORTRAIT: {! ! ! /* do your portrait stuff */! ! ! Log.d("TAG", "orientation: portrait");! ! ! break;! ! }! ! case Configuration.ORIENTATION_LANDSCAPE: {! ! ! /* do your landscape stuff */! ! ! Log.d("TAG", "orientation: landscape");! ! ! break;! ! }! ! default : {! ! ! Log.d("TAG", "orientation: unspecified");! ! ! break;! ! }! } Mobile App Development Layou6ng • Layouts für verschiedene Auflösung • Android unterscheidet 4 Qualifier • ldpi, mdpi, hdpi, xhdpi Bildquelle: http://developer.android.com/guide/practices/screens_support.html Mobile App Development Layou6ng • Layouts für verschiedene Auflösungen definieren • Analog zu Display-Größe und Orientierung werden Ordner für die einzelnen Auflösungen angelegt Mobile App Development Layou6ng • Fallunterscheidung Auflösung /* create a DisplayMetrics object */! DisplayMetrics metrics = new DisplayMetrics();! /* requesting metrics from default display */! getWindowManager().getDefaultDisplay().getMetrics(metrics);! ! /* switch density */! switch (metrics.densityDpi) {! case DisplayMetrics.DENSITY_LOW: {! /* do your low stuff */ break;! ! }! ! case DisplayMetrics.DENSITY_MEDIUM: {! /* do your medium stuff */ break;! }! case DisplayMetrics.DENSITY_HIGH: {! /* do your high stuff */ break;! }! case DisplayMetrics.DENSITY_XHIGH: {! /* do your extra high stuff */ break;! }! } Mobile App Development Layou6ng • Wie definiert man ein Layout für einen small Screen mit mittlerer Auflösung? Mobile App Development Layou6ng • Die Qualifier für Größe, Orientierung usw. können kombiniert werden • Die Reihenfolge der Qualifier ist nicht beliebig! dazu: • siehe http://developer.android.com/guide/topics/ resources/providingresources.html#QualifierRules Mobile App Development Layou6ng • Neben Größe, Orientierung und Auflösung existieren noch weitere Qualifier • Sprache/Region: de-rDE, en-rUS • Aspect Ratio: long, not long • Night mode: night, notnight Qualifier unter: • weitere http://developer.android.com/guide/topics/resources/ providing-resources.html#AlternativeResources Mobile App Development Menüs Menüs Menüs werden verwendet, um dem Benutzer Aktionen und Optionen in einem bestimmten Kontext anzuzeigen Mobile App Development Menüs • Unterscheidung zwischen Optionsmenüs Mobile App Development Kontextmenüs Popup-Menüs Menu erstellen ! • Anlegen einer neuen Menü XML Datei im Ordner res/menu Mobile App Development Menu erstellen • Anlegen einer neuen Menü XML Datei im Ordner res/menu Mobile App Development Menüs erstellen • das Menü erstellen <?xml version="1.0" encoding="utf-8"?>! <menu xmlns:android="..." >! ! ! <item! android:id="@+id/menu_new"! android:icon="@android:drawable/ic_menu_add"! android:title="@string/menu_new"/>! <item! android:id="@+id/menu_edit"! android:icon="@android:drawable/ic_menu_edit"! android:title="@string/menu_edit"/>! <item! android:id="@+id/menu_search"! android:checkable="true"! android:icon="@android:drawable/ic_menu_search"! android:title="@string/menu_search"/>! </menu> Mobile App Development Menüs erstellen • das Menü erstellen • höchstens 6 Items dargestellt • bei mehr Items weiteres Popup Mobile App Development Menüs erstellen • Untermenüs <?xml version="1.0" encoding="utf-8"?>! <menu xmlns:android="..." >! ! <item! android:id="@+id/menu_new"! android:icon="@android:drawable/ic_menu_add"! android:title="@string/menu_new">! <menu>! <item! android:id="@+id/menu_file"! android:title="@string/menu_file"/>! <item! android:id="@+id/menu_folder"! android:title="@string/menu_folder"/>! </menu>! </item>! ! ... </menu> Mobile App Development Menüs erstellen • Für jedes angelegte Menü wird ein gleichnamiger Eintrag in der R.java angelegt public final class R {! ...! public static final class menu {! public static final int activity_main=0x7f060000;! public static final int second_menu=0x7f060001;! }! ...! } Mobile App Development Op6onsmenüs • Verwendung als Optionsmenü • Optionsmenüs werden verwendet, um dem Benutzer im Kontext der aktuellen Activity Optionen und Aktionen zu Verfügung zu stellen Mobile App Development Op6onsmenüs • Menü als Optionsmenü verwenden public class MainActivity extends Activity {! ! ! @Override! public void onCreate(Bundle savedInstanceState) {! ...! }! /* wird von der Activity aufgerufen, um das Menü zu erstellen */! @Override! public boolean onCreateOptionsMenu(Menu menu) {! /* MenuInflater wird verwendet, um aus der XML Menü * Beschreibung Java Objekte zu erzeugen */! MenuInflater inflater = getMenuInflater();! /* Erstellen des Menüs aus der XML Ressource unter Angabe der ! * Menü ID */! inflater.inflate(R.menu.activity_main, menu);! /* true gibt an, dass das Menü angezeigt werden soll */! return true;! }! } Mobile App Development Op6onsmenüs • Auf Menü-Klicks reagieren ! ! ! ! ! ! ! ! ! ! ! ! /* wird aufgerufen, wenn ein Menüeintrag ausgewählt wurde */! @Override! public boolean onOptionsItemSelected(MenuItem item) {! ! ! /* item.getItemId() gibt die ID des geklickten Menüeintrags zurück */! ! switch (item.getItemId()) {! ! case R.id.menu_new_file: {! ! ! /* neue Datei erstellen */! ! ! return true;! ! }! ! case R.id.menu_new_folder: {! ! ! /* neuen Ordner erstellen */! ! ! return true;! ! }! ! default:! ! ! /* Oberklassen Implementierung bahandelt Klick */! ! ! return super.onOptionsItemSelected(item);! ! }! } Mobile App Development Kontextmenüs • Das Menü als Kontextmenü verwenden • Kontextmenüs werden verwendet, um dem Benutzer im Kontext einer bestimmten View ein Menü zur Verfügung zu stellen Mobile App Development Kontextmenüs • Das Menü als Kontextmenü verwenden public class MainActivity extends Activity {! @Override! public void onCreate(Bundle savedInstanceState) {! super.onCreate(savedInstanceState);! setContentView(R.layout.activity_main);! /* Referenz für die View holen, die das Kontextmenü bekommt */! TextView tv = (TextView) findViewById(R.id.myTextView);! /* View für Kontextmenü registrieren */! registerForContextMenu(tv);! } /* wird aufgerufen, wenn das Kontextmenü erzeugt wird */! @Override! public void onCreateContextMenu(ContextMenu menu, View v,! ! ! ContextMenuInfo menuInfo) {! /* Inflater wird verwendet, um aus XML Java Objekte zu erzeugen */! MenuInflater inflater = getMenuInflater();! /* Erstellen des Menüs aus der XML Ressource unter Angabe der Menü ID */! inflater.inflate(R.menu.activity_main, menu);! }! } Mobile App Development Kontextmenüs • Auf Klicks im Kontextmenü reagieren public class MainActivity extends Activity {! public void onCreate(Bundle savedInstanceState) {! /* Kontextmenü registrieren */! } /* wird aufgerufen, wenn das Kontextmenü erzeugt wird */! public void onCreateContextMenu(...) {! ! /* Kontextmenü erstellen */! }! /* wird aufgerufen, wenn ein Kontextmenüeintrag ausgewählt wurde */! @Override! public boolean onContextItemSelected(MenuItem item) {! ! /* item.getItemId() gibt die ID des geklickten Menüeintrags zurück */! ! switch (item.getItemId()) {! ! ! case R.id.menu_new_file:! ! ! ! /* neue Datei erstellen */ return true;! ! ! case R.id.menu_new_folder:! ! ! ! /* neuen Ordner erstellen */ return true;! ! ! default:! ! ! ! /* Oberklassen behandelt Klick */! ! ! ! return super.onContextItemSelected(item);! ! }! }! }! Mobile App Development Popup-­‐Menüs • Das Menü als Popup-Menü verwenden • Popup-Menüs werden verwendet, um im Kontext einer Aktion weitere Optionen zur Verfügung zu stellen • Popup-Menüs stehen ab APILevel 11 zur Verfügung Mobile App Development Popup-­‐Menüs • Das Menü als Popup-Menü verwenden • Beispiel: Bei Drücken des Buttons soll ein Popup-Menü erscheinen Mobile App Development Popup-­‐Menüs • Das Menü als Popup-Menü verwenden <Button! android:id="@+id/myButton"! android:onClick="myPopupButtonClick"! android:text="@string/popupButton" /> public class MainActivity extends Activity {! ! /* Methode, die bei Button-Klick aufgerufen wird */! public void myPopupButtonClick(View view) {! /* Erzeugen eines neuen Popup-Menüs */! PopupMenu popup = new PopupMenu(this, view);! /* menuInflater-Referenz vom Popup holen */! MenuInflater inflater = popup.getMenuInflater();! /* Menü aus XML erstellen */! inflater.inflate(R.menu.activity_main, popup.getMenu());! /* Popup anzeigen */! popup.show();! }! } Mobile App Development Popup-­‐Menüs • Auf Klicks im Popup-Menü reagieren ! ! ! ! ! ! ! ! ! /* Methode, die bei Button-Klick aufgerufen wird */! public void myPopupButtonClick(View view) {! PopupMenu popup = new PopupMenu(this, view);! MenuInflater inflater = popup.getMenuInflater();! inflater.inflate(R.menu.activity_main, popup.getMenu());! ! /* click listener für das Popup setzen */! popup.setOnMenuItemClickListener( new PopupMenu.OnMenuItemClickListener() {! ! /* wird aufgerufen, wenn ein Menüeintrag geklickt wurde */! ! ! @Override! ! ! public boolean onMenuItemClick(MenuItem item) {! ! ! ! /* switch über die MenuItem ID*/! ! ! ! switch (item.getItemId()) {! ! ! ! ! case R.id.menu_new_file: /* todo */ return true;! ! ! ! ! case R.id.menu_new_folder: /* todo */ return true;! ! ! ! ! default: return false;! ! ! ! }! ! ! }! });! popup.show();! } Mobile App Development Ac6onBar Ac6onBar • seit Android 3.0 kein Hardware MenüButton mehr notwendig • Einführung der ActionBar • API Level 11 + Theme.Holo Mobile App Development Ac6onBar • Die ActionBar füllen • gleiches Vorgehen, wie bei Optionsmenüs • Erstellen einer Menu-Datei res/menu/my_menu.xml <menu xmlns:android="http://schemas.android.com/apk/res/android" >! <item! android:id="@+id/menu_new"! android:icon="@android:drawable/ic_input_add"! android:title="@string/menu_new"/>! <item! android:id="@+id/menu_delete"! android:icon="@android:drawable/ic_delete"! android:title="@string/menu_delete"/>! <item! android:id="@+id/menu_settings" android:title="@string/menu_settings"/>! </menu> Mobile App Development Ac6onBar • Die ActionBar füllen • Das Menü aus XML erstellen public class MainActivity extends Activity { ...! @Override! public boolean onCreateOptionsMenu(Menu menu) {! /* Aus XML das Menü erstellen */! MenuInflater inflater = getMenuInflater();! inflater.inflate(R.menu.activity_main, menu);! /* super call */! return super.onCreateOptionsMenu(menu);! } ...! } Mobile App Development Ac6onBar • Auf ActionBar Klicks reagieren public class MainActivity extends Activity {! ...! @Override! public boolean onOptionsItemSelected(MenuItem item) {! ! /* switch über die MenuItem ID */! ! switch (item.getItemId()) {! ! ! case R.id.menu_new: {! ! ! ! /* ... todo ... */ return true;! ! ! }! ! ! case R.id.menu_delete: {! ! ! ! /* ... todo ... */ return true;! ! ! }! ! ! default: {! ! ! ! /* super Impl behandelt den Klick */! ! ! ! return super.onOptionsItemSelected(item);! ! ! }! ! }! }! } Mobile App Development Ac6onBar • ActionBar Menü-Einträge anpassen • showAsAction gibt an, wie das Menüelment in der ActionBar angezeigt wird (API Level 11 !) <menu xmlns:android="http://schemas.android.com/apk/res/android" >! <item! android:id="@+id/menu_search"! android:title="@string/menu_search"! android:icon="@android:drawable/ic_menu_search"! android:showAsAction="always" </menu> Mobile App Development />! Ac6onBar • ActionBar Menü-Einträge anpassen • showAsAction Werte • always: Element wird immer angezeigt • ifRoom: Element wird nur angezeigt, wenn genügend Platz ist • never: Element wird immer im Overflow angezeigt Mobile App Development Prak6kum Prak6kum Übung 02: Erweiterung Taschenrechner! ! Die Taschenrechner-App aus der letzten Übung soll erweitert werden. Über einen Menüeintrag „Weitere“ sollen in einem Untermenü die zusätzlichen Rechenoperationen Sinus, Kosinus, Tangens und Quadratwurzel auswählbar sein.! Außerdem soll die App für zwei verschiedene Layouts optimiert werden, zum einen für ein Smartphone (default Layout) und zum anderen für ein Tablet (ca. 7“ - 10“).! ! Es ist darauf zu achten, dass auf dem Tablet mehr Platz zur ! Verfügung steht als auf einem Smartphone, sodass die o.g. zusätzlichen Rechenoperationen in der Tablet Version nicht über ein Menü zur Verfügung gestellt werden müssen, sondern direkt mit angezeigt werden können.! Wie beim letzten Praktikum kann auch in dieser Übung die Bibliothek exp4j (http:// www.objecthunter.net/exp4j) verwendet werden.! ! Die Abgabe der Übung findet am Mittwoch, den 06.11.2013, statt. Mobile App Development Literatur I. Sven Haiges: Android Schnelleinstieg entwickler.press, 2011 II. Thomas Künneth: Android 3 - Apps entwickeln mit dem Android SDK Galileo Press, 2011 III.http://developer.android.com IV.Mark Murphy: The Busy Coders Guide To Android Development, 2013 Mobile App Development