SlideShare une entreprise Scribd logo
1  sur  15
Télécharger pour lire hors ligne
Jak zabít několik much
jednou ranou přechodem
na Fragmenty
+David Vávra pro GUG ČVUT
Dlužníček
●   Společné výdaje, 50k+ stažení
●   mouchy:
     ○ na tabletech roztažené
     ○ není úplně podle Android
        Design guidelines
         ■ dashboard screen
         ■ Nová platba a Kdo má
            platit jsou akce
     ○ Swipe mezi skupinami
     ○ rotace obrazovky => android:
        configChanges="orientation"
    ○   jinak AsyncTasky leaknou
        aktivitu
    ○   nepoužívají se observery na
        data
    ○   View not attached to window
        manager Exception
    ○   mohlo by být rychlejší
Co s tím? Fragmenty!
●   nové API Android 3.0 Honeycomb (+ Compatibility Library)
●   znovupoužitelné UI komponenty
●   http://developer.android.com/guide/components/fragments.html
Příklad z dokumentace
layout-sw600dp-land/fragment_layout.xml          layout/fragment_layout.xml
<LinearLayout xmlns:android ="http://schemas.    <FrameLayout xmlns:android ="http://schemas.
android.com/apk/res/android"                     android.com/apk/res/android"
    android:orientation ="horizontal"                android:layout_width ="match_parent"
    android:layout_width ="match_parent"         android:layout_height ="match_parent" >
android:layout_height ="match_parent" >              <fragment class="com.example.android.
                                                 apis.app.FragmentLayout$TitlesFragment"
    <fragment class="com.example.android.                    android:id ="@+id/titles"
apis.app.FragmentLayout$TitlesFragment"                      android:layout_width ="
            android:id ="@+id/titles" android:   match_parent" android:layout_height ="
layout_weight ="1"                               match_parent" />
            android:layout_width ="0px"          </FrameLayout>
android:layout_height ="match_parent" />
                                                 TitlesActity:
    <FrameLayout android:id ="@+id/details"
android:layout_weight ="1"
                                                 @Override
            android:layout_width ="0px"
                                                 protected void onCreate (Bundle
android:layout_height ="match_parent"
                                                 savedInstanceState ) {
            android:background ="?android:
                                                     super.onCreate (savedInstanceState );
attr/detailsElementBackground" />
                                                    setContentView (R.layout.fragment_layout );
                                                 }
</LinearLayout>
TitlesFragment
public static class TitlesFragment extends ListFragment {
    boolean mDualPane ;
    @Override
    public void onActivityCreated (Bundle savedInstanceState ) {
        setListAdapter (new ArrayAdapter <String>(getActivity (),
                android .R.layout.simple_list_item_activated_1 , Shakespeare .TITLES));
        View detailsFrame = getActivity ().findViewById (R.id.details);
        mDualPane = detailsFrame != null && detailsFrame .getVisibility () == View.VISIBLE;
    }

    @Override
    public void onListItemClick (ListView l, View v, int position , long id) {
        if (mDualPane ) {
            DetailsFragment details = DetailsFragment .newInstance (position );
            getFragmentManager ().beginTransaction ().replace(R.id.details, details ).commit();
        } else {
            Intent intent = new Intent();
            intent .setClass (getActivity (), DetailsActivity .class);
            intent .putExtra ("index", index);
            startActivity (intent);
        }
    }
}
DetailsFragment
public static class DetailsFragment extends Fragment {

    public static DetailsFragment newInstance (int index) {
        DetailsFragment f = new DetailsFragment ();

        Bundle args = new Bundle();
        args .putInt("index", index);
        f .setArguments (args);

        return f;
    }

    public int getShownIndex () {
        return getArguments ().getInt("index", 0);
    }

    @Override
    public View onCreateView (LayoutInflater inflater , ViewGroup container ,
             Bundle savedInstanceState ) {
        ScrollView scroller = new ScrollView (getActivity ());
        TextView text = new TextView (getActivity ());
        scroller .addView(text);
        text .setText(Shakespeare .DIALOGUE [getShownIndex ()]);
        return scroller ;
    }
}
DetailsActivity
public static class DetailsActivity extends Activity {

