Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
One Activity to rule them all
How to architect a mobile app on the fast
&
What to avoid to keep it clean
The problem
● Android framework does not impose
structure/architecture
● Any sensible application needs some form of a
pri...
Outline
● One screen = one fragment + one layout file
● Activity is used to orchestrate flow between
fragments/screens
● A...
SAMF diagram
Pros & Cons
+ Quick setup
+ Modular
+ Easy to implement views across multiple screens
- Can be unwieldy with too many scre...
// Get the code: https://github.com/olrandir/samf_3aadm
// com.olrandir.samf.fragments.HomeFragment
public class HomeFragm...
// com.olrandir.samf.fragments.HomeFragment
import com.olrandir.samf.models.SamfPerson;
public class HomeFragment extends ...
// com.olrandir.samf.fragments.ProfileFragment
public class ProfileFragment extends BaseFragment {
....
public interface P...
Activity views
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout ...>
<FrameLayout
android:id="@+id/mainactivity_cont...
// com.olrandir.samf.MainActivity
public class MainActivity extends AppCompatActivity
implements ProfileFragment.ProfileAc...
// com.olrandir.samf.MainActivity
public class MainActivity
extends AppCompatActivity
implements ProfileFragment.ProfileAc...
// com.olrandir.samf.fragments.HomeFragment
public class HomeFragment extends BaseFragment {
...
@Override
public void onF...
// com.olrandir.samf.fragments.BaseFragment
public abstract class BaseFragment extends Fragment {
...
public abstract void...
Mitigating
If you have many screens, the activity can become unwieldy (many
interfaces & functions to implement).
Solution...
Thank you!
dimitris@forky.gr | github: olrandir
code available: https://github.com/olrandir/samf_3aadm
Hungry?
Use promo D...
Upcoming SlideShare
Loading in …5
×

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

7,127 views

Published on

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.

Published in: Software
  • Great information about writing! If you ever need any help with proofreading, editing or research check out Writer’s Help. They are a great resource for personal, educational or business writing needs. The website is HelpWriting.net
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Follow the link, new dating source: ❤❤❤ http://bit.ly/39pMlLF ❤❤❤
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Dating for everyone is here: ❤❤❤ http://bit.ly/39pMlLF ❤❤❤
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

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

×