Tim Tim - 2 months ago 7
Android Question

Onclick in fragment, FATAL EXCEPTION. Shared preferences to a fragment

Basic info


I am using the Settings Activity and navigation menu : and i have button to display the data (which is the number) from the settings to a textview. It's a sms app


Problem
I have the textview in context_main (The first screen when you start the app) But i would really like to have the textview in my fragment and when i press the button "the onlick" will display the value from settings.

The Button is in the fragment. and when i click the button it works^^ for the context_main se below code.

public void displayData(View view){

SharedPreferences prefs =PreferenceManager.getDefaultSharedPreferences(this);
String restoredText = prefs.getString("example_text", "");
radertst.setText(restoredText);
}


But when i press a button to send a sms and i linked it with the textfield for where the number is but then i get this.

09-16 20:47:03.501 5389-5389/c.timno.smsgsm20 E/AndroidRuntime: FATAL EXCEPTION: main

Process: c.timno.smsgsm20, PID: 5389
java.lang.NullPointerException
at c.timno.smsgsm20.FirstFragment$1$override.onClick(FirstFragment.java:102)
at c.timno.smsgsm20.FirstFragment$1$override.access$dispatch(FirstFragment.java)
at c.timno.smsgsm20.FirstFragment$1.onClick(FirstFragment.java:0)
at android.view.View.performClick(View.java:4443)
at android.view.View$PerformClick.run(View.java:18475)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5103)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:788)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:604)
at dalvik.system.NativeStart.main(Native Method)




This my
MainActivity java class

public class MainActivity extends AppCompatActivity


implements NavigationView.OnNavigationItemSelectedListener {
TextView tstnr;
TextView radertst;
EditText nantxt;
Button sendSMSaon;
EditText aonTxt;
TextView nrladd;


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});

DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();

NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);


tstnr = (TextView) findViewById(R.id.nummertestsp);
radertst = (TextView) findViewById(R.id.raderanumtxt);
nantxt =(EditText) findViewById(R.id.nummer);
sendSMSaon = (Button)findViewById(R.id.skickaaon);
aonTxt = (EditText)findViewById(R.id.aon);
nrladd = (TextView)findViewById(R.id.numretladd);


}
//This is where the call for the value in the setttings are.
//Här är så att man kan lägga in values från inställningar till mainactivity.

public void displayData(View view){

SharedPreferences prefs =PreferenceManager.getDefaultSharedPreferences(this);
String name = prefs.getString("example_text", "");
radertst.setText(name + " ");
}

//downbelow is where the onresume so the value boots up with the app.
//nedanför är för att appen ska ladda koden i settings direkt när man startar

@Override
protected void onResume() {
super.onResume();
SharedPreferences prefs =PreferenceManager.getDefaultSharedPreferences(this);

String name = prefs.getString("example_text", "");
radertst.setText(name + " ");}



@Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, 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_settings) {
Intent intent = new Intent(this, SettingsActivity.class);
startActivity(intent);



return true;
}




return super.onOptionsItemSelected(item);
}


@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
android.app.FragmentManager fragmentManager = getFragmentManager();


if (id == R.id.nav_first_layout) {

fragmentManager.beginTransaction()
.replace(R.id.content_frame
, new FirstFragment())
.commit();
// Handle the camera action
} else if (id == R.id.nav_second_layout) {
fragmentManager.beginTransaction()
.replace(R.id.content_frame
, new SecondFragment())
.commit();

} else if (id == R.id.nav_third_layout) {
fragmentManager.beginTransaction()
.replace(R.id.content_frame
, new ThirdFragment())
.commit();




}

DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;








}
}




The fragment java file

public class FirstFragment extends Fragment {



private View view ;

public FirstFragment(){


}
Button sendSMS;
Button sendSMSaon;
Button sendSMSaoff;
Button sendSMSrela1;
Button sendSMSrela2;
EditText msgTxt;
EditText numTxt;
EditText aonTxt;
EditText aoffTxt;
EditText rela1txt;
EditText rela2txt;
Button taframnummer;
TextView nyanumtxt;

TextView ifirt;


TextView tstnr;


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.first_layout, container, false);



