Top Banner
Android UIs für alle(s) Konzepte für die adaptive UI-Entwicklung Andreas Hölzl Canoo Engineering AG Thursday, March 14, 13
69

MTC13 Android UIs für alle(s)

Jan 27, 2015

Download

Technology

Andreas Hölzl

Slide to my MobileTechCon 2013 talk in Munich on Android multi-screen support, see http://nextlevelandroid.com/?p=252
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: MTC13 Android UIs für alle(s)

Android UIs für alle(s)Konzepte für die adaptive UI-Entwicklung

Andreas HölzlCanoo Engineering AG

Thursday, March 14, 13

Page 2: MTC13 Android UIs für alle(s)

Agenda

๏ Grundlagen‣ Auflösungsunabhängigkeit‣ Multi-Screen-Support

๏ Fragments‣ phone ∪ tablet

2

๏ Best Practices‣ Design Pattern

๏ Tooling‣ ADK, Eclipse

๏ Ressourcen

2244 unterschiedliche Geräte - 1 Code-Basis

Ziel: Alles Wichtige in 1h, sonst ...

Thursday, March 14, 13

Page 3: MTC13 Android UIs für alle(s)

Wer bin ich?

3

@andywoodly

Thursday, March 14, 13

Page 4: MTC13 Android UIs für alle(s)

Fragmentierung ... Differenzierung ...

4

Eric Schmidt, CES 2012:“Differentiation is positive, fragmentation is negative.”

Thursday, March 14, 13

Page 5: MTC13 Android UIs für alle(s)

Fragmentierung ... Differenzierung ...

5

http://www.forbes.com/sites/limyunghui/2012/03/27/android-fragmentation-and-condoms/

Thursday, March 14, 13

Page 6: MTC13 Android UIs für alle(s)

Auflösungsunabhängigkeit

Thursday, March 14, 13

Page 7: MTC13 Android UIs für alle(s)

Auflösungsabhängigkeit

7

low density medium density high density

low density high density

Thursday, March 14, 13

Page 8: MTC13 Android UIs für alle(s)

Auflösungs un abhängigkeit

8

low density high density

low density medium density high density

Thursday, March 14, 13

Page 9: MTC13 Android UIs für alle(s)

Auflösungs un abhängigkeit

9

Bei Grössenangaben immer dp verwenden!

px dp

๏ Ursache der Abhängigkeit: px

๏ Lösung: dp / sp (devices independent pixel)

... sp für Textgrössen

Thursday, March 14, 13

Page 10: MTC13 Android UIs für alle(s)

๏ [l|m|h|xh]dpi - generalized densities

Auflösungsklassen

10

~120dpi ~160dpi ~240dpi ~320dpi

Auflösung (dpi)

Auflösungsklasse

100 200 300

ldpi mdpi hdpi xhdpi

tvdpi xxhdpi

Thursday, March 14, 13

Page 11: MTC13 Android UIs für alle(s)

Auflösungsklassen

11

๏ Skalierungsfaktoren

xhdpi launcher icon (nexus 10)

48

38

72

96

144

launcher iconpx

3:4:6:8 Verhältnis

Thursday, March 14, 13

Page 12: MTC13 Android UIs für alle(s)

12

Auflösungsklassen

/res/drawable ist nur für XML!

Grafiken immer in Ordner mit

Auflösungs-Klassifizierer verwalten

๏ Projekt-Ressourcen

drawable-120dpi

drawable-160dpi

drawable-240dpi

drawable-320dpi

drawable-480dpi

?

Thursday, March 14, 13

Page 13: MTC13 Android UIs für alle(s)

Auflösungs un abhängigkeit

13

Resources res = getResources();

DisplayMetrics metrics = res.getDisplayMetrics();

float scale = metrics.density;

px

๏ Problem: px -basierte APIs?

๏ Lösung: DisplayMetrics.density

Thursday, March 14, 13

Page 14: MTC13 Android UIs für alle(s)

14

Auflösungsklassen

๏ Tooling (Eclipse, ADT Plugin 20.0.0+)

Thursday, March 14, 13

Page 15: MTC13 Android UIs für alle(s)

15

Auflösungsklassen

๏ Tooling (Eclipse, ADT Plugin 20.0.0+)

Thursday, March 14, 13

Page 16: MTC13 Android UIs für alle(s)

16

Auflösungsklassen

๏ Tooling (Eclipse, ADT Plugin 20.0.0+)

Thursday, March 14, 13

Page 17: MTC13 Android UIs für alle(s)

17

Auflösungsklassen

๏ Tooling (Android Asset Studio)

Thursday, March 14, 13

