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)
实现。