    @Override
    protected void onCreate (Bundle savedInstanceState ) {
        super.onCreate (savedInstanceState );

        if (getResources ().getConfiguration ().orientation
                 == Configuration .ORIENTATION_LANDSCAPE ) {
            finish ();
            return;
        }
        DetailsFragment details = new DetailsFragment ();
        details .setArguments (getIntent ().getExtras ());
        getFragmentManager ().beginTransaction ().add(android.R.id.content, details ).commit();
    }
}
Zásek #1: PaymentsActivity
Zásek #1:
PaymentDetailActivity
Zásek #1: řešení
●   Jedna aktivita
     ○ hacky ActionBaru
     ○ rotace, rotace, rotace a zachování stavu
     ○ tlačítko back
         ■ addToBackStack - buggy = Fragmenty přes sebe
         ■ ale pak nejde použít setRetainInstance(true) => problémy s
             AsyncTasky a savedIntanceState
●   Dvě aktivity
     ○ ActionBar definovaný v aktivitě handling ve fragmentu
     ○ je jasné co bude po rotaci = stejná aktivita
     ○ back funguje out of the box
     ○ setRetainInstance(true) funguje krásně
     ○ bez hacků
     ○ animaci mezi aktivitami jde vypnout
Zásek #2: AsyncTasky a
observery
public class SettleUpFragment extends SherlockFragment   protected void registerObserver(Uri uri) {
{                                                                     this.uriToObserve = uri;
       protected SettleUpActivity c;                                  // TODO: multiple observers
       private Uri uriToObserve = null;                  c.getContentResolver().registerContentObserver(uri,
       private AsyncTask<Void, Void, Void>               true, observer);
fillDataTask;                                                   }
       private NewAsyncTaskCallback
newAsyncTaskCallback;                                           protected void loadData(NewAsyncTaskCallback
       @Override                                         callback) {
       public void onAttach(Activity activity) {                       this.newAsyncTaskCallback = callback;
              super.onAttach(activity);                                this.fillDataTask = callback.
              c = (SettleUpActivity) activity;           onCreateAsyncTask();
       }                                                               fillDataTask.execute();
       @Override                                                }
       public void onDetach() {
              super.onDetach();                                 ContentObserver observer = new ContentObserver
              if (fillDataTask != null) {                (null) {
                     fillDataTask.cancel(true);                        @Override
              }                                                        public void onChange(boolean selfChange) {
       }                                                                      if (fillDataTask != null && !
       @Override                                         fillDataTask.isCancelled()) {
       public void onDestroyView() {                                          SettleUpFragment.this.fillDataTask
              if (uriToObserve != null) {       c.       = newAsyncTaskCallback.onCreateAsyncTask();
getContentResolver().unregisterContentObserver                                       fillDataTask.execute();
(observer);                                                                   }
              }                                                        }
              if (fillDataTask != null) {                       };
                     fillDataTask.cancel(true);
              }                                                 public interface NewAsyncTaskCallback {
              super.onDestroyView();                                   AsyncTask<Void, Void, Void>
       }                                                 onCreateAsyncTask();
                                                                }
                                                         }
Zásek #3: ViewPager & taby
●   aplikace nepočítala s více skupinami
●   invalidace ViewPageru:
     ○ uiViewPagerIndicator.invalidate()
     ○ při změně tabu:
uiViewPager.getAdapter().
notifyDataSetChanged();

@Override
public int getItemPosition(Object object) {
   return POSITION_NONE;
}
●   handling ActionBaru z aktuálního
    ViewPager fragmentu:
SettleUpFragment fragment = (SettleUpFragment)
uiViewPager.getAdapter().instantiateItem
(uiViewPager,           uiViewPager.
getCurrentItem());
              if (fragment != null) {
                   return fragment.
onOptionsItemSelected(item);
              }
Zásek #4:
PreferenceFragment
●   Není v Compatibility library
●   Tutoriál: http://developer.android.com/guide/topics/ui/settings.html#BackCompatHeaders
     ○ Android >3.0 preference-headers
     ○ Android <3.0 PreferenceScreen s Intenty
●   Co když je potřeba přidat listenery atd?
     ○ samostatná třída co je inicializovaná z Activity nebo Fragmentu
Shrnutí
●   Zabité mouchy:
     ○ na tabletech vypadá dobře
     ○ podle Android Design Guidelines
     ○ rotace obrazovky, pamatování stavu + AsyncTasky bez problémů
     ○ aplikace svižnější
     ○ donutilo mě to k používání observerů a ORM
     ○ víc zapouzdřených komponent = v Aktivitě minimum kódu
●   Ale:
     ○ velký refaktoring celé aplikace
     ○ záseky kde i StackOverflow drhne (snad jich po dnešku bude míň)