Page 18: MTC13 Android UIs für alle(s)

18

Auflösungsklassen

๏ Lint

http://tools.android.com/tips/lint-checks

Thursday, March 14, 13

Page 19: MTC13 Android UIs für alle(s)

19

Auflösungsklassen

๏ Marktdaten

http://developer.android.com/about/dashboards/index.html

October 1, 2012

Thursday, March 14, 13

Page 20: MTC13 Android UIs für alle(s)

Multi-Screen-Support

Thursday, March 14, 13

Page 21: MTC13 Android UIs für alle(s)

21

http://www.google.de/nexus/

Thursday, March 14, 13

Page 22: MTC13 Android UIs für alle(s)

22

Thursday, March 14, 13

Page 23: MTC13 Android UIs für alle(s)

23

Screen Sizes

Bildschirmgrösse (inch)

Grössenklasse

2 4 7 10

small normal large xlarge

Thursday, March 14, 13

Page 24: MTC13 Android UIs für alle(s)

Multi-Screen-Support

24

Ziel: korrektes Resize-Verhalten

Thursday, March 14, 13

Page 25: MTC13 Android UIs für alle(s)

Multi-Screen-Support

25

<LinearLayout android:id="@+id/linearLayout1" android:layout_height="50dp" android:layout_width="match_parent" android:gravity="center">

<ImageView android:id="@+id/imageView1" android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_weight="0" android:paddingRight="30dp" android:layout_gravity="left" android:src="@drawable/logo" />

<View android:id="@+id/view1" android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_weight="1" />

<Button android:id="@+id/categorybutton" android:background="@drawable/button_bg" android:layout_height="match_parent" android:layout_width="120dp" android:layout_weight="0" />

</LinearLayout>

๏ korrektes Resizing‣ fixe Dimensionsangaben nur

wo sinnvoll‣ match_parent verwenden‣ wrap_content verwenden

Thursday, March 14, 13

Page 26: MTC13 Android UIs für alle(s)

Multi-Screen-Support

26

๏ korrektes Resizing‣ geschachtelte LinearLayout vermeiden‣ RelativeLayout verwenden

LinearLayout (vertical)|- LinearLayout (horizontal)|- LinearLayout (horizontal)

RelativeLayout

Thursday, March 14, 13

Page 27: MTC13 Android UIs für alle(s)

Multi-Screen-Support

27

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent">

<TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:text="Very Long Text" />

<EditText android:id="@+id/editText1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_toRightOf="@+id/textView1" />

<TextView android:id="@+id/textView2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_below="@+id/editText1" android:text="Text" />

<EditText android:id="@+id/editText2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/editText1" >

</EditText>

</RelativeLayout>

๏ RelativeLayout

Thursday, March 14, 13

Page 28: MTC13 Android UIs für alle(s)

28

Skalierbare Grafiken

๏ Nine-Patch Images

http://android-ui-utils.googlecode.com/hg/asset-studio/dist/nine-patches.html

<sdk>/tools/draw9patch

Thursday, March 14, 13

Page 29: MTC13 Android UIs für alle(s)

29

Skalierbare Grafiken

๏ Beispiel Nine-Patch Image - action bar shadow

Versionen für mdpi, hdpi, xhdpi erforderlich

Thursday, March 14, 13

Page 30: MTC13 Android UIs für alle(s)

Multi-Screen-Support

30

Ziel: Screen-optimierte Layouts

small

normal

res/layout/my_layout.xml

res/layout-small/my_layout.xml

Thursday, March 14, 13

Page 31: MTC13 Android UIs für alle(s)

Multi-Screen-Support

31

res/layout/my_layout.xml             // normal screen size ("default")res/layout-small/my_layout.xml       // small screen sizeres/layout-large/my_layout.xml       // large screen sizeres/layout-xlarge/my_layout.xml      // extra large screen sizeres/layout-xlarge-land/my_layout.xml // extra large in landscape orientation

๏ optimierte Ressourcen‣ screen size qualifier (small, normal, large, xlarge)‣ orientation qualifier (port, land)‣ locale, etc. qualifier

@Deprecated

Thursday, March 14, 13

Page 32: MTC13 Android UIs für alle(s)

Multi-Screen-Support

32

๏ optimierte Ressourcen‣ sw<N>dp‣ w<N>dp, h<N>dp

res/layout/main_activity.xml           # smaller than 600dp available widthres/layout-sw600dp/main_activity.xml   # For 7” tablets (600dp wide and bigger)res/layout-sw720dp/main_activity.xml   # For 10” tablets (720dp wide and bigger)

seit 3.2

res/layout/main_activity.xml         # smaller than 600dp available widthres/layout-w600dp/main_activity.xml   # any screen with >=600dp available