nyanumtxt = (TextView)view.findViewById(R.id.raderanumtxt);
sendSMS = (Button)view.findViewById(R.id.skicka);
sendSMSaon = (Button)view.findViewById(R.id.skickaaon);
sendSMSaoff = (Button)view.findViewById(R.id.skickaaoff);
sendSMSrela1 = (Button)view.findViewById(R.id.skickarela1);
sendSMSrela2 = (Button)view.findViewById(R.id.skickarela2);

msgTxt = (EditText)view.findViewById(R.id.Textmeddelande);
numTxt = (EditText)view.findViewById(R.id.nummer);
aonTxt = (EditText)view.findViewById(R.id.aon);
aoffTxt = (EditText)view.findViewById(R.id.aoff);
rela1txt = (EditText)view.findViewById(R.id.rela1txt);
rela2txt = (EditText)view.findViewById(R.id.relä2txt);
taframnummer = (Button) view.findViewById(R.id.taframnummer);

tstnr = (TextView) view.findViewById(R.id.numretladd);



msgTxt.setVisibility(View.INVISIBLE);
aonTxt.setVisibility(View.INVISIBLE);
aoffTxt.setVisibility(View.INVISIBLE);
rela1txt.setVisibility(View.INVISIBLE);
rela2txt.setVisibility(View.INVISIBLE);

//testnedan

LayoutInflater lf = getActivity().getLayoutInflater();
view = lf.inflate(R.layout.first_layout, container, false);



//ovantest

sendSMSaoff.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String mymsgaoff = aoffTxt.getText().toString();
String theNumber = numTxt.getText().toString();
sendMsg(theNumber, mymsgaoff);
}

}

);

sendSMSaon.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String mymsgaon = aonTxt.getText().toString();
String theNumber = nyanumtxt.getText().toString();
sendMsg(theNumber, mymsgaon);
}

}







);
sendSMS.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String myMsg = msgTxt.getText().toString();
String theNumber = numTxt.getText().toString();
sendMsg(theNumber, myMsg);
}

}
);

sendSMSrela1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String myMsgrela1 = rela1txt.getText().toString();
String theNumber = numTxt.getText().toString();
sendMsg(theNumber, myMsgrela1);
}

}
);
sendSMSrela2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String mymsgrela2 = rela2txt.getText().toString();
String theNumber = numTxt.getText().toString();
sendMsg(theNumber, mymsgrela2);
}

}







);

return view;
}



private void sendMsg(String theNumber, String myMsg)
{
SmsManager sms = SmsManager.getDefault();
sms.sendTextMessage(theNumber, null, myMsg, null, null);

}


}


if you look at

sendSMSaoff.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String mymsgaoff = aoffTxt.getText().toString();
String theNumber = numTxt.getText().toString();
sendMsg(theNumber, mymsgaoff);
}




The numTxt is where i want the value to be loaded and it's in the first layout xml not context_main. So for some reason it wont be loaded there. Imgur image

Answer

If I'm understanding you correctly, R.id.raderanumtxt is in the MainActivity's layout file and not FirstFragment's.

That means that it won't be found in the onCreateView() method of FirstFragment the way you're accessing it. The view object there is the layout you just loaded:

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.first_layout, container, false);
    nyanumtxt = (TextView)view.findViewById(R.id.raderanumtxt); // <- this assignment won't work
    ... 
}

You're also inflating R.layout.first_layout twice, which is unnecessary.

To get access to a View in the Activity, you can do something like this:

View view = getActivity().findViewById(R.id.viewid);

EDIT:

Without seeing your layouts, I can't be sure, but try and replace:

nyanumtxt = (TextView)view.findViewById(R.id.raderanumtxt);

... with:

nyanumtxt = (TextView) getActivity().findViewById(R.id.raderanumtxt);

That way you're looking for R.id.raderanumtxt in the entire Activity layout. This will only work if the Activity is available and the layout has already been added, so to be safer I'd move this assignment to onViewCreated() instead of onCreateView().