Layouts – Übersicht ● FrameLayout – Vermeiden – ● – ● Alles links oben – – Horizontal und vertikal, nebeneinander Verschachteln (kann langsam werden) Neuer Vertreter, wie Web-Layouttools Flexibel, interessante Alternative RelativeLayout – wer damit klar kommt – – Relative Lage zueinander Effizient Prof. Dr. Peter Barth, Mobile Computing LinearLayout ● LinearLayout – – ● Vertikal, horizontal nebeneinander Verschachtelt Beispiel – mXw bedeutet layout_width: match_parent layout_height: wrap_content Prof. Dr. Peter Barth, Mobile Computing FrameLayout: Links oben – TableLayout – nur für Tabellen GridLayout – Geordnetes Layout – ● ● LinearLayout – Standard – ● FrameLayout – Vermeiden 1 LinearLayout vertical, mXm Positioniert alle Views links oben Wenn mehrere dann übereinander <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:text="Diese TextView geht über alles"/> <TextView android:layout_width="wrap_content" android:layout_height="match_parent" android:width="60dp" android:gravity="center" android:background="#00FF00" android:text="Diese TextView geht über die gesamte Höhe" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:height="60dp" android:gravity="center" android:background="#FF0000" android:text="Diese Prof. Dr. Peter Barth, MobileTextView Computinggeht über die gesamte Breite" /> </FrameLayout> 2 TableLayout LinearLayout horizontal, mXw ● Tabelle mit Views – LinearLayout horizontal, mXw – – LinearLayout vertical, mXw – ● Optionen – – 3 Zeilenbasiert, <TableRow> Jede Spalte so breit wie die Breiteste strechColumns, um zu füllen Gut zum skalieren padding, gravity, … Trick zum Rahmen zeichnen* <TableLayout xmlns:android=... android:layout_width="match_parent" android:layout_height="match_parent" android:stretchColumns="1" > <TableRow> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="5dp" android:background="@drawable/back" android:text="Eins" /> <TextView ... android:gravity="left" /> <TextView … /> </TableRow> <TableRow> <TextView … /> <TextView android:gravity="right" /> </TableRow> </TableLayout> *http://stackoverflow.com/questions/3496269/how-to-put-a-border-around-an-android-textview Prof. Dr. Peter Barth, Mobile Computing 4 GridLayout ● RelativeLayout GridLayout – – – – – Anordnung in Zeilen/Spalten Grid Automatische oder explizite Zellenzuordnung Elemente können mehrere Zellen umfassen Gravity Space für Leerbereiche (Gewichte erst ab API 21) <GridLayout xmlns:... android:layout_width="match_parent" android:layout_height="match_parent" android:alignmentMode="alignBounds" android:useDefaultMargins="true" android:columnCount="4" > <TextView android:text="span4 cent_h" android:layout_columnSpan="4" android:layout_gravity="center_horizontal" /> <TextView android:text="span2 cent_h" android:layout_gravity="center_horizontal" android:layout_columnSpan="2" /> <TextView android:text="span2" android:layout_columnSpan="2" /> <TextView android:text="Vier sehr groß" /> <TextView android:text="Fünf" /> <TextView android:text="Sechs" /> <TextView android:text="Sieben right" android:layout_gravity="right"/> <TextView android:text="Sieben left" android:layout_gravity="left" android:layout_column="3" /> </GridLayout> http://android-developers.blogspot.de/2011/11/new-layout-widgets-space-and-gridlayout.html Prof. Dr. Peter Barth, Mobile Computing Menus ● Menus – – ● Ressource – – – – ● Mehrere mögliche (Inter-)Aktionen Deklarativ, Ressource res/menu/*.xml item mit ID, Title und Icon Vordefinerte Android-Icons Darstellung in ActionBar, meist never|ifRoom|always Gruppierung möglich ● Relative Layout: Relative Lage – – – Relative Anordnung zueinander Alle Views mit ID Lagespezifikation layout_* above toLeftOf toRightOf below – ● 5 <menu … > <item android:id="@+id/menu_search" android:title="Suche" android:icon="@android:drawable/ic_menu_search" android:showAsAction="ifRoom" /> <item android:id="@+id/menu_rotate" android:title="Sort" android:icon="@android:drawable/ic_menu_rotate" android:showAsAction="always" /> <group android:id="@+id/menu_group_admin"> <item android:id="@+id/menu_preferences" android:title="Einstellungen" android:icon="@android:drawable/ic_menu_preferences" android:showAsAction="never" /> … </group> </menu> Kombinationen möglich und sinnvoll Das effiziente, empfohlene Layout... Prof. Dr. Peter Barth, Mobile Computing ActionBar ● – ● – Standard seit API-11 Obere Leiste als zentrales Interaktionselement Overflow-Bereich Interaktion für App, Options-Menu Interaktion für ausgewählte Elemente, Kontext-Menu res/menu/actions.xml Kontext-Aktionen für ausgewählte Alle (anderen) Aktionen Kontext-Aktionen beenden OptionMenu (2.x) veraltet Prof. Dr. Peter Barth, Mobile Computing showAsAction always ActionBar – ● 6 Logo (meist App-Icon) und Name Darstellung: ActionBar, obere Leiste http://developer.android.com/guide/topics/ui/menus.html <RelativeLayout xmlns:android=... android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/tv1" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="#FF0000" android:text="TextView Eins" /> <TextView android:id="@+id/tv2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#00FF00" android:layout_below="@id/tv1" android:text="TextView Zwei" /> <TextView android:id="@+id/tv3" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="#6666FF" android:layout_toRightOf="@id/tv2" android:layout_below="@id/tv1" android:text="TextView Drei" /> </RelativeLayout> 7 http://developer.android.com/guide/topics/ui/actionbar.html Prof. Dr. Peter Barth, Mobile Computing 8 ActionBar aktivieren ● API-Level >= 11, alles ok – – – ● Festlegen mindestens API-11, wir nehmen sowieso 15 App-Style von Theme.Holo.* erben In Java import android.app.ActionBar; getActionBar() API-Level < 11 – – – – ActionBar/Menus verwenden <manifest … > <uses-sdk android:minSdkVersion="15" /> … </manifest> ● AndroidManifest.xml – – <resources> <style name="AppTheme" parent="android:Theme.Holo.Light"> </style> </resources> ● res/values/style.xml – ● public class MenuActivity extends Activity { … private ActionBar actionBar; @Override protected void onCreate( … ActionBar actionBar = getActionBar(); } … – – 9 Anpassen des Menus ● – ● – – ● Prof. Dr. Peter Barth, Mobile Computing ● Objekt-Baum verändern Nicht jedes Mal aufblasen (teuer) Wird gerufen vor jedem anzeigen Manipulation der Elemente möglich Hinzufügen/Entfernen möglich Beispiel – Bei jedem Anzeigen Such-Aktion mal aktiviert, mal deaktiviert Prof. Dr. Peter Barth, Mobile Computing Contextual Action Mode – Auswahl eines/mehrerer Elemente ● – Lösung: onPrepareOptionsMenu – Diskriminierung über ID des gewählten item true heißt abgearbeitet, falls nicht, dann super handeln lassen public class MenuActivity extends Activity { … @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.actions, menu); return super.onCreateOptionsMenu(menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.menu_finish: finish(); return true; case ... default: return super.onOptionsItemSelected(item); } 10 } Interaktion für ausgewählte Elemente in ActionBar Ziel: Anpassen des Menus – Inflater um XML nach Java-Objekt zu transformieren (aufblasen) Übergebenes menu füllen onOptionsItemSelected MenuActivity Prof. Dr. Peter Barth, Mobile Computing Aktionen unabhängig vom Kontext Callbacks onCreateOptionsMenu – import android.app.ActionBar; Support library Alle Pfade/Methoden etwas anders Von ActionBarActivity erben Doku lesen... ActionBar – Generell – ● – – – 11 Eins meist mit long click Aktion für diese Elemente Anzeige in ActionBar, ActionBar ändert sich Aktivieren – @Override public boolean onPrepareOptionsMenu(Menu menu) { MenuItem searchItem = menu.findItem(R.id.menu_search); if (searchItem.isEnabled()) { searchItem.setEnabled(false); } else { searchItem.setEnabled(true); } return super.onPrepareOptionsMenu(menu); } Kontext-Aktionen für ausgewählte ActionMode starten und merken, keine zwei gleichzeitig Callback (gleich) Bei ListView item merken/selektieren Im Beispiel LongClick Prof. Dr. Peter Barth, Mobile Computing Kontext-Aktionen beenden private ActionMode actionMode = null; ListView.OnItemLongClickListener oilcl = new ListView.OnItemLongClickListener() { @Override public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) { if (actionMode != null) { return false; } actionMode=MenusActivity.this.startActionMode(actionModeCallback); pairsAdapter.setSelectedPosition(position); return true; } }; public void onCreate(... ) { lvPairs.setOnItemLongClickListener(oilcl); ... 12 ActionMode.CallBack ● onCreate.. – ● onPrepare – ● Wie OptionsMenu, anpassen onActionItemClicked – – ● Wie OptionsMenu, aufblasen Mit item herausfinden was gemeint war Selektierte(s) separat merken! OnDestroy... – Freigeben, dass neu anlegen wieder klappt Eigentliche Behandlung ActionMode.Callback actionModeCallback = new ActionMode.Callback() { @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.contextactions, menu); return true; } @Override public boolean onPrepareActionMode(ActionMode mode, Menu menu) { return false; // nothing done } @Override public boolean onActionItemClicked(ActionMode mode, MenuItem item) { return handleMenuItemSelected(item); } @Override public void onDestroyActionMode(ActionMode mode) { MenusActivity.this.actionMode = null; } }; Prof. Dr. Peter Barth, Mobile Computing ● – ● ● – – 13 – – ● Prof. Dr. Peter Barth, Mobile Computing ● Eins meist mit long click – Aktion für diese Elemente Anzeige als überlagertes Auswahlelement, modales Kontext-Menu/Dialog – – – – registerForContextMenu ● Im Beispiel ListView ContextMenu traditionell automatisch bei LongClick onCreateContextMenu – Aktivieren – ● – – 15 Vor jeder Anzeige (immer neu) menu: Anzuzeigendes Menu view: Die darunterliegende View (im Beispiel das Layout mit der ListView) menuInfo: Extra-Information Einfach wieder aufblasen und zu menu hinzufügen onContextItemSelected – public void onCreate(... registerForContextMenu(lvPairs); Prof. Dr. Peter Barth, Mobile Computing 14 Kontext-Menu-Behandlung mit Callbacks Auswahl eines/mehrerer Elemente ● delete: löschen edit: Groß/Kleinschreibung Realisierung im Adapter } Floating Context Menu – Durch Adapter (später) Auswahl Aktion über ID Aktionen – Alternative – Interaktion für Ausgewählte als Kontext-Menu ● private boolean handleMenuItemSelected(MenuItem item) { int pos = pairsAdapter.getSelectedPosition(); if (pos == -1) { // nothing selected return super.onContextItemSelected(item); } switch (item.getItemId()) { case R.id.menu_edit: Pair<String, String> pair = pairsAdapter.getItem(pos); String first = null; if (Character.isUpperCase(pair.first.charAt(0))) { first = pair.first.toLowerCase(); } else { first = pair.first.toUpperCase(); } pairsAdapter.update(pos, first, pair.second); return true; case R.id.menu_delete: pairsAdapter.delete(pos); return true; default: return super.onContextItemSelected(item); } Selektierte finden @Override public void onCreateContextMenu( ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, v, menuInfo); MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.contextactions, menu); } @Override public boolean onContextItemSelected( MenuItem item) { AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo(); pairsAdapter.setSelectedPosition(info.position); return handleMenuItemSelected(item); } Bei Auswahl von Aktion (z.B. edit) Zusätzliche Information extrahierbar (info), bei ActionMode nicht zuverlässig, besser Selektiertes in Adapter merken Behandeln der Aktion wie gehabt Prof. Dr. Peter Barth, Mobile Computing 16 ScrollView ● Problem: Zu viele Elemente – – – ● ScrollView – Verwenden ● Lösung: Weniger Elemente Lösung: Widget erlaubt Scrolling, zum Beispiel ListView Lösung: Separater ScrollView – ● – – ● HorizontalScrollView Aber das ist Usability-Todsünde Prof. Dr. Peter Barth, Mobile Computing res/layout/scrollview.xml 17 Preferences ● – – ● ● Einfache Daten über Lebenszyklus der Anwendung hinaus merken Meist Einstellungen der Anwendung Vordefiniertes Layout und Ablage – – – – – ● Preferences als XML-Datei Keine vordefinierte Ressource Aber vorkompiliert Üblich: Werte in Ressourcen <string name="key_vorname"> vorname</string> <string name="key_nachname"> nachname</string> … <string-array name="stdg_entries"> <item>Angewandte Informatik</item> <item>Medieninformatik</item> … </string-array> <string-array name="stdg_entries_values"> <item>ai</item> <item>mi</item> … </string-array> Schlüssel/Wert Paare Texte, Ja/Nein, Auswahl, Zahlen, Kategorien Zugriff aus allen Activities einer App Prof. Dr. Peter Barth, Mobile Computing Deklaration – Preferences 19 ScrollViewActivity.onCreate Prof. Dr. Peter Barth, Mobile Computing Preferences – Deklaration Einstellungen/Settings – Beispiel: mit Java-Code <ScrollView ... android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:id="@+id/ll_scrollview" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> </LinearLayout> </ScrollView> Ein Layout, von FrameLayout abgeleitet Nur Widgets ohne eigenes Scrolling verwenden Vertikales Scrolling ● LinearLayout als Kind zum Füllen LinearLayout füllen – ScrollView – Layout mit ScrollView-Wurzel super.onCreate(savedInstanceState); setContentView(R.layout.scrollview); LinearLayout linearLayout = (LinearLayout) findViewById(R.id.ll_scrollview); ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); View.OnClickListener ocl = new View.OnClickListener() { @Override public void onClick(View view) { CharSequence msg = ((TextView) view).getText(); Toast.makeText(ScrollViewActivity.this, msg, Toast.LENGTH_SHORT).show(); } }; for (int i=0; i < 123; i+=1) { TextView textView = new TextView(this); textView.setLayoutParams(layoutParams); textView.setText(String.format("TextView %03d", i)); textView.setClickable(true); textView.setOnClickListener(ocl); linearLayout.addView(textView); } Prof. Dr. Peter Barth, Mobile Computing 18 <PreferenceScreen … > <PreferenceCategory android:title="Persönlich" > <EditTextPreference android:key="@string/key_vorname" android:title="Vorname" android:defaultValue="Susi" /> … </PreferenceCategory> <PreferenceCategory android:title="Anwendung" > <CheckBoxPreference android:key="@string/key_bafoeg" android:title="Bafög" android:defaultValue="false" /> <ListPreference android:key="@string/key_stdg" android:title="Studiengang" android:entries="@array/stdg_entries" android:entryValues="@array/stdg_entries_values" android:defaultValue="mi" /> </PreferenceCategory> … </PreferenceScreen> res/xml/preferences.xml Anzeige bei Auswahl Wert in Preferences, gut als Key in Map 20 Preferences – Ändern ● Separate Activity – – – – PreferencesFragment PreferenceActivity deprecated PreferenceFragment Nutzen in Activity immer so verwenden public class SettingsFragment extends PreferenceFragment { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.preferences); } } Prof. Dr. Peter Barth, Mobile Computing public class Settings extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getFragmentManager().beginTransaction() .replace(android.R.id.content, new SettingsFragment()) .commit(); } } 21 Preferences – Zugriff ● In jeder Activity – – – ● PreferenceManager setDefaultValues Sicherstellen initialisiert (zumindest in Main Activity) getDefault SharedPreferences für Zugriff get* – – Je Typ ein Getter, Schlüssel, Vorgabewert getString häufig Prof. Dr. Peter Barth, Mobile Computing Prof. Dr. Peter Barth, Mobile Computing 22 Preferences – Map für Auswahl ShowPreferences.onCreate ● PreferenceManager.setDefaultValues(this, R.xml.preferences, false); preferences = PreferenceManager.getDefaultSharedPreferences(this); Map – – tvVorname = (TextView) findViewById(R.id.tv_vorname); … Resources resources = getResources(); keyVorname = resources.getString(R.string.key_vorname); – ShowPreferences.refresh String → String Wert, der in den Preferences abgelegt wird ist Schlüssel in der Map AnzeigeString ist Wert in der Map ShowPreferences.onCreate String[] stdgEntries = resources.getStringArray(R.array.stdg_entries); String[] stdgEntriesValues = resources.getStringArray(R.array.stdg_entries_values); stdgMap = new HashMap<String, String>(); for (int i=0; i < stdgEntries.length; i+=1) { stdgMap.put(stdgEntriesValues[i], stdgEntries[i]); } tvVorname.setText(preferences.getString(keyVorname, null)); tvBafoeg.setText("" + (preferences.getBoolean(keyBafoeg, false))); tvStdg.setText(stdgMap.get(preferences.getString(keyStdg, null))); … 23 Prof. Dr. Peter Barth, Mobile Computing 24 Preferences – Änderungen ● Änderungen in Settings – ● Reagieren mit Callbacks/Listener OnShared Preference ChangeListener – – SharedPreferences.OnSharedPreferenceChangeListener ospcl = new SharedPreferences.OnSharedPreferenceChangeListener() { public void onSharedPreferenceChanged( SharedPreferences sharedPreferences, String key) { if (key.equals(keyAutoUpdate)) { String t = sharedPreferences.getString(keyAutoUpdate, "0"); tvAutoUpdate.setText(t); } } }; … protected void onCreate(... preferences = PreferenceManager.getDefaultSharedPreferences(this); preferences.registerOnSharedPreferenceChangeListener(ospcl); } Parameter Preferences und geänderter Schlüssel Registrieren, am besten in onCreate Preferences – Ändern ● Ziel – ● Von Java aus Settings ändern – ● – Prof. Dr. Peter Barth, Mobile Computing Hierarchy Viewer – im DDMS 25 Ausgewähltes Element in Baumhierarchy Start Wahl Screen Element mit Mouseover Prof. Dr. Peter Barth, Mobile Computing Details zu Element 27 SharedPreferences Editor Zu festen Zeitpunkten – Bei Änderung automatisch aktualisiert AutoUpdate-Wert alle 3 Sekunden erhöhen Executor Start/Stop für Lebenszyklus Prof. Dr. Peter Barth, Mobile Computing private void incrementAutoUpdate() { int val = Integer.parseInt( preferences.getString(keyAutoUpdate, "0")); SharedPreferences.Editor editor = preferences.edit(); editor.putString(keyAutoUpdate, "" + (val + 1)); editor.commit(); } private ScheduledExecutorService scheduleTaskExecutor; protected void onStart() { super.onStart(); scheduleTaskExecutor = Executors.newSingleThreadScheduledExecutor(); scheduleTaskExecutor.scheduleAtFixedRate(new Runnable() { public void run() { incrementAutoUpdate(); }},0,3,TimeUnit.SECONDS); } protected void onStop() { super.onStop(); if (scheduleTaskExecutor != null) { scheduleTaskExecutor.shutdown(); scheduleTaskExecutor = null; } } 26
© Copyright 2024 ExpyDoc