Your SlideShare is downloading. ×

Android 4 - UI-Design

1,206
views

Published on

Speaker: Lars Röwekamp auf der MobileTechCon 2012 in Frankfurt am Main. …

Speaker: Lars Röwekamp auf der MobileTechCon 2012 in Frankfurt am Main.

Nahezu zeitgleich mit Android 4 wurden stark überarbeitet UI-Design-Guidelines veröffentlicht. Angefangen bei dem bereits aus Honeycomb bekannten Action Bar über verbesserte Navigationskonzepte bis hin zu Multi-Pane-Layouts auf Basis von Fragments, sollen die Richtlinien für eine deutlich verbesserte User Experience sorgen. Die Session stellt die wichtigsten Konzepte vor und zeigt, wie sie gewinnbringend innerhalb der eigenen Android-Anwendung eingesetzt werden können – auch ohne Android 4.

Published in: Technology, Business

0 Comments
8 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,206
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
0
Comments
0
Likes
8
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. ANDROID 4UI Design @mobileLarson @_openKnowledge Lars Röwekamp | CIO New Technologies
  • 2. Android 4 UI> Vereinfachtes Look & Feel> Vereinheitlichte Tablet/Phone Plattform> Action Bar> Navigation> Multi-Pane Layout> Rich Notifications> Drag & Drop Support
  • 3. Android 4 UI> Vereinfachtes Look & Feel> Vereinheitlichte Tablet/Phone Plattform> Action Bar> Navigation> Multi-Pane Layout> Rich Notifications> Drag & Drop Support
  • 4. Demo
  • 5. Unified UI
  • 6. Unified UI> Vereinheitlichte Tablet/Phone Plattform
  • 7. Unified UI> Vereinheitlichte Tablet/Phone Plattform
  • 8. Unified UI> Vereinheitlichte Tablet/Phone Plattform „more to come ...“
  • 9. Action Bar
  • 10. Action Bar> Dedizierter Bereich „oben“ auf jedem Screen> Menu-Ersatz für Schnellzugriff> Hervorheben prominenter Aktionen> Unterstützung von Navigation> Darstellen der aktuellen App-Position> Konsistenz zwischen Tablet & Smartphone> Ermöglichen von Branding
  • 11. Action Bar> Dedizierter Bereich „oben“ auf jedem Screen> Menu-Ersatz für Schnellzugriff> Hervorheben prominenter Aktionen> Unterstützung von Navigation> Darstellen der aktuellen App-Position> Konsistenz zwischen Tablet & Smartphone> Ermöglichen von Branding
  • 12. Action BarApp Icon View Control Action Btn Action Overflow
  • 13. Action Bar App Icon View Control Action Btn Action Overflow„Wo bin ich?“
  • 14. Action Bar App Icon View Control Action Btn Action Overflow„Wo bin „Was kann ich?“ ich sehen?“
  • 15. Action Bar App Icon View Control Action Btn Action Overflow„Wo bin „Was kann „Was kann ich?“ ich sehen?“ ich tun?“
  • 16. Action Bar> Activation // Step 1: Use Theme.Holo (or friends) <manifest ... >     <uses-sdk ...               android:targetSdkVersion="11" />     ... </manifest>
  • 17. Action Bar> Customizing // Step 2: Define „Action Bar“ <?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="...">     <item android:id="@+id/menu_save"           android:icon="@drawable/ic_menu_save"           android:title="@string/menu_save"           android:showAsAction="ifRoom|withText" /> ... </menu>
  • 18. Action Bar> Inflating // Step 3: Inflate „Action Bar“ @Override public boolean onCreateOptionsMenu(Menu menu) {     MenuInflater inflater = getMenuInflater();     inflater.inflate(R.menu.main_activity, menu);     return true; }
  • 19. Action Bar> Split Action Bar Main Action Bar Top Bar „Was machen, wenn‘s nicht passt?“ Bottom Bar
  • 20. Action Bar> Split Action Bar
  • 21. Action Bar> Split Action Bar
  • 22. Action Bar> Split Action Bar // SPLIT Action Bar <manifest ... >     <uses-sdk android:minSdkVersion="14"               android:targetSdkVersion="14" /> <application uiOptions="splitActionBarWhenNarrow"> ... </application>     ... </manifest>
  • 23. Action Bar> Contextual Action Bar (a.k.a. CAB)
  • 24. Action Bar> Contextual Action Bar (a.k.a. CAB)
  • 25. Action Bar> Contextual Action Bar > Kontext-spezifischer ActionMode > erlaubt spezielle Actions für aktuelle Auswahl > Action Bar wird automatisch angepasst > Selektion mehrerer Elemente ist möglich
  • 26. Action Bar> Contextual Action Bar // Step 1: ActionMode.Callback implementieren private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() { // inflate CAB menu here ... public boolean onCreateActionMode( ActionMode actionMode, Menu menu) { ... } // implement Action calls here ... public boolean onActionItemClicked( ActionMode actionMode, MenuItem menuItem) { ... } public void onDestroyActionMode( ActionMode actionMode) { ... } };
  • 27. Action Bar> Contextual Action Bar // Step 1: ActionMode.Callback implementieren private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() { // inflate CAB menu here ... public boolean onCreateActionMode( ActionMode actionMode, Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.ctx_mn_photo, menu); return true; } ... };
  • 28. Action Bar> Contextual Action Bar // Step 1: ActionMode.Callback implementieren private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() { ... // implement Action calls here ... public boolean onActionItemClicked( ActionMode actionMode, MenuItem menuItem) { switch(menuItem.getId()) { case (R.id.mn_share): sharePhoto(); actionMode.finish(); return true; } return false; } ... };
  • 29. Action Bar> Contextual Action Bar // Step 1: ActionMode.Callback implementieren private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() { ... // implement clean up code, if needed ... public void onDestroyActionMode( ActionMode actionMode) { mCurrentActionMode = null; mImageView.setSelected(false); } };
  • 30. Action Bar> Contextual Action Bar // Step 2: ActionMode fuer Image View Element starten mImageView.setOnLongClickListener(new View.OnLongClickListener() { public boolean onLongClick(View view) { mCurrentActionMode = startActionMode(mActionModeCallback); view.setSelected(true); return true; } });
  • 31. Navigation
  • 32. Navigation
  • 33. Navigation WTH! Somebody has stollen my buttons!
  • 34. Navigation Status BarNavigation Bar Combined Bar
  • 35. Navigation> Key Handling // Task 1: Intercept system bar button(s) @Override public boolean onKeyDown(int keyCode, KeyEvent event) { // only BACK // for RECENT APPs or HOME use NDK ;-) if (KeyEvent.KEYCODE_BACK == keyCode) {" " // do what ever you want to do ... "" """ }" return true; }
  • 36. Navigation> Fullscreen // Task 2: Hiding the system bar Window window = getActivity().getWindow(); View view = getView(); // Add fullscreen flag (hide status bar) window.setFlags( WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); // Hide system bar view.setSystemUiVisibility(View.STATUS_BAR_HIDDEN);
  • 37. Navigation> Fullscreen // Task 2: Hiding the system bar Window window = getActivity().getWindow(); View view = getView(); // Add fullscreen flag (hide status bar) window.setFlags( WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); // Hide system bar view.setSystemUiVisibility(View.STATUS_BAR_HIDDEN);
  • 38. Navigation> Fullscreen // Task 2: Hiding the system bar Window window = getActivity().getWindow(); View view = getView(); // Add fullscreen flag (hide status bar) window.setFlags( WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); // Hide system bar view.setSystemUiVisibility(View.STATUS_BAR_HIDDEN); // use SYSTEM_UI_FLAG_LOW_RPOFILE instead
  • 39. Navigation> Fullscreen // Task 2: Hiding the system bar Window window = getActivity().getWindow(); View view = getView(); // Add fullscreen flag (hide status bar) window.setFlags( WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); // Hide system bar view.setSystemUiVisibility(View.STATUS_BAR_HIDDEN); // use SYSTEM_UI_FLAG_HIDE_NAVIGATION instead
  • 40. Navigation
  • 41. Navigation> a.k.a. „Back“ vs. „Up“
  • 42. Navigation> „Back“ vs. „Up“
  • 43. Navigation
  • 44. Navigation
  • 45. Navigation
  • 46. Navigation> „Back“ vs. „Up“ // Enable UP navigation @Override public void onCreate(Bundle savedInstanceState) {" super.onCreate(savedInstanceState);" setContentView(R.layout.main);" ActionBar actionBar = getActionBar();" actionBar.setDisplayHomeAsUpEnabled(true);" ..." }
  • 47. Navigation> „Back“ vs. „Up“ // Use UP navigation @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { // app icon in action bar clicked: go home case android.R.id.home: Intent i = new Intent(this, MainActivity.class); i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(intent); return true; default: return super.onOptionsItemSelected(item); } }
  • 48. Multi-Pane
  • 49. Multi-Pane
  • 50. Multi-Pane> UI Fragments als „Building Blocks“> UI Activity Layout als „Block Assembler“> UI Activity Class als „Block Assembler Logic“> UI Ressources als „Switch“
  • 51. Multi-Pane Was ist ein> UI Fragments als „Building Blocks“> UI Activity Layout als „Block Assembler“ Fragment?> UI Activity Class als „Block Assembler Logic“> UI Ressources als „Switch“
  • 52. Multi-Pane> Fragments
  • 53. Multi-Pane
  • 54. Multi-Pane> Fragment > Activity Modul a.k.a. Sub Activity > inkl. eigener UI > inkl. eigenem Lifecycle > benötigt immer eine umliegende Activity > Lifecycle passt sich Activity-Lifecycle an
  • 55. Multi-Pane Und wieso> Fragment > Activity Modul a.k.a. Sub Activity Resources? > inkl. eigener UI > inkl. eigenem Lifecycle > benötigt immer eine umliegende Activity > Lifecycle passt sich Activity-Lifecycle an
  • 56. Multi-Pane> Resources > Size: small, normal, large, xlarge > Density: ldpi, mdpi, hdpi, xhdpi > Orientation: landscape, portrait > Designation: sw, w, h, ...dp
  • 57. Multi-Pane> Resources > Size: small, normal, large, xlarge Deprecated > Density: ldpi, mdpi, hdpi, xhdpi > Orientation: landscape, portrait > Designation: sw, w, h, ...dp Added
  • 58. Multi-PaneOk, aber wie> Resources > Size: small, normal, large, xlarge spielt das Deprecated > Density: ldpi, mdpi, hdpi, xhdpi > Orientation: landscape, portraitzusammen? > Designation: sw, w, h, ...dp Added
  • 59. Multi-Pane> in Action
  • 60. Multi-Pane> in Action
  • 61. Multi-Pane > in Action > Starte MainActivity > Screensize Smartphone > Orientierung Portrait 1) > Layout aus /res/layout > Fragment A > Bei Selektion schicke Intent „Details“ > Zeige DetailsActivity mit Fragment B1) Standardlayout
  • 62. Multi-Pane > in Action > Starte DetailsActivity > Screensize Smartphone > Orientierung Portrait 1) > Layout aus /res/layout > Fragment B1) Standardlayout
  • 63. Multi-Pane > in Action > Starte MainActivity > Screensize Tablet > Orientierung Landscape 1) > Layout aus /res/layout-sw600dp > Fragment A und B > Bei Selektion aktualisiere B1) Layout für: smalest witdh 600dp = 10“ Tablet
  • 64. Multi-Pane> Modus-Check // Check, if detail fragment is visible @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); ... DetailFragment frag = (DetailFragment) getFragmentManager() .findFragmentById(R.id.detail_fragment); if (frag != null) mDualPane = true; }
  • 65. Multi-Pane> Modus-Weiche // Call detail for selected list item @Override public void onItemSelected(int category, int pos) { if (!mDualPane) { Intent i = new Intent(this, DetailActivity.class); startActivity(i); // Not shown: i.putExtra(...) } else { DetailFragment frag = (ContentFragment) getFragmentManager() .findFragmentById(R.id.detail_fragment); frag.updateContent(category, pos); } }
  • 66. Multi-Pane> Special Features > Transaktionssteuerung via FragmentTransaction > insert(), replace(), delete() via FragmentManager > addToBackStack() erlaubt Verwaltung > Back-Stack erlaubt Navigation via „Back-Button“
  • 67. Multi-Pane> Special Features // Using Fragments and FragmentTransactions Fragment newFragment = new ExampleFragment(); FragmentTransaction transaction = getFragmentManager().beginTransaction(); // Replace, and add the transaction to the back stack transaction.replace(R.id.fragment, newFragment); transaction.addToBackStack(null); // Commit the transaction transaction.commit();
  • 68. Multi-Pane> Design Pattern
  • 69. Multi-Pane> Design Pattern
  • 70. Multi-Pane> Show/Hide
  • 71. Multi-Pane> Expand/Collaps
  • 72. Multi-Pane > ScretchMulti-Pane
  • 73. Multi-Pane > Stack
  • 74. Notifications
  • 75. Notifications> Rich Notification
  • 76. Notifications> Rich Notification
  • 77. Notifications> Self-Made UI für Notifications> Rich Content und Controls> RemoteViews als Mittel zum Zweck> Nicht wirklich neu aber ...> ... einfacher dank Notification.Builder
  • 78. Notifications> How to? // Create rich notification via Notification.Builder Notification.Builder b = new Notification.Builder(this) .setSmallIcon(R.drawable.ic_notify) .setAutoCancel(true) .setTicker(getString(R.string.notify_ticker_text)); .setContentIntent(...); // some Pending Intent RemoteViews layout = new RemoteViews(getPackageName(), R.layout.notification); layout.setTextViewText(... , ...); // some key(s)/text(s) b.setContent(layout); b.setLargeIcon(largeIcon); notificationManager.notify(NOTIFICATION_DEFAULT, b.getNotification());
  • 79. Drag & Drop
  • 80. Drag & Drop> in Action
  • 81. Drag & Drop> in Action
  • 82. Drag & Drop> in Action
  • 83. Drag & Drop> Drag ... (Text, Intent, Uri) // Drag ... (in OverviewFragment) listVew.setOnItemLongClickListener( new OnItemLongClickListener() { public boolean onItemLongClick(AdapterView<?> av, View v, int pos, long id) { final String title = (String) ((TextView) v).getText(); // Set up clip data with text, intent or uri. final String textdata = String.format("%d||%d", mCategory, pos); ClipData data = ClipData.newPlainText(title, textData); v.startDrag(data, new MyDragShadowBuilder(v), null, 0); return true; } });
  • 84. Drag & Drop> Listener // ... and Drop (in DetailFragment | onCreateView ) mContentView.setOnDragListener(new View.OnDragListener() { public boolean onDrag(View view, DragEvent event) { switch (event.getAction()) { case DragEvent.ACTION_DRAG_ENTERED: ... break; case DragEvent.ACTION_DRAG_EXITED: ... break; case DragEvent.ACTION_DRAG_STARTED: return processDragStarted(event); case DragEvent.ACTION_DROP: return processDrop(event, imageView); } return false; } });
  • 85. Drag & Drop> Drag ... // ... and Drop (in DetailFragment | processDragStarted ) boolean processDragStarted(DragEvent event) { // Determine whether to continue processing // drag and drop based on the plain text mime type. ClipDescription cd = event.getClipDescription(); if (cd != null) { return cd.hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN); } return false; }
  • 86. Drag & Drop> ... and Drop // ... and Drop (in DetailFragment | processDrop) boolean processDrop(DragEvent event, ImageView iv) { // parse clip data: category||entry_id. ClipData data = event.getClipData(); Item item = data.getItemAt(0); String textData = (String) item.getText(); ... int category = ... ; int entryId = ...; updateContent(category, entryId); // Update list fragment with selected entry. OverviewFragment overviewFragment = (OverviewFragment) getFragmentManager().findFragmentById(...); ... }
  • 87. Demo
  • 88. Sharing Widget
  • 89. Sharing> Einfache Integration von Data Share > zwischen Apps > via ShareActionProvider (extends ActionProvider) > in ActionBar der UI> Eigentliche Arbeit macht das System > Liste möglicher „Share Intent Candidates“ > Intent Dispatching nach Auswahl der App
  • 90. Sharing
  • 91. Sharing> Share Action Provider ... // Step 1: Declare menu item <menu xmlns:android="..."> <item android:id="@+id/menu_item_share"        android:showAsAction="ifRoom"        android:title="Share"        android:actionProviderClass= "android.widget.ShareActionProvider" />    ... </menu>
  • 92. Sharing> ... in ... // Step 2: Define Share Intent, e.g. for binary data Intent shareIntent = new Intent(); shareIntent.setAction(Intent.ACTION_SEND); shareIntent.putExtra(Intent.EXTRA_STREAM, uriToImage); shareIntent.setType("image/jpeg");
  • 93. Sharing> ... Action // Step 3: Say what to share private ShareActionProvider mShareActionProvider; ... // access/set ShareActionProvider onCreateOptionsMenu // via menuItem.getShareActionProvider() ... // set shareIntent for the provider private void setShareIntent(Intent shareIntent) { if (mShareActionProvider != null) {        mShareActionProvider.setShareIntent(shareIntent);    } }
  • 94. Demo
  • 95. ANDROID 4UI Design @mobileLarson @_openKnowledge Lars Röwekamp | CIO New Technologies