+ All Categories
Home > Technology > Jak zabít několik much jednou ranou přechodem na fragmenty

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

Date post: 22-May-2015
Category:
Upload: david-vavra
View: 665 times
Download: 2 times
Share this document with a friend
Description:
Přednáška pro aDevMeetup na ČVUT
15
Jak zabít několik much jednou ranou přechodem na Fragmenty +David Vávra pro GUG ČVUT
Transcript
Page 1: Jak zabít několik much jednou ranou přechodem na fragmenty

Jak zabít několik much jednou ranou přechodem na Fragmenty+David Vávra pro GUG ČVUT

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

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ší

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

● nové API Android 3.0 Honeycomb (+ Compatibility Library)● znovupoužitelné UI komponenty● http://developer.android.com/guide/components/fragments.html

Co s tím? Fragmenty!

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

Příklad z dokumentace layout-sw600dp-land/fragment_layout.xml

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

<fragment class="com.example.android.apis.app.FragmentLayout$TitlesFragment" android:id="@+id/titles" android:layout_weight="1" android:layout_width ="0px" android:layout_height ="match_parent" />

<FrameLayout android:id="@+id/details" android:layout_weight ="1" android:layout_width ="0px" android:layout_height ="match_parent" android:background ="?android:attr/detailsElementBackground" />

</LinearLayout>

layout/fragment_layout.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width ="match_parent" android:layout_height ="match_parent" > <fragment class="com.example.android.apis.app.FragmentLayout$TitlesFragment" android:id="@+id/titles" android:layout_width ="match_parent" android:layout_height ="match_parent" /></FrameLayout>

TitlesActity:

@Overrideprotected void onCreate(Bundle savedInstanceState ) { super.onCreate(savedInstanceState ); setContentView (R.layout.fragment_layout );}

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

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

TitlesFragment

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

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; }}

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

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

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

Zásek #1: PaymentsActivity

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

Zásek #1: PaymentDetailActivity

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

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

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

Zásek #2: AsyncTasky a observerypublic class SettleUpFragment extends SherlockFragment {

protected SettleUpActivity c;private Uri uriToObserve = null;private AsyncTask<Void, Void, Void>

fillDataTask;private NewAsyncTaskCallback

newAsyncTaskCallback;@Overridepublic void onAttach(Activity activity) {

super.onAttach(activity);c = (SettleUpActivity) activity;

}@Overridepublic void onDetach() {

super.onDetach();if (fillDataTask != null) {

fillDataTask.cancel(true);}

}@Overridepublic void onDestroyView() {

if (uriToObserve != null) { c.getContentResolver().unregisterContentObserver(observer);

}if (fillDataTask != null) {

fillDataTask.cancel(true);}super.onDestroyView();

}

protected void registerObserver(Uri uri) {this.uriToObserve = uri;// TODO: multiple observers

c.getContentResolver().registerContentObserver(uri, true, observer);

}

protected void loadData(NewAsyncTaskCallback callback) {

this.newAsyncTaskCallback = callback;this.fillDataTask = callback.

onCreateAsyncTask();fillDataTask.execute();

}

ContentObserver observer = new ContentObserver(null) {

@Overridepublic void onChange(boolean selfChange) {

if (fillDataTask != null && !fillDataTask.isCancelled()) {

SettleUpFragment.this.fillDataTask = newAsyncTaskCallback.onCreateAsyncTask();

fillDataTask.execute();}

}};

public interface NewAsyncTaskCallback {AsyncTask<Void, Void, Void>

onCreateAsyncTask();}

}

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

● 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 #3: ViewPager & taby

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

● 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

Zásek #4: PreferenceFragment

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

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

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

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

Dotazy?


Recommended