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

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

on

  • 1,014 views

Přednáška pro aDevMeetup na ČVUT

Přednáška pro aDevMeetup na ČVUT

Statistics

Views

Total Views
1,014
Slideshare-icon Views on SlideShare
1,014
Embed Views
0

Actions

Likes
0
Downloads
0
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

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

    • 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 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 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>
    • 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); } }}
    • 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 ; }}
    • 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(); }}
    • 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 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(); } }
    • 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); }
    • 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