Your SlideShare is downloading. ×
  • Like
Jak zabít několik much jednou ranou přechodem na fragmenty
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Now you can save presentations on your phone or tablet

Available for both IPhone and Android

Text the download link to your phone

Standard text messaging rates apply

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

  • 591 views
Published

Přednáška pro aDevMeetup na ČVUT

Přednáška pro aDevMeetup na ČVUT

Published in Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
591
On SlideShare
0
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
1
Comments
0
Likes
0

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. Jak zabít několik muchjednou ranou přechodemna 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 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. 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. 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. 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. Zásek #1: PaymentsActivity
  • 9. Zásek #1:PaymentDetailActivity
  • 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 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. 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. 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