Jak zabít několik muchjednou ranou přechodemna 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        D...
Co s tím? Fragmenty!●   nové API Android 3.0 Honeycomb (+ Compatibility Library)●   znovupoužitelné UI komponenty●   http:...
Příklad z dokumentacelayout-sw600dp-land/fragment_layout.xml          layout/fragment_layout.xml<LinearLayout xmlns:androi...
TitlesFragmentpublic static class TitlesFragment extends ListFragment {    boolean mDualPane ;    @Override    public void...
DetailsFragmentpublic static class DetailsFragment extends Fragment {    public static DetailsFragment newInstance (int in...
DetailsActivitypublic static class DetailsActivity extends Activity {    @Override    protected void onCreate (Bundle save...
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 ba...
Zásek #2: AsyncTasky aobserverypublic class SettleUpFragment extends SherlockFragment   protected void registerObserver(Ur...
Zásek #3: ViewPager & taby●   aplikace nepočítala s více skupinami●   invalidace ViewPageru:     ○ uiViewPagerIndicator.in...
Zásek #4:PreferenceFragment●   Není v Compatibility library●   Tutoriál: http://developer.android.com/guide/topics/ui/sett...
Shrnutí●   Zabité mouchy:     ○ na tabletech vypadá dobře     ○ podle Android Design Guidelines     ○ rotace obrazovky, pa...
Dotazy?●   David Vávra     ○ http://gplus.to/destil     ○ @destil     ○ Dlužníček: http://www.settleup.info
Upcoming SlideShare
Loading in...5
×

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

703

Published on

Přednáška pro aDevMeetup na ČVUT

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
703
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
2
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

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

  1. 1. Jak zabít několik muchjednou ranou přechodemna Fragmenty+David Vávra pro GUG ČVUT
  2. 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. 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. 4. Příklad z dokumentacelayout-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 (Bundleandroid:layout_height ="match_parent" savedInstanceState ) { android:background ="?android: super.onCreate (savedInstanceState );attr/detailsElementBackground" /> setContentView (R.layout.fragment_layout ); }</LinearLayout>
  5. 5. TitlesFragmentpublic 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. 6. DetailsFragmentpublic 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. 7. DetailsActivitypublic 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(); }}
  8. 8. Zásek #1: PaymentsActivity
  9. 9. Zásek #1:PaymentDetailActivity
  10. 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. 11. Zásek #2: AsyncTasky aobserverypublic 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 NewAsyncTaskCallbacknewAsyncTaskCallback; 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. 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();@Overridepublic 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. 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. 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. 15. Dotazy?● David Vávra ○ http://gplus.to/destil ○ @destil ○ Dlužníček: http://www.settleup.info
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×