I declare a button in the Main Activity, but get NullObjectReference when I run the app. No matter where I try to move the declaration (outside of the class, inside the onCreate method, etc.), it redlines either the declaration or the button reference. I see posts recommending status versus non-static classes/methods, but I'm new to OOP and not exactly sure how to implement that. Can anyone tell me what I'm doing wrong?
public class MainActivity extends AppCompatActivity {
…
// Declare button in the MainActivity
Button btnWrong = (Button)findViewById(R.id.btnWrong);
...
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// WHEN USER TAPS ITEMS ON APPBAR
switch (item.getItemId()) {
case R.id.mnuLoad: // If use taps "Load"
final Dialog dialog = new Dialog(MainActivity.this); /
…
btnLoad.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
deckNumber = deckPicker.getValue();
if … }
dialog.dismiss();
btnWrong.setEnabled(true); // Trying to reference the button here
You have to do this:
outside onCreate() (under public class MainActivity extends AppCompatActivity)
Button btnWrong; //Declare button as private
in onCreate()
btnWrong = (Button)findViewById(R.id.btnWrong);
Now you can use btnWrong anywhere in its class
Try this:
public class MainActivity extends AppCompatActivity {
// Declare as class field
Button btnWrong;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.YOUR_LAYOUT_XML);
btnWrong = (Button)findViewById(R.id.btnWrong);
}
....
}
Related
I wish to pass a argument to snakebar function ,which is in main activity function from a non activity simple java class. Simply instantiating a activity class and passing value as argument does not work as I tried below. How can I achieve it in below scenario.
public class MainActivity extends AppCompatActivity {
private ConstraintLayout coordinatorLayout;
private Button button;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
coordinatorLayout=findViewById(R.id.coordinator);
button= findViewById(R.id.james);
button.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View view){
showSnackbar("its not working ");
}
});
}
public void showSnackbar(String james){
Snackbar snackbar=Snackbar.make(coordinatorLayout,james,Snackbar.LENGTH_INDEFINITE);
snackbar.show();
}
}
2nd class without activity ,simple non view class
class MyAccount extends Account
{
#Override
public void onRegState(OnRegStateParam prm)
{
MyApp.observer.notifyRegState(prm.getCode(), prm.getReason(),
prm.getExpiration());
if(prm.getReason().equals("OK")) {
/ /when ever above value equals ok , I wish to send a below message as snakebar // message on the main activity class. but below code does not works
MainActivity2 main2= new MainActivity2(); // trying to call snakebar function from main activity.
if(prm.getReason().equals("Service Unavailable")){
Log.e("javan007", prm.getReason());
main2.showSnackbar("service Unavailable");
}
}
}
I want to modularize the usage of my class but I have problem in passing function. I want to be able to pass an OnClickListener from 1 activity to this CoachmarkActivity.
I tried 2 different method:
1. Passing an OnClickListener to Intent
2. Passing a class, FollowUpClass, implements Serializable, which has method onClick.
You can see the code below. It is not complete code, but you should be able to comprehend this.
public class CoachmarkActivity extends Activity {
public static final String RES_LAYOUT = "RES-LAYOUT";
public static final String LISTENER = "LISTENER";
public static final String FOLLOW_UP = "FOLLOW-UP";
#Override protected void onCreate(Bundle savedInstance) {
setContentView(getIntent.getIntExtra(RES_LAYOUT, R.layout.activity_default))
Button button1 = (Button) findViewById(R.id.button1);
Button button2 = (Button) findViewById(R.id.button2);
// 1ST ATTEMPT
// I want to modularize this
OnClickListener onClickPassedFromIntent = (OnClickListener) getIntent().getSerializableExtra(LISTENER);
button1.setOnClickListener(onClickPassedFromIntent);
// 2ND ATTEMPT
final FollowUpListener folllowup = (FollowUpListener) getIntent().getSerializableExtra(FOLLOW_UP);
button2.setOnClickListener(new OnClickListener() {
#Override void onClick() {
// !! Here is error, exception thrown
folllowup.onClick();
}
});
}
/**
* Public method to be used in other activity.
* Invocation wanna be:
* CoachmarkActivity.startThisActivity(getActivity(), R.layout.coachmark1, new OnClickListener() {
* #Override void onClick() {
* // Do something
* }
* });
*/
public static void startThisActivity(Context context, int resId, OnClickListener listener) {
Intent intent = new Intent(context, CoachmarkActivity.class);
intent.putExtra(RES_LAYOUT, resId);
// !! Line below is error, onClickListener is not serializable, no method can accomadate below
intent.putExtra(LISTENER, listener);
context.startActivity(intent);
}
/**
* Public method to be used in other activity.
* Invocation wanna be:
* CoachmarkActivity.startThisActivity(getActivity(), R.layout.coachmark1, new FollowUpListener() {
* #Override void onClick() {
* // Do something
* }
* });
*/
public static void startThisActivity(Context context, int resId, FollowUpListener folllowup) {
Intent intent = new Intent(context, CoachmarkActivity.class);
intent.putExtra(RES_LAYOUT, resId);
intent.putExtra(FOLLOW_UP, followup);
context.startActivity(intent);
}
}
The abstract class:
public abstract class FollowUpListener implements Serializable {
public abstract void onClick();
}
The problems are stated in the comment in source code above, with tag "!!" (Just CTRL+F "!!"). What I want to do is like passing a Delegate object (function in form of variable) in C#, but in Android Java.
Any idea? Thanks.
You are trying to add a Serializable extra to your Intent, but OnClickListener does not implement that interface. You can achieve what you want by creating a class that implements both of the interfaces you need.
private class SerializableClickListener implements View.OnClickListener, Serializable {
#Override public void onClick() {
// TODO handle click
}
}
However, just because you can doesn't mean you should. Sending a click listener to another activity is a horrible code smell, and you should really rethink how you could do this via Intents/Broadcasts.
I tried to pass the OnlclickListener and I couldn't. then I tried this solution.
I made a static click listener variable in a GlobalData class
public static View.OnClickListener btn;
Then when I call the startactivity to go to another activity I did this.
GlobalData.btn = new View.OnClickListener() {
#Override
public void onClick(View v) {
//Listern action
}
};
c.startActivity(new Intent(c, DialogActivity.class));
Then in the second activity, I can set the static listener reference which I used to assign a listener object in the first activity.
b1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(GlobalData.btn!=null){
GlobalData.btn1.onClick(v);
}
finish();
}
});
I didn't use it directly as a parameter so I can do other stuff in the second activity listener. this worked for me.
But you have to think more because you are using a static reference. this is not a 100% solution. but it's worth trying.
I have a 'MainActivity class', inside that i have the object of radio button. i have an another class 'classB' inside the 'MainActivity' how can i able to access radio buttons checked state "RB1.isChecked()" from classB?
public class MainActivity extends Activity
{
public RadioButton RB1
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.test_layout);
RB1 = (RadioButton)findViewById(R.id.radioButtonA);
}
public class classB extends BroadcastReceiver
{
}
}
Make radio button static so you can access it in any other class.
public static RadioButton RB1;
In classB access Radiobutton using MainActivity.RB1
The rb1 object is accessible with in your nested class so use it like this:
rb1.isChecked()
public class classB extends BroadcastReceiver
{
void doSomething(){
if(rb1.isChecked()){
//place your code here
}
}
class B is an Non Static Inner class so it can access members of its enclosing class without any change:
http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html
Both the above answers are correct even if you need to use the Class B else where you can use the sharedpreferences like this
SharedPreferences prefs1 = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
save the state of the radiobutton inside onCheckedChangeListener
onCheckedChange(boolean ischecked)
{
SharedPreferences.Editor editor = prefs1.edit();
editor.putBoolean("confirm", isChecked);
editor.commit();
}
and then you can access this anywhere
boolean rbcheckedState=prefs1.getBoolean("confirm",true);
public class Activity01 extends Activity implements OnClickListener,
ViewFactory {
...
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout main_view = new LinearLayout(this);
m_Switcher = new ImageSwitcher(this);
main_view.addView(m_Switcher);
m_Switcher.setId(SWITCHER_ID);
m_Switcher.setFactory(this);
m_Switcher.setOnClickListener(this);
setContentView(main_view);
...
}
public void onClick(View v) {
...
}
}
Above code is from an Android project, and below function's argument is set as 'this', why?
m_Switcher.setOnClickListener(this);
According to the javadoc, here should be like below:
public void setOnClickListener (View.OnClickListener l)
That means the argument should be this kind: View.OnClickListener
So why 'this' can be there? Thanks!
Note: According to the answers, I gave a more complete code above.
In the class declaration you will find it either extends or implements OnClickListener. That means that the class can be used as an OnClickListener (because it is one, amongst other things). That is why you can use this here.
I have extended Dialog to create a popup with a edittext. My plan is to use this popup in a few places within my code. I want to set the edittext when the popup is opened from the class it is opening
Trouble I am having is the settext method gives a nullpointer
public class RoundCommentDialog extends Dialog implements View.OnClickListener {
private Context context;
private String roundCommentText;
private EditText roundCommentEditText;
private Button postiveButton;
private Button negativeButton;
public RoundCommentDialog(Context context) {
super(context);
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.custom_round_comment_dialog);
postiveButton = (Button) findViewById(R.id.dialog_positive_button);
postiveButton.setOnClickListener (this);
negativeButton = (Button) findViewById(R.id.dialog_negative_button);
negativeButton.setOnClickListener (this);
roundCommentEditText = (EditText) findViewById(R.id.comment_text);
}
public void setRoundCommentText(String roundCommentText) {
this.roundCommentText = roundCommentText;
}
public String getRoundCommentText() {
return roundCommentEditText.getText().toString();
}
public void updateCommentEditField() {
roundCommentEditText.setText("TEST");
}
public Dialog getDialog() {
updateCommentEditField();
return this;
}
public void onClick(View v) {
switch (v.getId()) {
case R.id.dialog_positive_button:
setRoundCommentText(roundCommentText);
dismiss();
break;
case R.id.dialog_negative_button:
cancel();
break;
}
}
}
from the class I am calling it from I create new version of the class and then call the setRoundComment(test) method and then the show method. this gives a nullpointer
Thanks for your time
EDITTED
Baisiclly I am calling the class above from the main class
RoundCommentDialog myDialog = new RoundCommentDialog(this);
Then I am doing the following on a Button Listenerer
myDialog.setRoundCommentText(roundComentText);
myDialog.getDialog().show();
When Errors it is erroring when I call the GetDialog() and within the dialog class it was erroring on the following line
roundCommentEditText.setText("TEST");
Try changing the
private String roundCommentText;
to
public String roundCommentText;
I'm no expert with strings but that's what I would try first