Successfully reported this slideshow.
Your SlideShare is downloading. ×

Android: the Single Activity, Multiple Fragments pattern | One Activity to rule them all

Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Upcoming SlideShare
Flutter
Flutter
Loading in …3
×

Check these out next

1 of 15 Ad

Android: the Single Activity, Multiple Fragments pattern | One Activity to rule them all

Download to read offline

Description: We will discuss the Single Activity, Multiple Fragments architectural pattern, its uses and misuses. We will see what benefits it provides and what kinds of apps can benefit from its provisions. Finally, we will outline an implementation and highlight some features and pitfalls in practice.

Description: We will discuss the Single Activity, Multiple Fragments architectural pattern, its uses and misuses. We will see what benefits it provides and what kinds of apps can benefit from its provisions. Finally, we will outline an implementation and highlight some features and pitfalls in practice.

Advertisement
Advertisement

More Related Content

Slideshows for you (20)

Similar to Android: the Single Activity, Multiple Fragments pattern | One Activity to rule them all (20)

Advertisement

Recently uploaded (20)

Android: the Single Activity, Multiple Fragments pattern | One Activity to rule them all

  1. 1. One Activity to rule them all How to architect a mobile app on the fast & What to avoid to keep it clean
  2. 2. The problem ● Android framework does not impose structure/architecture ● Any sensible application needs some form of a priori architectural thinking/setup ● Creating a heavily outlined and well-thought-out architecture is often overkill for simple apps
  3. 3. Outline ● One screen = one fragment + one layout file ● Activity is used to orchestrate flow between fragments/screens ● Activity also supplies all data needed to the screens, and handles all API to underlying data, network etc. layers
  4. 4. SAMF diagram
  5. 5. Pros & Cons + Quick setup + Modular + Easy to implement views across multiple screens - Can be unwieldy with too many screens - Complex UI flows hard to handle - Dealing with state loss can be messy Use for simple, contained screens without too many animations
  6. 6. // Get the code: https://github.com/olrandir/samf_3aadm // com.olrandir.samf.fragments.HomeFragment public class HomeFragment extends BaseFragment { ... public interface HomeActions { public SamfPerson getStoredPerson(); public void goToProfile(); } } // ============================== // com.olrandir.samf.MainActivity public class MainActivity extends AppCompatActivity implements HomeFragment.HomeActions { .... @Override public SamfPerson getStoredPerson() { return getUser(); } @Override public void goToProfile() { transitionTo(new ProfileFragment()); } } The fragment defnes an interface with thefunctionality it requires The activity implements it
  7. 7. // com.olrandir.samf.fragments.HomeFragment import com.olrandir.samf.models.SamfPerson; public class HomeFragment extends BaseFragment { .... @Override public void onStart(){ super.onStart(); // Initialize our data SamfPerson user = ((HomeActions)getActivity()).getStoredPerson(); String name = getString(R.string.home_text_greeting_nameUnknown); // Fill in fields with initial data, if available if( user != null && !TextUtils.isEmpty(user.getName()) ){ name = user.getName(); } mGreeting.setText( getString(R.string.home_text_greeting).replace("$1", name) ); } }
  8. 8. // com.olrandir.samf.fragments.ProfileFragment public class ProfileFragment extends BaseFragment { .... public interface ProfileActions { public SamfPerson getStoredPerson(); public void setStoredPerson(SamfPerson person); public void goToHome(); } } // ============================== // com.olrandir.samf.MainActivity public class MainActivity extends AppCompatActivity implements ProfileFragment.ProfileActions, HomeFragment.HomeActions { .... @Override public void setStoredPerson(SamfPerson person) { storeUser(person); } @Override public void goToHome() { transitionTo(new HomeFragment()); } } Note the accumulation of “implements” clauses!
  9. 9. Activity views <?xml version="1.0" encoding="utf-8"?> <RelativeLayout ...> <FrameLayout android:id="@+id/mainactivity_content" android:layout_width="match_parent" android:layout_height="match_parent"/> <FloatingActionButton android:id="@+id/activity_button_edit" ... /> </RelativeLayout>
  10. 10. // com.olrandir.samf.MainActivity public class MainActivity extends AppCompatActivity implements ProfileFragment.ProfileActions, HomeFragment.HomeActions { BaseFragment currentScreen; @Override protected void onCreate(Bundle savedInstanceState) { ... // Create first screen if( currentScreen==null ){ currentScreen = new HomeFragment(); } getSupportFragmentManager().beginTransaction() .replace(R.id.mainactivity_content, currentScreen).commit(); // Add a backstack listener getSupportFragmentManager().addOnBackStackChangedListener( new OnBackStackChangedListener() { public void onBackStackChanged() { currentScreen = (BaseFragment) getSupportFragmentManager() .findFragmentById(R.id.mainactivity_content); } } ); } } Get a handle for thecurrent screen fragment
  11. 11. // com.olrandir.samf.MainActivity public class MainActivity extends AppCompatActivity implements ProfileFragment.ProfileActions, HomeFragment.HomeActions, View.OnClickListener { BaseFragment currentScreen; FloatingActionButton editButton; @Override protected void onCreate(Bundle savedInstanceState) { ... // Initialize views belonging to the main activity editButton = (FloatingActionButton) findViewById(R.id.activity_button_edit); editButton.setOnClickListener(this); } @Override public void onClick(View v) { if( currentScreen != null ){ currentScreen.onFABClick(); } } } The activity creates the view, then delegates its interactions to the current fragment
  12. 12. // com.olrandir.samf.fragments.HomeFragment public class HomeFragment extends BaseFragment { ... @Override public void onFABClick() { ((HomeActions)getActivity()).goToProfile(); } } // =========================================== // com.olrandir.samf.fragments.ProfileFragment public class ProfileFragment extends BaseFragment { ... @Override public void onFABClick() { showMessage(“You’re already in the profile!”); } } Different fragments can have different actions for the button
  13. 13. // com.olrandir.samf.fragments.BaseFragment public abstract class BaseFragment extends Fragment { ... public abstract void onFABClick(); } // ======================================== // com.olrandir.samf.fragments.HomeFragment public class HomeFragment extends BaseFragment { ... @Override public void onFABClick() { ((HomeActions)getActivity()).goToProfile(); } } Fragments have interfaces; the activity can defne its API in a parent fragment all screens inherit from
  14. 14. Mitigating If you have many screens, the activity can become unwieldy (many interfaces & functions to implement). Solutions: 1. Use a single interface for all fragments; this allows you to be more specific and careful with your Fragment-Activity API. 2. Break the pattern: use >1 activities, and group similar fragments and 1 activity into flows e.g. LoginActivity with LoginFragment and ForgotPasswordFragment Luckily, it’s relatively easy to achieve this: have all activities extend a parent Activity, implement lower layer APIs there.
  15. 15. Thank you! dimitris@forky.gr | github: olrandir code available: https://github.com/olrandir/samf_3aadm Hungry? Use promo DIMITRIS for 1 free meal, first order only! www.forky.gr

×