#Tip 1 – static newInstance
method pattern
Note: Avoid setter methods and parametrized constructors to modify fragment state, because platform uses only default (0 parameter) constructor, arguments bunde and saved state bundle to restore it later.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
public static MyFragment newInstance(int someParam) { Bundle args = new Bundle(); args.putInt(ARGS_SOME_PARAM, someParam); MyFragment fragment = new MyFragment(); fragment.setArguments(args); return fragment; } @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); int parameterValue getArguments().getInt(ARGS_SOME_PARAM); ... } |
#Tip 2 – single fragment in Activity
If your activity role is only to show fragment don’t create custom layout with container to add your fragment. Use default activity root container identified by android.R.id.content.
1 2 3 |
Fragment newFragment = new MyFragment(); FragmentTransaction ft = getFragmentManager().beginTransaction(); ft.add( android.R.id.content , newFragment).commit(); |
#Tip 3 – nested/child fragments will not get onActivityResult callback
Activities started with startActivityForResult
will automatically call onActivityResult
on ‘first level’ (added directly to Activity FragmentManager
) Fragments.
If you want to use activity result mechanism with child fragments, you have to pass this callback on your own.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
@Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); List<Fragment> childFragments = getChildFragmentManager().getFragments(); if (childFragments != null && childFragments.size() > 0) { for (Fragment childFragment : childFragments) { if (childFragment != null && !childFragment.isRemoving()) { childFragment.onActivityResult(requestCode, resultCode, data); } } } } |
#Tip 4 – Use setRetainInstance(true) only in non-UI fragments
setRetainInstance(true)
method will ensure that your fragment will survive orientation changes and its activity recreation. Using this flag in Fragments with UI/widget/view references could potentially cause memory leaks, like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
public class MyFragment extends Fragment { private TextView mMyTextView; @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setRetainInstance(true); } @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View root = inflater.inflate(R.layout.fragment_layout, container, false); mMyTextView = (TextView) root.findViewById(R.id.my_text); return root; } } |
After orientation change and before second onCreateView
TextView reference will hold old view with all it’s context – which is an old Activity. This means two Activities in memory at the same time, one new and one old held because of this TextView reference until mMyTextView = (TextView) root.findViewById(R.id.my_text);
will not be called again
#Tip 5 – setRetainInstance(true) cannot be used with nested/child fragments
If you try to use this flag in your child fragment you will get exception java.lang.IllegalStateException: Can't retain fragements that are nested in other fragments
#Tip 6 – Custom attributes on XML initialized fragments
If you want to create fragment via XML layout, you could declare custom style attributes and read them later in onInflate (Context context, AttributeSet attrs, Bundle savedInstanceState)
#Tip 7 – Debug your fragment
If you want to check what is the current state of FragmentManager
and it’s fragments just use FragmentManager.dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args)
method like this:
1 |
getSupportFragmentManager.dump("prefix", null, new PrintWriter(outputStream, true), null); |
#Tip 8 – Prefer android.support.v4.app.Fragment
over android.app.Fragment
Fragments packed into v4 support library are created on newer code. Support library could receive faster updates and bugfixes in contrast to android.app.Fragment
which is a part of Android framework released with different version on different devices (with a small probability of receiving updates).