Die allermeisten Tablets verwenden >=3.2

res/layout/main_activity.xml           # For phonesres/layout-xlarge/main_activity.xml    # For pre-3.2 tabletsres/layout-sw600dp/main_activity.xml   # For 3.2 and up tablets

Thursday, March 14, 13

Page 33: MTC13 Android UIs für alle(s)

33

Screen Sizes - Smallest Width

320dp 480dp 600dp 720dp

res/layout/main_activity.xml           # For phonesres/layout-sw600dp/main_activity.xml   # For tablet

res/layout-sw720dp/main_activity.xml   # For 10” tablets

res/layout-w600dp/main_activity.xml   # Multi-pane when enough width

Best practice

Thursday, March 14, 13

Page 34: MTC13 Android UIs für alle(s)

34

Multi-Screen-Support - Tooling

Thursday, March 14, 13

Page 35: MTC13 Android UIs für alle(s)

Fragments

A fragment a day

keeps the fragmentation at bay!

Thursday, March 14, 13

Page 36: MTC13 Android UIs für alle(s)

36

Fragments

Thursday, March 14, 13

Page 37: MTC13 Android UIs für alle(s)

37

✔ wiederverwendbare (UI-)Komponente✔ “Sub-Activity”✔ eigener Lifecycle✔ immer an Activity gebunden✔ lose Kopplung

Fragments

Thursday, March 14, 13

Page 38: MTC13 Android UIs für alle(s)

38

Fragments - Anwendungsprinzip

๏ Fragment‣ UI-Komponente

๏ Activity-Layout (XML)‣ verwendet Fragments

๏ Activity-Klasse‣ Inter-Fragment-Logik

๏ XML-Ressourcen‣ “Switch”

Thursday, March 14, 13

Page 39: MTC13 Android UIs für alle(s)

39

Fragments - Resourcen-Switch

res/layout/main.xml

res/layout-w600dp/main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal" >

<fragment android:name="com.example.android.FragmentA" android:layout_width="0dp" android:layout_weight="1" android:layout_height="match_parent" />

<fragment android:name="com.example.android.FragmentB" android:layout_width="0dp" android:layout_weight="2" android:layout_height="match_parent" />

</LinearLayout>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal" >

<fragment android:name="com.example.android.FragmentA" android:layout_width="match_parent" android:layout_height="match_parent" />

</LinearLayout>

Thursday, March 14, 13

Page 40: MTC13 Android UIs für alle(s)

40

Fragments - Anwendung

res/layout/main.xml

res/layout-w600dp/main.xml

Activity A

src/

Activity B

Fragment A

Fragment B

Intent:Activity B

Activity A event

UpdateFragment B

Fragment B sichtbar?

Ja

Nein

Activity AFragment A

Fragment B

Thursday, March 14, 13

Page 41: MTC13 Android UIs für alle(s)

41

Fragments - Implementierung

Activity A

src/

Activity B

Fragment A

Fragment B

Activity AFragment A

Fragment B

@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main);

// find our fragments mFragmentA = (FragmentA) getFragmentManager().findFragmentById(R.id.fragment_a); mFragmentB = (FragmentB) getFragmentManager().findFragmentById(R.id.fragment_b);

// Determine whether we are in single-pane or dual-pane mIsDualPane = mFragmentB != null; }

ActivityA.java

@Override public void onItemSelected(int index) { if (mIsDualPane) { // display it on the article fragment mFragmentB.displayStuff(...); } else { // use separate activity Intent i = new Intent(this, ActivityB.class); i.putExtra("stuff", ...); startActivity(i); } }

Thursday, March 14, 13

Page 42: MTC13 Android UIs für alle(s)

42

Fragments - Implementierung II

Activity A

src/

Activity B

Fragment A

Fragment B

Activity AFragment A

Fragment B

@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); ...

// Determine whether we are in single-pane or dual-pane mIsDualPane = getResources().getBoolean(R.bool.has_two_panes) }

ActivityA.java

Alternativer Layout-Switch

<resources> <bool name="has_two_panes">false</bool></resources>

<resources> <bool name="has_two_panes">true</bool></resources>

res/values/layouts.xml

res/values-w600dp/layouts.xml

Thursday, March 14, 13

Page 43: MTC13 Android UIs für alle(s)

43

Fragments - Implementierung III programmatisch

FragmentTransaction ftx = getFragmentManager().beginTransaction();

DetailFragment fragment = new DetailFragment();ftx.add(R.id.fragment_container, fragment);

ftx.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);ftx.addToBackStack(null); ftx.commit();

