[英]Attempt to invoke virtual method on a null object reference
這是我得到的錯誤:
03-11 08:27:48.513:E / AndroidRuntime(23647):java.lang.RuntimeException:無法啟動活動ComponentInfo {com.plan.yeahimin / com.plan.yeahimin.PlanDetailsActivity}:java.lang.NullPointerException:嘗試在空對象引用上調用虛擬方法'java.io.Serializable android.os.Bundle.getSerializable(java.lang.String)'
我理解它是由於變量的值為空,但我無法鍛煉原因。 它看起來像它的“EXTRA_NEW_PLAN”在getSerializable()
的方法DetailsFragment
但除此之外,我不知道。 我是Android的新手,所以很明顯,請原諒我,但任何幫助將不勝感激。
這是我的ListFragment
代碼;
public class PlanListFragment extends ListFragment {
public final static String TAG = "com.plan.yeahimin.PlanListFragment";
public final static String EXTRA_NEW_PLAN = "com.plan.yeahimin.plan_id";
private Button mAddPlan;
private ArrayList<Plan> mPlansList;
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState){
View v = inflater.inflate(R.layout.empty_view_or_list_view, parent, false);
ListView view = (ListView) v.findViewById(android.R.id.list);
view.setEmptyView(v.findViewById(android.R.id.empty));
mAddPlan = (Button) v.findViewById(R.id.add_a_plan);
mAddPlan.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
Log.d(TAG, "add plan clicked");
Plan plan = new Plan();
Log.d(TAG, "new plan created");
PlanArrayList.get(getActivity()).addPlans(plan);
Log.d(TAG, "plan added to mPlansList");
Intent i = new Intent(getActivity(), PlanDetailsActivity.class);
i.putExtra(PlanDetailsFragment.EXTRA_NEW_PLAN, plan.getId());
startActivity(i);
return;
}
});
return v;
}
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
mPlansList = PlanArrayList.get(getActivity()).getPlans();
//ArrayList<Plan> mPlansList = new ArrayList<Plan>();
PlanArrayAdapter paa = new PlanArrayAdapter(mPlansList);
setListAdapter(paa);
}
public class PlanArrayAdapter extends ArrayAdapter<Plan>{
public PlanArrayAdapter(ArrayList<Plan> planList){
super(getActivity(), 0, planList);
}
public View getView(int position, View convertView, ViewGroup parent){
// Get the plan item for this position
Plan plan = getItem(position);
//If layout doesnt exist, inflate one
if(convertView == null){
convertView = LayoutInflater.from(getContext()).inflate(R.layout.plan_list_fragment, parent, false);
}
TextView planTitle = (TextView) convertView.findViewById(R.id.plan_title);
planTitle.setText(plan.getTitle());
TextView planDate = (TextView) convertView.findViewById(R.id.plan_date);
planDate.setText(plan.getDate().toString());
return convertView;
}
}
}
這是我的DetailsFragment代碼,該代碼從添加按鈕打開;
public class PlanDetailsFragment extends Fragment {
private static final String TAG = "com.plan.yeahimin.PlanDetailsFragment";
public static final String EXTRA_NEW_PLAN = "com.plan.yeahimin.plan_id";
private EditText mTitleField;
private Button mDateButton;
private Button mTimeButton;
private EditText mLocationField;
private EditText mAttendeesField;
private EditText mDescriptionField;
private Plan mPlan;
private ArrayList<Plan> mPlansList;
public static PlanDetailsFragment newInstance(UUID planId){
Bundle args = new Bundle();
args.putSerializable(EXTRA_NEW_PLAN, planId);
PlanDetailsFragment f = new PlanDetailsFragment();
f.setArguments(args);
Log.d(TAG, "newInstance created");
return f;
}
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
UUID planId = (UUID)getArguments().getSerializable(EXTRA_NEW_PLAN);
mPlan = PlanArrayList.get(getActivity()).getPlan(planId);
}
@Override
public View onCreateView (LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState){
View v = inflater.inflate(R.layout.plan_details_fragment, parent, false);
mTitleField = (EditText)v.findViewById(R.id.plan_title);
mLocationField = (EditText)v.findViewById(R.id.plan_location);
mAttendeesField = (EditText)v.findViewById(R.id.plan_attendees);
mDescriptionField = (EditText)v.findViewById(R.id.plan_description);
mDateButton = (Button)v.findViewById(R.id.plan_date);
mTimeButton = (Button)v.findViewById(R.id.plan_time);
return v;
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater){
inflater.inflate(R.menu.main_to_do, menu);
}
public boolean onOptionsItemSelected(MenuItem item){
switch(item.getItemId()){
case R.id.save_button:
Log.d(TAG, "save button pressed");
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
我認為您無法使用.newInstance()向Fragment發送任何參數,因為根據文檔,此方法不接受任何參數。 因此,即使您已重載.newInstance(UUID),系統也會調用.newInstance()(如果有調用,我會有一些疑問)。 另外請注意,您已使用.putExtra()將參數放入Intent,但不要從Intent中調用它。
實際上,將參數發送到Fragment的正確方法如下:
在調用方中(通常是一個Activity,但也許帶有另一個Fragment,就像您的示例一樣,它也可以工作,我不能肯定地說):
PlanDetailsFragment fragment = new PlanDetailsFragment();
Bundle args = new Bundle();
args.putSerializable(PlanDetailsFragment.TAG_NEW_PLAN, plan.getID());
fragment.setArguments(args);
getFragmentManager().beginTransaction().add(fragment, TAG_DETAILS_FRAGMENT).commit();
在片段中:
Bundle args = getArguments();
UUID planID = (UUID) args.getSerializable(TAG_NEW_PLAN);
它不是現成的代碼,您應該根據類和變量名稱,標簽所在的位置等對它進行修改。如果您希望從另一個片段中進行工作,則Activity方法的調用也可能需要進行一些更改。 這只是一個整體描述。
我的答案適用於兩個片段都在一個活動中的情況。 您對Intent的使用使我對此有所懷疑,但我並不完全理解。
您已將參數發送到Activity(PlanDetailsActivity)。
您應該通過newInstance()方法將參數發送給Fragment。
在您的PlainDetailsActivity中,您應該創建片段實例,例如:
UUID uuid = getIntent().getSerializableExtra(PlanDetailsFragment.EXTRA_NEW_PLAN);
PlanDetailsFragment f = PlanDetailsFragment.newInstance(uuid);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.