●   Takže:
     ○ pro nové aplikace určitě, pro existující zvážit
     ○ šance jak se prosadit v davu aplikací - HoloEverywhere.com atd.
         ■ Aplikace Tasks - za 3 měsíce 100k stažení placené verze
Dotazy?




●   David Vávra
     ○ http://gplus.to/destil
     ○ @destil
     ○ Dlužníček: http://www.settleup.info

Contenu connexe

Tendances

Assalamualaykum warahmatullahi wabarakatuu
Assalamualaykum warahmatullahi wabarakatuuAssalamualaykum warahmatullahi wabarakatuu
Assalamualaykum warahmatullahi wabarakatuuiswan_di
 
Android Fast Track CRUD Android PHP MySql
Android Fast Track CRUD Android PHP MySqlAndroid Fast Track CRUD Android PHP MySql
Android Fast Track CRUD Android PHP MySqlAgus Haryanto
 
聞いてスッキリ!Lightningの理解ポイント
聞いてスッキリ!Lightningの理解ポイント聞いてスッキリ!Lightningの理解ポイント
聞いてスッキリ!Lightningの理解ポイント寛 吉田
 
RxSwift 예제로 감잡기
RxSwift 예제로 감잡기RxSwift 예제로 감잡기
RxSwift 예제로 감잡기Yongha Yoo
 
Юнит тестирование в Zend Framework 2.0
Юнит тестирование в Zend Framework 2.0Юнит тестирование в Zend Framework 2.0
Юнит тестирование в Zend Framework 2.0zfconfua
 
RxJava, Getting Started - David Wursteisen - 16 Octobre 2014
RxJava, Getting Started - David Wursteisen - 16 Octobre 2014RxJava, Getting Started - David Wursteisen - 16 Octobre 2014
RxJava, Getting Started - David Wursteisen - 16 Octobre 2014SOAT
 
Юнит тестирование в Zend Framework 2.0
Юнит тестирование в Zend Framework 2.0Юнит тестирование в Zend Framework 2.0
Юнит тестирование в Zend Framework 2.0zfconfua
 
Palestra PythonBrasil[8]
Palestra PythonBrasil[8]Palestra PythonBrasil[8]
Palestra PythonBrasil[8]Thiago Da Silva
 
Hacer una calculadora en Java y en Visual Basic
Hacer una calculadora en Java y en Visual BasicHacer una calculadora en Java y en Visual Basic
Hacer una calculadora en Java y en Visual BasicHumbertoWuwu
 
Como hacer una calculadora en java
Como hacer una calculadora en javaComo hacer una calculadora en java
Como hacer una calculadora en javaaldair fernandez
 
Java AWT Calculadora
Java AWT CalculadoraJava AWT Calculadora
Java AWT Calculadorajubacalo
 
Skaters and BMXers from all over the U.S. descend on Grant Park
Skaters and BMXers from all over the U.S. descend on Grant ParkSkaters and BMXers from all over the U.S. descend on Grant Park
Skaters and BMXers from all over the U.S. descend on Grant Parkchicagonewsyesterday
 
SSP - The Simple Singleton Pattern
SSP - The Simple Singleton PatternSSP - The Simple Singleton Pattern
SSP - The Simple Singleton PatternRodolfo Dias
 

Tendances (19)

Assalamualaykum warahmatullahi wabarakatuu
Assalamualaykum warahmatullahi wabarakatuuAssalamualaykum warahmatullahi wabarakatuu
Assalamualaykum warahmatullahi wabarakatuu
 
Dwr实战
Dwr实战Dwr实战
Dwr实战
 
1- Sourcecode Array
1- Sourcecode Array1- Sourcecode Array
1- Sourcecode Array
 
Android Fast Track CRUD Android PHP MySql
Android Fast Track CRUD Android PHP MySqlAndroid Fast Track CRUD Android PHP MySql
Android Fast Track CRUD Android PHP MySql
 
聞いてスッキリ!Lightningの理解ポイント
聞いてスッキリ!Lightningの理解ポイント聞いてスッキリ!Lightningの理解ポイント
聞いてスッキリ!Lightningの理解ポイント
 
RxSwift 예제로 감잡기
RxSwift 예제로 감잡기RxSwift 예제로 감잡기
RxSwift 예제로 감잡기
 
Юнит тестирование в Zend Framework 2.0
Юнит тестирование в Zend Framework 2.0Юнит тестирование в Zend Framework 2.0
Юнит тестирование в Zend Framework 2.0
 
