访问片段的子视图时出现空指针异常
Posted
技术标签:
【中文标题】访问片段的子视图时出现空指针异常【英文标题】:nullpointer exception while accessing childviews of a fragment 【发布时间】:2018-06-06 13:08:59 【问题描述】:我正在创建一个包含三个标签片段的活动。我想将来自对象(在父活动中可用)的数据设置为片段的子视图。我尝试通过片段的公共方法来做到这一点。但是当尝试访问视图时,它返回空指针异常并且应用程序崩溃。有人可以帮我解决这个问题吗?
父活动是:
public class EnquiryViewActivity extends AppCompatActivity implements IFragmentToActivity
private Context mContext;
// Session Manager Class
SessionManagement session;
private RequestQueue requestQueue;
private Gson gson;
//String enquiryId;
int enId, uid;
Enquiry enquiry;
// Alert Dialog Manager
AlertDialogManager alert = new AlertDialogManager();
/* Button btn_MoreEnqDetails, btn_ToSiteVisit, btn_nextEnq2;
EditText etName, etAddress, etSiteAddress, etPhoneNo, etMob, etEmail;
private RadioGroup rgrp_familyType;
private RadioButton radioselectedFamilyType;
*/
private TabLayout addenqtabLayout;
private ViewPager addenqviewPager;
//Fragments
ContactFragment contactFragment;
RequirementsFragment requirementsFragment;
FollowUpFragment followupFragment;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_enquiry);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
//--------------------------------------------
//Initializing viewPager
addenqviewPager = (ViewPager) findViewById(R.id.addenqviewpager);
addenqviewPager.setOffscreenPageLimit(3);
//Initializing the tablayout
addenqtabLayout = (TabLayout) findViewById(R.id.addenqtablayout);
addenqtabLayout.setupWithViewPager(addenqviewPager);
addenqviewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener()
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels)
@Override
public void onPageSelected(int position)
addenqviewPager.setCurrentItem(position, false);
@Override
public void onPageScrollStateChanged(int state)
);
setupViewPager(addenqviewPager);
//----------------------------------------------
enquiry = new Enquiry();
try
mContext = this;
enId = getIntent().getIntExtra("EnquiryId", -1);
uid = getIntent().getIntExtra("UserId", -1);
if (enId != -1)
Log.d("h", "get enqid is " + enId);
enquiry = EnquiryORM.findEnquiryById(mContext, enId);
else
Log.d("h", "didn't get bid");
/*int position = tabLayout.getSelectedTabPosition();
Fragment fragment = adapter.getFragment(tabLayout
.getSelectedTabPosition());
if (fragment != null)
switch (position)
case 0:
((TabFragment1) fragment).onRefresh();
break;
case 1:
((TabFragment2) fragment).onRefresh();
break;
*/
contactFragment.setDataToScreen(enquiry);
contactFragment.disableAllViews();
catch (NumberFormatException e)
Log.d("NumberFormatException: ", "some int is null");
Log.d("NumberFormatException: ", e.getMessage());
//---------------------------------------------------------------
@Override
public void showToast(String msg)
Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
@Override
public void communicateToFragment2()
/*RequirementsFragment fragment = (RequirementsFragment) adapter.getFragment(1);
if (fragment != null)
fragment.fragmentCommunication();
else
Log.i("log", "Fragment 2 is not initialized");
*/
@Override
public void gotoMoreDetails()
if (ConnectivityReceiver.isConnected())
//fetch and
//send indent to next activity to view more details
//show option to edit details
fetchMoreEnquiryDetails();
else
alert.showAlertDialog(EnquiryViewActivity.this, "Network Error", "Internet is not available!\nCannot connect to server", false);
@Override
public void gotoSiteVisit()
Intent in = new Intent(EnquiryViewActivity.this, SiteVisitViewActivity.class);
in.putExtra("EnquiryId", enId);
in.putExtra("UserId", uid);
startActivity(in);
@Override
public void saveDataContacts(Enquiry enq)
if (enquiry != null)
enq.setId(enquiry.getId());
enq.setStatus(enquiry.getStatus());
enq.setUser_id(enquiry.getUser_id());
enq.setEnqstatusnew(enquiry.getEnqstatusnew());
enq.setCreateddate(getDateTime());
int enI=(int)EnquiryORM.insertEnquiry(mContext, enq);
enq.setId(enI);
//-----------------------------------------------------------------------
private void setupViewPager(ViewPager viewPager)
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
contactFragment = new ContactFragment();
requirementsFragment = new RequirementsFragment();
followupFragment = new FollowUpFragment();
adapter.addFragment(contactFragment, "CONTACT DETAILS");
adapter.addFragment(requirementsFragment, "REQUIREMENTS");
adapter.addFragment(followupFragment, "FOLLOW-UP");
viewPager.setAdapter(adapter);
private void fetchMoreEnquiryDetails()
// Get a RequestQueue
// RequestQueue requestQueue = MyVolleySingleton.getInstance(this.getApplicationContext()).getRequestQueue();
requestQueue = Volley.newRequestQueue(this);
//create gson instance which is used to parse json
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.excludeFieldsWithoutExposeAnnotation();
//gsonBuilder.setDateFormat("M/d/yy hh:mm a");
gson = gsonBuilder.create();
StringRequest sr = new StringRequest(Request.Method.POST, EndPoints.GET_SELECTED_ENQUIRIES_URL, new Response.Listener<String>()
@Override
public void onResponse(String response)
Log.d("d", "getting response.........\n" + response);
Toast.makeText(getApplicationContext(), "Selected Enquiry JSON data :" + response, Toast.LENGTH_LONG).show();
//Enquiry detailEnquiry = gson.fromJson(response, Enquiry.class);
//detailEnquiry.setUser_id(uid);
Enquiry detailEnquiry = new Enquiry();
List<Enquiry> enquiryList = Arrays.asList(gson.fromJson(response, Enquiry[].class));
for (Enquiry enqu : enquiryList)
detailEnquiry = enqu;
forwardToViewEnquiryMoreDetails(detailEnquiry);
/*Log.d("e", "All data inserted...now display.........");
List<Enquiry> enqlist= EnquiryORM.getEnquiries(getBaseContext());
for(Enquiry i:enqlist)
Log.d("e", "enquiry :" +i.getId());
Log.d("e", i.getName()+","+i.getStatus()+","+i.getAddress()+","+i.getUser_id());
*/
, new Response.ErrorListener()
@Override
public void onErrorResponse(VolleyError error)
Log.e("EnqViewActivity", error.toString());
Toast.makeText(getApplicationContext(), "Error: " + error.getMessage(), Toast.LENGTH_LONG).show();
)
@Override
protected Map<String, String> getParams() throws AuthFailureError
Log.d("d", "inside getparams()...\n");
Map<String, String> params = new HashMap<String, String>();
params.put("enquiryid", String.valueOf(enId));
params.put("userid", String.valueOf(uid));
Log.d("d", "enquiry id to pass:" + enId + "\n");
return params;
;
// Add the request to RequestQueue.
// MyVolleySingleton.getInstance(this).addToRequestQueue(sr);
requestQueue.add(sr);
Log.d("d", "Added to queue");
//-----------------------------------------------------------------------
private void forwardToViewEnquiryMoreDetails(Enquiry detailedEnquiry)
Gson mynewgson = new Gson();
String DEnquiryDataObjectAsString = mynewgson.toJson(detailedEnquiry);
Intent toDetail = new Intent(EnquiryViewActivity.this, EnquiryViewMoreActivity.class);
toDetail.putExtra("DetailedEnquiryDataObjectAsString", DEnquiryDataObjectAsString);
startActivity(toDetail);
// close this activity
//finish();
private String getDateTime()
SimpleDateFormat dateFormat = new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss", Locale.getDefault());
Date date = new Date();
return dateFormat.format(date);
//---------------------------------------------------------------
@Override
public boolean onCreateOptionsMenu(Menu menu)
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.view_enq, menu);
return true;
@Override
public boolean onOptionsItemSelected(MenuItem item)
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in androidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_add_enquiry)
startActivity(new Intent(EnquiryViewActivity.this, EnquiryAddActivity.class));
return true;
if (id == R.id.action_edit_enquiry)
// Make all fields editable
contactFragment.enableAllViews();
return true;
return super.onOptionsItemSelected(item);
片段代码是:
public class ContactFragment extends Fragment implements View.OnClickListener
private IFragmentToActivity mCallback;
Button btn_MoreEnqDetails, btn_ToSiteVisit, btn_nextEnq1;
EditText etName, etAddress, etSiteAddress, etPhoneNo, etMob, etEmail;
public ContactFragment()
// Required empty public constructor
@Override
public void onCreate(@Nullable Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_contact, container, false);
btn_MoreEnqDetails = (Button) view.findViewById(R.id.btn_MoreEnqDetails);
btn_ToSiteVisit = (Button) view.findViewById(R.id.btn_ToSiteVisit);
btn_nextEnq1 = (Button) view.findViewById(R.id.btn_nextEnq1);
etName = (EditText) view.findViewById(R.id.etClientName);
etAddress = (EditText) view.findViewById(R.id.etAddress);
etSiteAddress = (EditText) view.findViewById(R.id.etSiteAddress);
etPhoneNo = (EditText) view.findViewById(R.id.etPhoneNo);
etMob = (EditText) view.findViewById(R.id.etMob);
etEmail = (EditText) view.findViewById(R.id.etEmail);
btn_MoreEnqDetails.setOnClickListener(this);
btn_ToSiteVisit.setOnClickListener(this);
btn_nextEnq1.setOnClickListener(this);
return view;
@Override
public void onClick(View v)
switch (v.getId())
case R.id.btn_MoreEnqDetails:
mCallback.showToast("Hello from Fragment 1");
break;
case R.id.btn_ToSiteVisit:
mCallback.gotoSiteVisit();
break;
case R.id.btn_nextEnq1:
Enquiry enq=new Enquiry();
enq=getDataFromViews(enq);
mCallback.saveDataContacts(enq);
break;
@Override
public void onAttach(Context context)
super.onAttach(context);
try
mCallback = (IFragmentToActivity) context;
catch (ClassCastException e)
throw new ClassCastException(context.toString()
+ " must implement IFragmentToActivity");
@Override
public void onDetach()
mCallback = null;
super.onDetach();
public void onRefresh()
Toast.makeText(getActivity(), "Fragment 1: Refresh called.",
Toast.LENGTH_SHORT).show();
public void disableAllViews()
Log.d("EnqViewAct: ", "disabling all views..");
btn_MoreEnqDetails.setEnabled(false);
btn_ToSiteVisit.setEnabled(false);
btn_nextEnq1.setEnabled(false);
etName.setEnabled(false);
etAddress.setEnabled(false);
etSiteAddress.setEnabled(false);
etPhoneNo.setEnabled(false);
etMob.setEnabled(false);
etEmail.setEnabled(false);
public void enableAllViews()
Log.d("EnqViewAct: ", "enabling all views..");
btn_MoreEnqDetails.setEnabled(true);
btn_ToSiteVisit.setEnabled(true);
btn_nextEnq1.setEnabled(true);
etName.setEnabled(true);
etAddress.setEnabled(true);
etSiteAddress.setEnabled(true);
etPhoneNo.setEnabled(true);
etMob.setEnabled(true);
etEmail.setEnabled(true);
public void setDataToScreen(Enquiry enquiry)
Log.d("EbqViewAct","Data to display : "
+enquiry.getId()+","+enquiry.getUser_id()+","+
enquiry.getStatus()+","+enquiry.getEnqstatusnew()+","+
enquiry.getCreateddate()+","+
enquiry.getName()+","+enquiry.getAddress()+","+
enquiry.getSiteaddress()+","+enquiry.getPhone_number()+","+
enquiry.getMobile_number()+","+enquiry.getEmail());
if(enquiry.getName()!=null && enquiry.getName()!="")
etName.setText(enquiry.getName());
if(enquiry.getAddress()!=null && enquiry.getAddress()!="")
etAddress.setText(enquiry.getAddress());
if(enquiry.getSiteaddress()!=null && enquiry.getSiteaddress()!="")
etSiteAddress.setText(enquiry.getSiteaddress());
if(enquiry.getPhone_number()!=null && enquiry.getPhone_number()!="")
etPhoneNo.setText(enquiry.getPhone_number());
if(enquiry.getMobile_number()!=null && enquiry.getMobile_number()!="")
etMob.setText(enquiry.getMobile_number());
if(enquiry.getEmail()!=null && enquiry.getEmail()!="")
etEmail.setText(enquiry.getEmail());
/* if (thisSv.getFamilytype() != null)
if (thisSv.getFamilytype().equalsIgnoreCase("Nuclear"))
rgrp_familyType.check(R.id.rbtn_nuclear);
else if (thisSv.getFamilytype().equalsIgnoreCase("Join"))
rgrp_familyType.check(R.id.rbtn_join);
else
rgrp_familyType.check(R.id.rbtn_nuclear);
*/
public Enquiry getDataFromViews(Enquiry enq)
/*
radioSelectedFamilyType = (RadioButton) findViewById(rgrp_familyType.getCheckedRadioButtonId());
if (radioSelectedFamilyType != null)
newSv.setFamilytype(radioSelectedFamilyType.getText().toString());
*/
if ((etName.getText().toString()) != "" && (etName.getText().toString()) != null)
enq.setName(etName.getText().toString().trim());
if ((etAddress.getText().toString()) != "" && (etAddress.getText().toString()) != null)
enq.setAddress(etAddress.getText().toString().trim());
if ((etSiteAddress.getText().toString()) != "" && (etSiteAddress.getText().toString()) != null)
enq.setSiteaddress(etSiteAddress.getText().toString().trim());
if ((etPhoneNo.getText().toString()) != "" && (etPhoneNo.getText().toString()) != null)
enq.setPhone_number(etPhoneNo.getText().toString().trim());
if ((etMob.getText().toString()) != "" && (etMob.getText().toString()) != null)
enq.setMobile_number(etMob.getText().toString().trim());
if ((etEmail.getText().toString()) != "" && (etEmail.getText().toString()) != null)
enq.setEmail(etEmail.getText().toString().trim());
return enq;
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
界面是:
public interface IFragmentToActivity
void showToast(String msg);
void communicateToFragment2();
void gotoMoreDetails();
void gotoSiteVisit();
void saveDataContacts(Enquiry enq);
PagerAdapter 是:
public class ViewPagerAdapter extends FragmentStatePagerAdapter
private final SparseArray<WeakReference<Fragment>> instantiatedFragments = new SparseArray<>();
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager)
super(manager);
@Override
public Fragment getItem(int position)
return mFragmentList.get(position);
@Override
public int getCount()
return mFragmentList.size();
public void addFragment(Fragment fragment, String title)
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
@Override
public CharSequence getPageTitle(int position)
return mFragmentTitleList.get(position);
@Override
public int getItemPosition(Object object)
return super.getItemPosition(object);
//--------------------------------------------------------
@Override
public Object instantiateItem(final ViewGroup container, final int position)
final Fragment fragment = (Fragment) super.instantiateItem(container, position);
instantiatedFragments.put(position, new WeakReference<>(fragment));
return fragment;
@Override
public void destroyItem(final ViewGroup container, final int position, final Object object)
instantiatedFragments.remove(position);
super.destroyItem(container, position, object);
@Nullable
public Fragment getFragment(final int position)
final WeakReference<Fragment> wr = instantiatedFragments.get(position);
if (wr != null)
return wr.get();
else
return null;
错误日志是:
12-25 11:09:46.931 3136-3136/com.example.anjana.decorightkitchen E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.anjana.decorightkitchen, PID: 3136
java.lang.RuntimeException: Unable to start activity ComponentInfocom.example.anjana.decorightkitchen/com.example.anjana.decorightkitchen.activity.EnquiryViewActivity: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.EditText.setText(java.lang.CharSequence)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.EditText.setText(java.lang.CharSequence)' on a null object reference
at com.example.anjana.decorightkitchen.fragment.ContactFragment.setDataToScreen(ContactFragment.java:149)
at com.example.anjana.decorightkitchen.activity.EnquiryViewActivity.onCreate(EnquiryViewActivity.java:140)
at android.app.Activity.performCreate(Activity.java:6237)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
注意:查询对象值正确进入片段。 enqName.setText("hai") 在片段的 onCreateView() 内正常工作。 但是当enqName.setText("hai")放到fragment的一个公共方法中,并从onCreateView()中调用该方法时,再次出现nullpointer异常。
【问题讨论】:
也发布您的错误日志 编辑添加错误日志@Tej 您收到您的数据enquiry.getName()
了吗?在您的联系人片段中?
是的...我在联系人片段@Tej 中获取查询对象数据
那么可能是你的edittext初始化问题。所以请确保您的所有编辑文本中的findViewbyId
带有他们受人尊敬的 ID
【参考方案1】:
来自您的代码和错误日志
void android.widget.EditText.setText(java.lang.CharSequence)' on a null object reference
似乎,可能只有两个问题。
-
您的 Edittext 初始化问题,可能与您的
finViewByID
或您的
身份证名称(R.id.checkthis)
当您启用和禁用视图时。所以当你
setText ,您的视图是Enable
而不是Visibility.Gone
。
正如您已经检查了您的 enquiry
对象。它运作良好。所以我认为这些可能导致NullPointerException
【讨论】:
删除启用和禁用方法无效!【参考方案2】:也许您正在寻找这样的东西。?
Fragment home = getSupportFragmentManager().findFragmentById(R.id.content_frame);
if (home instanceof HomeFragment)
((HomeFragment)home).setData(data);
【讨论】:
【参考方案3】:要在创建时将数据发送到片段,您可以在创建片段时为片段设置参数,然后您可以像这样稍后检索它:
public static ContactFragment newInstance(String data, int data2)
ContactFragment fragment = new ContactFragment();
Bundle bundle = new Bundle();
bundle.putString("someData", data);
bundle.putInt("otherData", data2);
fragment.setArguments(bundle);
return fragment;
当你调用你的片段时,像这样使用这个构造函数:
ContactFragment fragment = ContactFragment.newInstance("firstData",1200);
在您的片段中,您可以像这样在任何地方检索数据:
int variable = getArguments().getInt("otherData");
String string = getArguments().getString("someData");
希望这会有所帮助。
【讨论】:
以上是关于访问片段的子视图时出现空指针异常的主要内容,如果未能解决你的问题,请参考以下文章
Android ViewBinding 有时会在绑定对象处返回 null,因此在尝试访问视图时出现空指针异常
在使用ViewPager时尝试从其父活动修改片段时出现空指针异常
Android:小部件 - 在远程视图上使用 setOnclickPendingIntent 时出现空指针异常?
尝试从 Kotlin 中的另一个活动访问 EditText 时出现空指针异常