newInstance() 模式
儘管可以使用引數建立片段建構函式,但 Android 在重新建立片段時會在內部呼叫零引數建構函式(例如,如果因為 Android 自身原因而被殺死後它們正在被恢復)。因此,不建議依賴具有引數的建構函式。
為了確保始終存在你期望的片段引數,你可以使用靜態 newInstance()
方法建立片段,並將你想要的任何引數放入建立新例項時可用的包中。
import android.os.Bundle;
import android.support.v4.app.Fragment;
public class MyFragment extends Fragment
{
// Our identifier for obtaining the name from arguments
private static final String NAME_ARG = "name";
private String mName;
// Required
public MyFragment(){}
// The static constructor. This is the only way that you should instantiate
// the fragment yourself
public static MyFragment newInstance(final String name) {
final MyFragment myFragment = new MyFragment();
// The 1 below is an optimization, being the number of arguments that will
// be added to this bundle. If you know the number of arguments you will add
// to the bundle it stops additional allocations of the backing map. If
// unsure, you can construct Bundle without any arguments
final Bundle args = new Bundle(1);
// This stores the argument as an argument in the bundle. Note that even if
// the 'name' parameter is NULL then this will work, so you should consider
// at this point if the parameter is mandatory and if so check for NULL and
// throw an appropriate error if so
args.putString(NAME_ARG, name);
myFragment.setArguments(args);
return myFragment;
}
@Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final Bundle arguments = getArguments();
if (arguments == null || !arguments.containsKey(NAME_ARG)) {
// Set a default or error as you see fit
} else {
mName = arguments.getString(NAME_ARG);
}
}
}
現在,在活動中:
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
MyFragment mFragment = MyFragment.newInstance("my name");
ft.replace(R.id.placeholder, mFragment);
//R.id.placeholder is where we want to load our fragment
ft.commit();
此模式是確保在建立時將所有必需引數傳遞給片段的最佳實踐。請注意,當系統銷燬片段並稍後重新建立它時,它將自動恢復其狀態 - 但你必須為其提供 onSaveInstanceState(Bundle)
實現。