RxJava, Getting Started - David Wursteisen - 16 Octobre 2014
RxJava, Getting Started - David Wursteisen - 16 Octobre 2014RxJava, Getting Started - David Wursteisen - 16 Octobre 2014
RxJava, Getting Started - David Wursteisen - 16 Octobre 2014
 
Blog 3
Blog 3Blog 3
Blog 3
 
Юнит тестирование в Zend Framework 2.0
Юнит тестирование в Zend Framework 2.0Юнит тестирование в Zend Framework 2.0
Юнит тестирование в Zend Framework 2.0
 
Get more votes!
Get more votes!Get more votes!
Get more votes!
 
Palestra PythonBrasil[8]
Palestra PythonBrasil[8]Palestra PythonBrasil[8]
Palestra PythonBrasil[8]
 
Sis quiz
Sis quizSis quiz
Sis quiz
 
Hacer una calculadora en Java y en Visual Basic
Hacer una calculadora en Java y en Visual BasicHacer una calculadora en Java y en Visual Basic
Hacer una calculadora en Java y en Visual Basic
 
Testování prakticky
Testování praktickyTestování prakticky
Testování prakticky
 
Como hacer una calculadora en java
Como hacer una calculadora en javaComo hacer una calculadora en java
Como hacer una calculadora en java
 
Java AWT Calculadora
Java AWT CalculadoraJava AWT Calculadora
Java AWT Calculadora
 
Skaters and BMXers from all over the U.S. descend on Grant Park
Skaters and BMXers from all over the U.S. descend on Grant ParkSkaters and BMXers from all over the U.S. descend on Grant Park
Skaters and BMXers from all over the U.S. descend on Grant Park
 
SSP - The Simple Singleton Pattern
SSP - The Simple Singleton PatternSSP - The Simple Singleton Pattern
SSP - The Simple Singleton Pattern
 

Plus de David Vávra

Development for Google Glass using Android GDK
Development for Google Glass using Android GDKDevelopment for Google Glass using Android GDK
Development for Google Glass using Android GDKDavid Vávra
 
Životní cyklus indie aplikace (eClub)
Životní cyklus indie aplikace (eClub)Životní cyklus indie aplikace (eClub)
Životní cyklus indie aplikace (eClub)David Vávra
 
Vydáním mobilní aplikace vše teprve začíná
Vydáním mobilní aplikace vše teprve začínáVydáním mobilní aplikace vše teprve začíná
Vydáním mobilní aplikace vše teprve začínáDavid Vávra
 
Catch & Run velký test
Catch & Run velký testCatch & Run velký test
Catch & Run velký testDavid Vávra
 
Google Analytics Mobile SDK
Google Analytics Mobile SDKGoogle Analytics Mobile SDK
Google Analytics Mobile SDKDavid Vávra
 
Google Maps Challenge
Google Maps ChallengeGoogle Maps Challenge
Google Maps ChallengeDavid Vávra
 
Internship u Google - jaké to bylo a jak se tam dostat + soutěž o ceny
Internship u Google - jaké to bylo a jak se tam dostat + soutěž o cenyInternship u Google - jaké to bylo a jak se tam dostat + soutěž o ceny
Internship u Google - jaké to bylo a jak se tam dostat + soutěž o cenyDavid Vávra
 
Geocaching na ČVUT
Geocaching na ČVUTGeocaching na ČVUT
Geocaching na ČVUTDavid Vávra
 
Czech presentation
Czech presentationCzech presentation
Czech presentationDavid Vávra
 

Plus de David Vávra (9)

Development for Google Glass using Android GDK
Development for Google Glass using Android GDKDevelopment for Google Glass using Android GDK
Development for Google Glass using Android GDK
 
Životní cyklus indie aplikace (eClub)
Životní cyklus indie aplikace (eClub)Životní cyklus indie aplikace (eClub)
Životní cyklus indie aplikace (eClub)
 
Vydáním mobilní aplikace vše teprve začíná
Vydáním mobilní aplikace vše teprve začínáVydáním mobilní aplikace vše teprve začíná
Vydáním mobilní aplikace vše teprve začíná
 
Catch & Run velký test
Catch & Run velký testCatch & Run velký test
Catch & Run velký test
 
Google Analytics Mobile SDK
Google Analytics Mobile SDKGoogle Analytics Mobile SDK
Google Analytics Mobile SDK
 