add(), remove(), replace(), show(), hide()

kein remove(), replace() auf XML-deklarierten Fragments!

Thursday, March 14, 13

Page 44: MTC13 Android UIs für alle(s)

44

Fragments/Activity - Kommunikation

notify

listen toActivity A Fragment A

๏ Listener Pattern‣ wiederverwertbare Komponenten‣ lose Kopplung

setter

Thursday, March 14, 13

Page 46: MTC13 Android UIs für alle(s)

Fragmentspre 3.0

happy path

Thursday, March 14, 13

Page 48: MTC13 Android UIs für alle(s)

Support Library + Fragments + Map (pre Maps v2)

48

“Maps + Fragments +

Support package =

headache”

http://nextlevelandroid.com/?p=114

public class MapFragment extends LocalActivityManagerFragment { private TabHost mTabHost;

@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.map_fragment, container, false); mTabHost = (TabHost) view.findViewById(android.R.id.tabhost); mTabHost.setup(getLocalActivityManager()); TabSpec tab = mTabHost.newTabSpec("map") .setIndicator("map") .setContent(new Intent(getActivity(), MyMapActivity.class)); mTabHost.addTab(tab); /* * hack!!! * view hierarchy is: * PhomeWindow$DecorView$.../FrameLayout/LinearLayout/MapView * findViewById() does not work directly on tab content view */ mMapView = (MyMapView) mTabHost.getTabContentView().getChildAt(0).findViewById(R.id.mapview); ...

return view; }

public class LocalActivityManagerFragment extends Fragment {

private static final String KEY_STATE_BUNDLE = "localActivityManagerState"; private LocalActivityManager mLocalActivityManager; protected LocalActivityManager getLocalActivityManager() { return mLocalActivityManager; }

...}

Problem: MapView ⇔ MapActivity

Thursday, March 14, 13

Page 49: MTC13 Android UIs für alle(s)

Support Library + MapFragment (Maps v2)

49

<fragment class="com.google.android.gms.maps.SupportMapFragment" android:layout_width="match_parent" android:layout_height="match_parent"/>

Installation über Google Play Services SDK

Google Maps Android API v2

The Google Maps Android API

v2 Utopiahttp://android.cyrilmottier.com/?p=855

Thursday, March 14, 13

Page 50: MTC13 Android UIs für alle(s)

Support Library + MapFragment + ActionbarSherlock

50

ActionbarSherlock-Erweiterung notwendig

public class SherlockMapFragment extends SupportMapFragment {}

http://stackoverflow.com/questions/13721929/using-actionbarsherlock-with-the-new-supportmapfragment

Thursday, March 14, 13

Page 51: MTC13 Android UIs für alle(s)

Nested Fragments

๏ seit November 2012, Version 4.2

51

Unterstützt nur programmatische Verwendung von Fragments

Child Fragment: getChildFragmentManager()

Asynchrone Initialisierung notwendig

(Bsp.: Fragment mit ViewPager mit

Fragments)

private class SetAdapterTask extends AsyncTask<Void,Void,Void>{ protected Void doInBackground(Void... params) { return null; }

@Override protected void onPostExecute(Void result) { mViewPager.setAdapter(mPagerAdapter); mViewPager.setCurrentItem(mSelectedTab); mViewPager.setOffscreenPageLimit(3); } }

ViewPagerFragment

Thursday, March 14, 13

Page 52: MTC13 Android UIs für alle(s)

Design Pattern

Thursday, March 14, 13

Page 53: MTC13 Android UIs für alle(s)

53

Design Pattern

Show / HideAusblenden eines Fragments, Rück-Navigation mittels Up-Action.

Thursday, March 14, 13

Page 54: MTC13 Android UIs für alle(s)

54

Design Pattern

Stretch/compressFragments passen sich in der Breite an.

Thursday, March 14, 13

Page 55: MTC13 Android UIs für alle(s)

55

Design Pattern

Expand / CollapseAktive Komponente erhält mehr Platz.

Thursday, March 14, 13

Page 56: MTC13 Android UIs für alle(s)

56

Design Pattern

StackNeuanordnung der Fragments (v.a. bei Orientierungswechsel).

Thursday, March 14, 13

Page 57: MTC13 Android UIs für alle(s)

57

Design Pattern

“Tabs To Columns”Tabs / ViewPages werden nebeneinander dargestellt.

https://code.google.com/p/iosched/

Thursday, March 14, 13

Page 58: MTC13 Android UIs für alle(s)

Tooling

Thursday, March 14, 13

Page 59: MTC13 Android UIs für alle(s)

59

Tooling - Eclipse

Multi-configuration editing

RelativeLayout support, spacing defaults

