I am working on an android app that launches two activities using the on click listener everything in my code checks out fine except where the public void onClick(View v) begins I have multiple errors starting on that line and I am unable to run the code? I would kindly appreciate any help as I am fairly new to this. My code is as follows
public class Safaricom extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.safaricom);
Button button1 = (Button)findViewById(R.id.button1);
Button button2 = (Button)findViewById(R.id.button2);
button1.setOnClickListener(buttonClickListener);
button2.setOnClickListener(buttonClickListener);
}
private OnClickListener buttonClickListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = null;
switch(v.getId()){
case R.id.button1:
intent = new Intent(this, Second.class);
break;
case R.id.button2:
intent = new Intent(this, SignUp.class);
break;
}
if (intent != null)
this.startActivity(intent);
}
};
}
The Errors are at two points.
First where it says public void on click view ( The Error is - Multiple Markers at this line - implements android.view.View.OnClickListener.onClick- The method onClick(View) of type new View.OnClickListener(){} must override a superclass )
Second where it says this.startActivity(intent); (The Error is -The method startActivity(Intent) is undefined for the type new View.OnClickListener(){})
Instead of this use v.getContext() or YOUR_ACTIVITY.this
Actually If you read the Docs carefully, you will know that Intent parameters contain Activity so when you are using this it means that you are giving a parameter of type new View.OnClickListener
Well, I can see right off a couple of errors. To make it clearer since it apparently was not clear by simply looking at the code and learning. I added Safaricom.this in each of the new Intent statements. This is because the Intent constructor needs a Context as the first argument and an OnClickListener is not a Context, you need to ge the enclosing Activity which is a context. One other edit, I missed, the startActivity also needs to have Safaricom prepended.
public class Safaricom extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.safaricom);
Button button1 = (Button)findViewById(R.id.button1);
Button button2 = (Button)findViewById(R.id.button2);
button1.setOnClickListener(buttonClickListener);
button2.setOnClickListener(buttonClickListener);
}
private OnClickListener buttonClickListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = null;
switch(v.getId()){
case R.id.button1:
intent = new Intent(Safaricom.this, Second.class);
break;
case R.id.button2:
intent = new Intent(Safaricom.this, SignUp.class);
break;
}
if (intent != null)
Safaricom.this.startActivity(intent);
}
};
}
For the first error
The Error is - Multiple Markers at this line - implements android.view.View.OnClickListener.onClick- The method onClick(View) of type new View.OnClickListener(){} must override a superclass )
Try removing the #override
If that doesn't remove the second error then let us know if there is a different issue arising.
Related
I've been trying to find out the back navigation button to lead to another activity.
Every time when I pressed the back button, it goes to the previous activity which is not what I want. I would like to set the back button that goes to another activity I want, instead of previous one.
For example, I have Activity 1, 2 and 3. I was in Activity 2 and just moved to Activity 3. But when I press the back button, it goes automatically to the previous activity which is Activity 2. I want to make it to Activity 1 and not Activity 2. Can anyone suggest me a solution please?
You can make the button to go to a specific activity, instead of having the default behavior that you described.
It can be something like this:
#Override
public void onClick(View v) {
Intent intent = new Intent(Activity2.this, Activity3.class);
intent.putExtra("variable", information); //this is optional, but can be useful if you need to send a specific info to the next activity
startActivity(intent);
}
Activity 2 is parliamonar, and Activity 3 is federalparliamentary. I replaced parliamonar with Activity 1, but it still didn't solve the problem.
public class federalparliamentary extends AppCompatActivity {
Button federal;
private Object parliamonar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_federalparliamentary);
federal = findViewById(R.id.back160);
federal.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent reserve = new Intent(getApplicationContext(), parliamonar.class);
startActivity(reserve);
}
});
federal = findViewById(R.id.next164);
federal.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent reserve = new Intent(getApplicationContext(), sar.class);
startActivity(reserve);
}
});
}
public void onClick(View V) {
Intent back = new Intent((Context) parliamonar, federalparliamentary.class);
startActivity(back);
}
}
public class federalparliamentary extends AppCompatActivity {
Button federal;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_federalparliamentary);
federal = findViewById(R.id.back160);
federal.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent reserve = new Intent(getApplicationContext(), parliamonar.class);
startActivity(reserve);
}
});
federal = findViewById(R.id.next164);
federal.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent reserve = new Intent(getApplicationContext(), sar.class);
startActivity(reserve);
}
});
}
public void Onclick(View v) {
Intent intent = new Intent(federalparliamentary.this, politicalsystem.class);
startActivity(intent);
}
}
Activity 1 is "politicalsystem".
I added with #Override method, but it says that I have to remove the method, so I added outside, then it says that I have to extract interface, so clicked on it, then it gave me a bunch of list. So I chose onClick(v:View ):void, but it still didn't solve the issue. I tried in another way without #Override, but nothing changed when I tested my app. I also tried inside onCreate method which did not modified the navigation as I desired.
I'm a noobie making a quiz in Android Studio and i'm trying to pass an integer between activities to add to the amount of questions they got correct for the end but in the second activity it isn't changing when I answer the first question correct.
Question1 activity:
public class Question1 extends AppCompatActivity {
public int correctAnswers = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_question1);
Intent intent = new Intent(Question1.this, Question2.class);
Intent i = getIntent();
Intent answersCorrect = new Intent(Question1.this, Question2.class);
answersCorrect.putExtra("correctAnswers", correctAnswers);
}
public void submitQuestion1(View view) {
EditText question1TextInput = (EditText) findViewById(R.id.question1TextInput);
if (question1TextInput.getText().toString().length() >= 1) {
startActivity(new Intent(Question1.this, Question2.class));
if (question1TextInput.getText().toString().toUpperCase().contentEquals("FATHER")) {
correctAnswers += 1;
Intent answersCorrect = new Intent(Question1.this, Question2.class);
answersCorrect.putExtra("correctAnswers", correctAnswers);
}
}
}
}
Question2 Activity:
public class Question2 extends AppCompatActivity {
public int correctAnswers;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_question2);
Intent intent = getIntent();
int number = intent.getIntExtra("correctAnswers", 0);
TextView myAwesomeTextView = (TextView)findViewById(R.id.text);
myAwesomeTextView.setText(String.valueOf(number));
}
}
you duplicate your intent here:
Intent intent = new Intent(Question1.this, Question2.class);
Intent i = getIntent();
Intent answersCorrect = new Intent(Question1.this, Question2.class);
answersCorrect.putExtra("correctAnswers", correctAnswers);
replace it to:
Intent intent = new Intent(Question1.this, Question2.class);
intent.putExtra("correctAnswers", correctAnswers);
startActivity(intent);
in your second Activity:
int correctAnswers;
correctAnswers = (int) getIntent().getIntExtra("correctAnswers", 0);
So basically, when you have one activity and want to open a second activity, an Intent is the most important thing to have. It's responsible for communcation between your system and your application.
Intent is responsible for starting an activity, starting a service, and delivering a broadcast.
Note that there are two different types of intent: Explicit and Implicit.
Explicit Intent is used in this manner:
You have Activity_1 and you KNOW that you want to start Acticity_2 FROM Activity_1.
Implicit Intent is used when you DON'T know the name of the activity that you want to start.
Now, I know you probably understand what the StartActivity() method DOES, but StartActivity always requires an intent to go into the parenthesis. StartActivity(Activity_2); will not work.
So, when using Explicit Intent:
Intent i = new Intent(Activity_1.this, Activity_2.class);
StartActivity(i);
You start with making a reference - i - and, inside the parameters, the first being the activity from which you are calling the second activity, and the second being the activity which you want to call.
Here's a video on Intents as well: https://youtu.be/FH1Ym1KjJNc
Hope this helped.
Move the intent to a field. You only need it once.
Then, the issue is that you start the other activity too soon, without setting any value. You started the other activity with an empty, new Intent
public class Question1 extends AppCompatActivity {
public int correctAnswers = 0;
final Intent answersIntent = new Intent(Question1.this, Question2.class);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_question1);
}
public void submitQuestion1(View view) {
EditText question1TextInput = (EditText) findViewById(R.id.question1TextInput);
String answer = question1TextInput.getText().toString();
// No need to check for length if directly checking another string
if (answer.toUpperCase().contentEquals("FATHER")) {
answersIntent.putExtra("correctAnswers", ++correctAnswers);
startActivity(answersIntent);
}
}
If you plan on sharing that value over many questions, try SharedPreferences.
FWIW, make a generic View for any question that has the question text and possible answer fields. Try not to make one activity per question.
Is it possible to define the source of a click? I can access my MainActivity through either clicking on a RecyclerView or through a Notification action. Depending on which it is, I need to provide different info. Is there a way of saying: if click is from recyclerview then..., else if it is from notification action then...?
What I can think of so far is this, but the problem is I am not using buttons as such:
Button mClickButton1 = (Button)findViewById(R.id.clickButton1);
mClickButton1.setOnClickListener(this);
Button mClickButton2 = (Button)findViewById(R.id.clickButton2);
mClickButton2.setOnClickListener(this);
public void onClick(View v) {
switch (v.getId()) {
case R.id.clickButton1: {
// do something for button 1 click
break;
}
case R.id.clickButton2: {
// do something for button 2 click
break;
}
}
}
Thanks!
you have to define two different calling intents for the same activity and put info for each View Example :
mClickButton1.setOnClickListener(new onClickListener(){
public void onClick(View v) {
Intent view1_int = new Intent (this, MainActivity.class);
view1_int.putExtra("Calling Intent" ,"RecyclerView");
startaActivityForResult(view1_int);
}
});
mClickButton2.setOnClickListener(new onClickListener(){
public void onClick(View v) {
Intent view2_int = new Intent (this, MainActivity.class);
view1_int.putExtra("Calling Intent" ,"Notification action");
startaActivityForResult(view1_int);
}
});
and in the onCreate Method in your MainActivity you can say :
String callin_view;
callin_view =getresources.getIntent.getExtras("Calling_Intent");
This will retrieve the name of the calling source you defined
I have this Activity:
public class WelcomeActivity extends ActivityBase {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
setContentView(R.layout.welcome);
final OnClickListener Click = new OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(WelcomeActivity.this, WelcomeDoneActivity.class);
startActivityForResult(intent, 0);
setResult(RESULT_OK);
finish();
}
};
((TitleBar)findViewById(R.id.theTitleBar)).setOnClickCloseListener(Click);
}
And this test:
#Test
public void clickingLogin_shouldStartLoginActivity() {
WelcomeActivity activity = Robolectric.setupActivity(WelcomeActivity.class);
activity.findViewById(R.id.theTitleBar).performClick();
Intent expectedIntent = new Intent(activity, WelcomeDoneActivity.class);
assertThat(shadowOf(activity).getNextStartedActivity(), equalTo(expectedIntent));
}
how come I get an assertion error?
java.lang.AssertionError:
Expected: <Intent { cmp=com.w/.profile.WelcomeDoneActivity }>
but: was null
Update
I have tried this as well but the startedIntent == null
ShadowActivity shadowActivity = shadowOf(activity);
Intent startedIntent = shadowActivity.getNextStartedActivity();
// ShadowIntent shadowIntent = shadowOf(startedIntent);
// String name = startedIntent.getIntentClass().getName();
// assertThat(shadowIntent.getIntentClass().getName(), equalTo(targetActivityName));
Change:
shadowOf(activity).getNextStartedActivity()
To:
shadowOf(activity).getNextStartedActivityForResult()
In the code you posted, you are setting the onClick on the TitleBar via setOnClickCloseListener.
It looks like your TitleBar is a custom view, and the setOnClickCloseListener to me implies there is a 'close' button or view on the TitleBar that performClick() should be called on, not the TitleBar itself, in order for Robolectric to behave the way you expect.
It's hard to tell without knowing the TitleBar and setOnClickCloseListener implementation, but:
1) If you just want to click the TitleBar to launch the new activity,
then change setOnClickCloseListener to setOnClickListener,
Or
2) If the TitleBar contains a view of the close button/view (or whatever "ClickClose" refers to in setOnClickCloseListener!), delve into the TitleBar layout to find the ID of this view, and call performClick on that, it should resolve your issue.
I had a very similar problem before where i wanted to show random xml layouts. I've done that - with lots of help by Ben Williams - with a class named DisplayRandomPage.class and I had a main.xml layout with four buttons.
That's the code of the Main.class:
switch (view.getId()) {
case R.id.first_button:
startActivity(new Intent(this, FirstPage.class));
break;
case R.id.second_button:
startActivity(new Intent(this, SecondPage.class));
break;
case R.id.third_button:
startActivity(new Intent(this, ThirdPage.class));
break;
case R.id.random_button:
Intent intent = new Intent(this, DisplayRandomPage.class);
startActivity(intent);
and this is in the DisplayRandomPage.class:
public class DisplayRandomPage extends Activity {
private Integer [] mLinearLayoutIds = {
R.layout.one
R.layout.two,
R.layout.three
};
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Random random = new java.util.Random();
int rand = random.nextInt(3);
setContentView(mLinearLayoutIds[rand]);
}
}
What i'd like to do is creating a DisplaySpecificPage.class. Above I've shown my main.class with the switch-case-clause. So when i click on the first button, it will start the FirstPage.class, clicking the second, it will start SecondPage.class, and so on. So for each xml-file i have to create a new java-class although the different java-classes do all the same. Only the xml-files are different. So i'd like to put something like this:
pseudo-code:
case R.id.first_button:
startActivity(new Intent(this, DisplaySpecificPage.class)) with R.layout.first_page;
break;
how do i pass the ID from the layout (R.layout.first_page) on?
You should change your switch statement to
final Intent intent = new Intent(this, DisplaySpecificPage.class);
switch (view.getId()) {
case R.id.first_button:
intent.putExtra("mylayout", R.layout.one);
break;
case R.id.second_button:
intent.putExtra("mylayout", R.layout.two);
break;
case R.id.third_button:
intent.putExtra("mylayout", R.layout.three);
break;
case R.id.random_button:
intent.putExtra("mylayout", randomNumber);
startActivity(intent);
}
startActivity(intent);
This way you'd start the same activity no matter which button would be pressed, and inside the DisplaySpecificPage activity's onCreate method you should set the content to this passed layout:
final int layout = getIntent().getIntExtra("mylayout", R.layout.one);
setContentView(layout);
The code above passes an extra parameter to the intent when starting the DisplaySpecificPage activity, with the name: "mylayout".
Inside the DisplaySpecificPage class' onCreate method you just retrieve this extra parameter using the getIntExtra method of the passed intent (getIntent() will return it for you), and you set the content view of this DisplaySpecificPage activity to the passed layout by setContentView(layout).
You should make sure though, to always pass a valid layout identifier to that intent, otherwise you'll get exception when trying to inflate it (so randomNumber should be selected properly).
Update
With adding extras to the Intent you can parametrize your activities.
So using intent.putExtra("paramName", paramValue) you'll pass the paramValue value on the name of paramName to the activity you start by this intent.
You want to start the DisplaySpecificPage activity, but want it to have different layout based on which button you click.
So you create an intent:
final Intent intent = new Intent(this, DisplaySpecificPage.class);
Before starting the activity by calling startActivity(intent), you have to put this extra information inside the intent, so the DisplaySpecificPage activity to know which layout it should set as its content view:
So if you pressed the second button, you want the layout of your new activity to be the one defined by the two.xml inside your res/layout folder. It is referenced by as R.layout.two (which is a static int value).
intent.putExtra("mylayout", R.layout.two);
This line puts the layout's value as an extra into the intent object, and now you can start the activity, the layout reference will be passed to it.
The "mylayout" is a name you choose for your parameter. It can be anything (valid), it will be used inside the DisplaySpecificPage activity to retrieve the layout's reference. It is retrieved by this name:
final int layout = getIntent().getIntExtra("mylayout", R.layout.one);
The getIntExtra method gets the integer value from the intent which has the name "mylayout", and if it's not found, then it will return R.layout.one.
If you want to handle this case (when no parameter with name mylayout is set), you can write
final int layout = getIntent().getIntExtra("mylayout", -1);
if (layout < 0)
{
//TODO: no layout reference was passed
}
Here is my final code:
Main.class:
public class Main extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public void change(final View view) {
Intent intent2 = null;
final Intent intent = new Intent(this, DisplaySpecificPage.class);
switch (view.getId()) {
case R.id.first_button:
intent.putExtra("mylayout", R.layout.layout1);
break;
case R.id.second_button:
intent.putExtra("mylayout", R.layout.layout2);
break;
case R.id.third_button:
intent.putExtra("mylayout", R.layout.layout3);
break;
case R.id.random_button:
intent2 = new Intent(this, DisplayRandomPage.class);
startActivity(intent2);
}
// if the Random button was not clicked, if-condition is true.
if (intent2 == null)
startActivity(intent);
}
}
DisplaySpecificPage.class:
public class DisplaySpecificPage extends Activity{
public void onCreate(Bundle savedInstanceState) {
final int layout = getIntent().getIntExtra("mylayout", R.layout.one);
super.onCreate(savedInstanceState);
setContentView(layout);
}
}
DisplayRandomPage.class:
public class DisplayRandomPage extends Activity {
private Integer [] mLinearLayoutIds = {
R.layout.layout1,R.layout.layout2,R.layout.layout3
};
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Random random = new java.util.Random();
int rand = random.nextInt(mLinearLayoutIds.length);
setContentView(mLinearLayoutIds[rand]);
}
}
Big thanks to rekaszeru!