我开始开发基于 FragmentsBasic.zip 示例项目的应用程序:http: //developer.android.com/training/basics/fragments/index.html
在开始编写自己的代码之前,我导入了 ActionBarSherlock 并让一切按预期工作。
情况:我有一个主要的活动类(TaskListActivity)和3个片段类。在手机中运行应用程序时,TaskListActivity 首先加载 TaskListFragment,如果用户触摸操作栏中的“新任务”图标,它会将 TaskListFragment 替换为 NewTaskFragment。这个片段有一个布局,其中包含一个 EditText 和一个 Button View。当用户输入文本并按下“完成”按钮时,测试被添加到 ListView。
问题:只要不发生设备旋转,一切都会按预期工作。无论我在将项目添加到列表之前还是之后旋转设备,我都会收到以下错误,
10-18 23:19:40.838: E/TaskListActivity(2021): Fragment has a null value
10-18 23:19:40.848: E/AndroidRuntime(2021): FATAL EXCEPTION: main
10-18 23:19:40.848: E/AndroidRuntime(2021): java.lang.NullPointerException
10-18 23:19:40.848: E/AndroidRuntime(2021): at com.sample.testapp.TasksListActivity.onNewTaskAdded(TasksListActivity.java:169)
10-18 23:19:40.848: E/AndroidRuntime(2021): at com.sample.testapp.NewTaskFragment$2.onClick(NewTaskFragment.java:63)
10-18 23:19:40.848: E/AndroidRuntime(2021): at android.view.View.performClick(View.java:2449)
10-18 23:19:40.848: E/AndroidRuntime(2021): at android.view.View$PerformClick.run(View.java:9027)
我的活动如下所示:
public class TasksListActivity extends SherlockFragmentActivity
implements TasksListFragment.OnTaskSelectedListener, NewTaskFragment.OnNewTaskAddedListener {
private ArrayList<Task> tasks;
private String taskName;
private TasksListFragment firstFragment;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tasks_list);
if (findViewById(R.id.fragment_container) != null) {
if (savedInstanceState != null) {
return;
}
firstFragment = new TasksListFragment();
// In case this activity was started with special instructions from an Intent,
// pass the Intent's extras to the fragment as arguments
firstFragment.setArguments(getIntent().getExtras());
// Add the fragment to the 'fragment_container' FrameLayout
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container, firstFragment).commit();
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_new:
//Toast.makeText(this, "Tapped new task", Toast.LENGTH_SHORT).show();
// try code from Fragment sample
NewTaskFragment newTaskFragment = (NewTaskFragment)getSupportFragmentManager().findFragmentById(R.id.task_fragment);
if(newTaskFragment != null){
// if itemFragment is available we are in two-pane layout
// Call method in NewItemFragment to update its content
//itemFragment.
}
else{
// if the frag is not available, we are in one-pane layout and must swap fragments
// Create fragment and give it an argument for the selected article
newTaskFragment = new NewTaskFragment();
Bundle args = new Bundle();
//args.putInt(NewItemFragment.ARG_POSITION, position);
newTaskFragment.setArguments(args);
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view wiht this fragment,
// and add the transaction to the back stack so the user can navigate back
transaction.replace(R.id.fragment_container, newTaskFragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
}
break;
}
return super.onOptionsItemSelected(item);
}
}
public void onNewTaskAdded(String newItem){
this.taskName = newItem;
if(firstFragment == null){
Log.e("TaskListActivity", "Fragment has a null value");
}
firstFragment.onItemAdded(this.taskName); // This is line 169
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fragment_container, firstFragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
}
NewItemFragment 具有以下内容(界面未显示):
public class NewTaskFragment extends SherlockFragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.new_task_fragment, container, false);
int layout = R.layout.new_task_fragment;
Log.v("NewTaskFragment", "The layout to use is (NewTask): " + layout);
final EditText myEditText = (EditText)view.findViewById(R.id.newTask);
final Button doneButton = (Button)view.findViewById(R.id.addNewTask);
final InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
doneButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
String newItem = myEditText.getText().toString();
onNewTaskAddedListener.onNewTaskAdded(newItem); // This is line 63
myEditText.setText("");
imm.hideSoftInputFromWindow(getView().getWindowToken(), 0);
}
});
return view;
}
我已经用 NullPointerException 标记的注释行 169(活动)和 63(片段)突出显示。我在 onNewTaskAdded 上添加了一些代码,并且能够确认在旋转后片段的值为空。有人可以帮我找出为什么对象在旋转后变为空(因此出现 NullPointerException)?让我知道是否需要其他详细信息。谢谢!