Google Maps Challenge
Google Maps ChallengeGoogle Maps Challenge
Google Maps Challenge
 
Internship u Google - jaké to bylo a jak se tam dostat + soutěž o ceny
Internship u Google - jaké to bylo a jak se tam dostat + soutěž o cenyInternship u Google - jaké to bylo a jak se tam dostat + soutěž o ceny
Internship u Google - jaké to bylo a jak se tam dostat + soutěž o ceny
 
Geocaching na ČVUT
Geocaching na ČVUTGeocaching na ČVUT
Geocaching na ČVUT
 
Czech presentation
Czech presentationCzech presentation
Czech presentation
 

Jak zabít několik much jednou ranou přechodem na fragmenty

  • 1. Jak zabít několik much jednou ranou přechodem na Fragmenty +David Vávra pro GUG ČVUT
  • 2. Dlužníček ● Společné výdaje, 50k+ stažení ● mouchy: ○ na tabletech roztažené ○ není úplně podle Android Design guidelines ■ dashboard screen ■ Nová platba a Kdo má platit jsou akce ○ Swipe mezi skupinami ○ rotace obrazovky => android: configChanges="orientation" ○ jinak AsyncTasky leaknou aktivitu ○ nepoužívají se observery na data ○ View not attached to window manager Exception ○ mohlo by být rychlejší
  • 3. Co s tím? Fragmenty! ● nové API Android 3.0 Honeycomb (+ Compatibility Library) ● znovupoužitelné UI komponenty ● http://developer.android.com/guide/components/fragments.html
  • 4. Příklad z dokumentace layout-sw600dp-land/fragment_layout.xml layout/fragment_layout.xml <LinearLayout xmlns:android ="http://schemas. <FrameLayout xmlns:android ="http://schemas. android.com/apk/res/android" android.com/apk/res/android" android:orientation ="horizontal" android:layout_width ="match_parent" android:layout_width ="match_parent" android:layout_height ="match_parent" > android:layout_height ="match_parent" > <fragment class="com.example.android. apis.app.FragmentLayout$TitlesFragment" <fragment class="com.example.android. android:id ="@+id/titles" apis.app.FragmentLayout$TitlesFragment" android:layout_width =" android:id ="@+id/titles" android: match_parent" android:layout_height =" layout_weight ="1" match_parent" /> android:layout_width ="0px" </FrameLayout> android:layout_height ="match_parent" /> TitlesActity: <FrameLayout android:id ="@+id/details" android:layout_weight ="1" @Override android:layout_width ="0px" protected void onCreate (Bundle android:layout_height ="match_parent" savedInstanceState ) { android:background ="?android: super.onCreate (savedInstanceState ); attr/detailsElementBackground" /> setContentView (R.layout.fragment_layout ); } </LinearLayout>
  • 5. TitlesFragment public static class TitlesFragment extends ListFragment { boolean mDualPane ; @Override public void onActivityCreated (Bundle savedInstanceState ) { setListAdapter (new ArrayAdapter <String>(getActivity (), android .R.layout.simple_list_item_activated_1 , Shakespeare .TITLES)); View detailsFrame = getActivity ().findViewById (R.id.details); mDualPane = detailsFrame != null && detailsFrame .getVisibility () == View.VISIBLE; } @Override public void onListItemClick (ListView l, View v, int position , long id) { if (mDualPane ) { DetailsFragment details = DetailsFragment .newInstance (position ); getFragmentManager ().beginTransaction ().replace(R.id.details, details ).commit(); } else { Intent intent = new Intent(); intent .setClass (getActivity (), DetailsActivity .class); intent .putExtra ("index", index); startActivity (intent); } } }
  • 6. DetailsFragment public static class DetailsFragment extends Fragment { public static DetailsFragment newInstance (int index) { DetailsFragment f = new DetailsFragment (); Bundle args = new Bundle(); args .putInt("index", index); f .setArguments (args); return f; } public int getShownIndex () { return getArguments ().getInt("index", 0); } @Override public View onCreateView (LayoutInflater inflater , ViewGroup container , Bundle savedInstanceState ) { ScrollView scroller = new ScrollView (getActivity ()); TextView text = new TextView (getActivity ()); scroller .addView(text); text .setText(Shakespeare .DIALOGUE [getShownIndex ()]); return scroller ; } }
  • 7. DetailsActivity public static class DetailsActivity extends Activity { @Override protected void onCreate (Bundle savedInstanceState ) { super.onCreate (savedInstanceState ); if (getResources ().getConfiguration ().orientation == Configuration .ORIENTATION_LANDSCAPE ) { finish (); return; } DetailsFragment details = new DetailsFragment (); details .setArguments (getIntent ().getExtras ()); getFragmentManager ().beginTransaction ().add(android.R.id.content, details ).commit(); } }
  • 10. Zásek #1: řešení ● Jedna aktivita ○ hacky ActionBaru ○ rotace, rotace, rotace a zachování stavu ○ tlačítko back ■ addToBackStack - buggy = Fragmenty přes sebe ■ ale pak nejde použít setRetainInstance(true) => problémy s AsyncTasky a savedIntanceState ● Dvě aktivity ○ ActionBar definovaný v aktivitě handling ve fragmentu ○ je jasné co bude po rotaci = stejná aktivita ○ back funguje out of the box ○ setRetainInstance(true) funguje krásně ○ bez hacků ○ animaci mezi aktivitami jde vypnout
  • 11. Zásek #2: AsyncTasky a observery public class SettleUpFragment extends SherlockFragment protected void registerObserver(Uri uri) { { this.uriToObserve = uri; protected SettleUpActivity c; // TODO: multiple observers private Uri uriToObserve = null; c.getContentResolver().registerContentObserver(uri, private AsyncTask<Void, Void, Void> true, observer); fillDataTask; } private NewAsyncTaskCallback newAsyncTaskCallback; protected void loadData(NewAsyncTaskCallback @Override callback) { public void onAttach(Activity activity) { this.newAsyncTaskCallback = callback; super.onAttach(activity); this.fillDataTask = callback. c = (SettleUpActivity) activity; onCreateAsyncTask(); } fillDataTask.execute(); @Override } public void onDetach() { super.onDetach(); ContentObserver observer = new ContentObserver if (fillDataTask != null) { (null) { fillDataTask.cancel(true); @Override } public void onChange(boolean selfChange) { } if (fillDataTask != null && ! @Override fillDataTask.isCancelled()) { public void onDestroyView() { SettleUpFragment.this.fillDataTask if (uriToObserve != null) { c. = newAsyncTaskCallback.onCreateAsyncTask(); getContentResolver().unregisterContentObserver fillDataTask.execute(); (observer); } } } if (fillDataTask != null) { }; fillDataTask.cancel(true); } public interface NewAsyncTaskCallback { super.onDestroyView(); AsyncTask<Void, Void, Void> } onCreateAsyncTask(); } }
  • 12. Zásek #3: ViewPager & taby ● aplikace nepočítala s více skupinami ● invalidace ViewPageru: ○ uiViewPagerIndicator.invalidate() ○ při změně tabu: uiViewPager.getAdapter(). notifyDataSetChanged(); @Override public int getItemPosition(Object object) { return POSITION_NONE; } ● handling ActionBaru z aktuálního ViewPager fragmentu: SettleUpFragment fragment = (SettleUpFragment) uiViewPager.getAdapter().instantiateItem (uiViewPager, uiViewPager. getCurrentItem()); if (fragment != null) { return fragment. onOptionsItemSelected(item); }
  • 13. Zásek #4: PreferenceFragment ● Není v Compatibility library ● Tutoriál: http://developer.android.com/guide/topics/ui/settings.html#BackCompatHeaders ○ Android >3.0 preference-headers ○ Android <3.0 PreferenceScreen s Intenty ● Co když je potřeba přidat listenery atd? ○ samostatná třída co je inicializovaná z Activity nebo Fragmentu
  • 14. Shrnutí ● Zabité mouchy: ○ na tabletech vypadá dobře ○ podle Android Design Guidelines ○ rotace obrazovky, pamatování stavu + AsyncTasky bez problémů ○ aplikace svižnější ○ donutilo mě to k používání observerů a ORM ○ víc zapouzdřených komponent = v Aktivitě minimum kódu ● Ale: ○ velký refaktoring celé aplikace ○ záseky kde i StackOverflow drhne (snad jich po dnešku bude míň) ● Takže: ○ pro nové aplikace určitě, pro existující zvážit ○ šance jak se prosadit v davu aplikací - HoloEverywhere.com atd. ■ Aplikace Tasks - za 3 měsíce 100k stažení placené verze
  • 15. Dotazy? ● David Vávra ○ http://gplus.to/destil ○ @destil ○ Dlužníček: http://www.settleup.info