Asset wizard

New activity wizard

Lint integration

Thursday, March 14, 13

Page 60: MTC13 Android UIs für alle(s)

60

Tooling - Monitor, DDMS (screen snapshot)

$ ./tools/monitor

Hilfreich bei dynamischen Layouts/Fragments

Thursday, March 14, 13

Page 61: MTC13 Android UIs für alle(s)

61

Tooling - Monitor, Hierarchyviewer

$ ./tools/monitor

nur Emulator / developer devices

Thursday, March 14, 13

Page 62: MTC13 Android UIs für alle(s)

Summary

Thursday, March 14, 13

Page 63: MTC13 Android UIs für alle(s)

63

Cheat Sheet

✔ dp Dimensionen

✔ Auflösungsspezifische Bild-Ressourcen

✔ wrap_content, match_parent

✔ RelativeLayout✔ Screen-optimierte Layouts

✔ Wiederverwendung durch Fragments

✔ Tooling Support nutzen - Lint

✔ Design Pattern beachten

✔ an guten Apps orientieren

✔ Dokumentation / Style Guide lesen

Thursday, March 14, 13

Page 64: MTC13 Android UIs für alle(s)

Ressourcen

Thursday, March 14, 13

Page 65: MTC13 Android UIs für alle(s)

65

๏ Official Documentation‣ Android Design Guide

http://developer.android.com/design/index.html

‣ Supporting Multiple Screenshttp://developer.android.com/guide/practices/screens_support.html

‣ New tools for managing screen sizeshttp://android-developers.blogspot.de/2011/07/new-tools-for-managing-screen-sizes.html

‣ Designing for Multiple Screenshttp://developer.android.com/training/multiscreen/index.html

‣ Multi-pane Layoutshttp://developer.android.com/design/patterns/multi-pane-layouts.html

‣ Building a Dynamic UI with Fragmentshttp://developer.android.com/training/basics/fragments/index.html

‣ Android Lint Toolhttp://tools.android.com/tips/linthttp://developer.android.com/tools/help/lint.htmlhttp://developer.android.com/tools/debugging/improving-w-lint.html

Ressourcen I

Thursday, March 14, 13

Page 66: MTC13 Android UIs für alle(s)

66

๏ App Clinichttp://goo.gl/piLXJ

๏ Android Design in Action - Android Developershttp://goo.gl/skOPDhttp://goo.gl/JGB4e

๏ Android Asset Studiohttp://android-ui-utils.googlecode.com/hg/asset-studio/dist/index.html

Ressourcen II

Thursday, March 14, 13

Page 67: MTC13 Android UIs für alle(s)

67

๏ Google I/O‣ Schedule app

https://code.google.com/p/iosched/

‣ What's New in Android Developers' Toolshttp://www.youtube.com/watch?v=Erd2k6EKxCQ

‣ Multi-Versioning Android User Interfaceshttp://www.youtube.com/watch?v=amZM8oZBgfk

‣ Designing and Implementing Android UIs for Phones and Tabletshttp://www.youtube.com/watch?v=WGIU2JX1U5Y

Ressourcen III

Thursday, March 14, 13

Page 68: MTC13 Android UIs für alle(s)

68

๏ Juhani Lehtimäki‣ Smashing Android UI

http://www.androiduipatterns.com/http://eu.wiley.com/WileyCDA/WileyTitle/productCd-1118387287,descCd-buy.html

๏ Others‣ Cyrill Mottier

http://android.cyrilmottier.com

‣ Android 4 - UI Design - Lars Röwekamphttp://www.openknowledge.de/publikationen/vortraege/mtc-2012/android-4-ui-design.html

‣ Flexibles UI-Design - Lars Röwekamphttp://it-republik.de/jaxenter/artikel/Flexibles-UI-Design-4770.html

‣ Deep dive into responsive mobile design - Kirill Grouchnikovhttp://www.pushing-pixels.org/2011/11/08/deep-dive-into-responsive-mobile-design-part-1.html

Ressourcen IV

Thursday, March 14, 13

Page 69: MTC13 Android UIs für alle(s)

69

๏ Apps mit beispielhaftem Design‣ Google I/O 2012

https://code.google.com/p/iosched/

‣ Gmailcom.google.android.gm

‣ TEDcom.ted.android

‣ Evernotecom.evernote

‣ Flipboardflipboard.app

‣ Pulsecom.alphonso.pulse

Ressourcen V

‣ Prixingfr.epicdream.beamy

‣ Pattrnorg.lucasr.pattrn

‣ Glimmrcom.bourke.glimmr

‣ The Vergecom.verge.android

Thursday, March 14, 13