How can I update the editText field with a button when the button and the editText are on different layouts and classes?
I have a mainActivity class and layout but I wand to add this function to an intent (by clicking the save button update main_activity layout). I tried by calling the saveDegrees method onClick in the intent class but that didn't work.
After that I want to go back to the main_activity layout. My saveDegrees code is this:
public void saveDegrees(View view) {
LayoutInflater inflater = getLayoutInflater();
View activityView = inflater.inflate(R.layout.activity_main, null);
mCompassEditText = (EditText) activityView.findViewById(
R.id.compass_edit_text);
mCompassEditText.setText(toString().valueOf(currentDegree));
}
You cannot access an activity from another activity. Instead, you should send the data back to the first activity. You can do this by starting the second activity with startActivityForResult() rather than startActivity(). The second activity sets the result before finishing. The first activity receives the result in onActivityResult() and changes its own views. See How to manage `startActivityForResult` on Android? for more details.
Related
I am designing a chatting app where I am required to make links clickable inside a TextView. I have used android:autoLink="all" in TextView to distinguish links/phones etc.
This works up to displaying the part of TextView that are links/phones as clickable but when I click it, I get the following exception:
android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
I searched a bit and it seems that I need to pass the activity context while inflating the TextView from XML. But how can I do that as i am inflating this view inside an adapter? This TextView is part of card view that is part of a recycler view in an adapter.
Instead of using layoutInflater.inflate() to inflate the view, I used LayoutInflater.from(parent.getContext()).inflate() and it worked.
Either use the Parent Activity to start a new activity from adapter or set the Intent flag.
For parent activity pass the Activity to Adapter's Construcutor and initialize it to use in the adatper like this.
in you MainActivity
Activity activity = this;
MyAdapter _adpater = new MyAdapter(....., activity);
in MyAdapter class
//constructor
Activity activity;
public MyAdapter (......, Activity _activity) {
........
this.activity= _activity;
}
now you can use this activity to start new activity.
activity.startActivity(new Intent(activity,target.class));
or you can try setting the flag with your current method.
context.startActivity(new Intent(context.getApplicationContext, target.class).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
I have a three different activities all of whom switch to a common Activity via Intent, with only minor modifications in the appearance of the child or switched-to Activity. I want to change the text of the TextView, so that each time the child activity displays a different text based on which activity it was switched-to from.
I have tried using this:
Button startSendingLocation = (Button) findViewById(R.id.wmb_start_sending_button);
startSendingLocation.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(view.getContext(), ll_wmb_Map.class);
startActivity(intent);
TextView bmo_map_toolbar_title = (TextView) findViewById(R.id.wmb_toolbar_title);
bmo_map_toolbar_title.setText(R.string.ll_bmo_toolbar_title);
}
});
But this doesn't update the text in the TextView. Am I doing it wrong ?
Should I create three different Activities with their own layouts to achieve this ?
Will I be able to add or update a few views, differently, based on the activity I am switching from ?
I thought switching to the same activity via Intent will be a good idea for code-reusability and some efficiency gains as the child activity makes use of a MapFragment in all the three cases.
ll_wmb_Map.class : The common activity that is being switched to, using Intent
wmb_toolbar_title : The id of the TextView I want to change
ll_bmo_toolbar_title : The text I want to set in the TextView
Fine, If you just want to enable/disable the view and change the textview content, you just need to use enable and disable functionality within onclick listeners instead of calling the same activity again and again.
startSendingLocation.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
bmo_map_toolbar_title.setText(R.string.ll_bmo_toolbar_title);
//enable/disable the views
}
});
I'm trying to build a quiz-like app for guessing flags in android. Basically i have an activity named SetFlagActivity which receivs intent from the startFlagActivity(View v) in MainActivity if a button is clicked . It needs to do two things: # 1 if the user inputs correct name of the flag load a new flag and # 2 display message: "correct" else just display "wrong".
When the button is pressed the correct message is displayed, but the ImageView containing the image of the flag disappears. Also when the button is clicked again application crashes with following output:
I assumed that image doesn't appear because it's displayed in MainActivity, so i used finish() to go back. That fixed the app crashing, but again when i click the button nothing happens...no message is displayed. So the question is how do i use SetFlagActivity in a correct way that it displays my message and sets a new image..
Any help will be apreciated.
This gets the input and sends an intent
public void startFlagActivity(View v){
EditText flagInput = (EditText) findViewById(R.id.inputFlag);
String message = flagInput.getText().toString();
Intent intent = new Intent(MainActivity.this, SetFlagActivity.class);
if(!message.equals(""))
intent.putExtra("flag", message);
MainActivity.this.startActivity(intent);
}
And my SetFlagActivity looks like this:
package ivve.projects.flags;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;
public class SetFlagActivity extends Activity {
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button= (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startFlagActivity(v);
}
});
TextView text = (TextView) findViewById(R.id.displayAnswer);
Intent intent = getIntent();
String value = intent.getStringExtra("flag");
if(value.equals("Iceland")){
text.setText("correct");
}
else{
text.setText("wrong");
}
finish();
}
}
Edit1: StartFlagActivity is actually not an activity by itself...it is a function inside the MainActivity
Edit2: I have added the onClick handler to my SetFlagActivity as suggested, but i get an error "The method startFlagActivity(View) is undefined for the type new View.OnClickListener(){}" which doesn't allow me to call to startFlagActivity method
You have declared the button (id = button) in activity_main.xml and set the button's OnClickListener through the onClick attribute to refer to the startFlagActivity method. What you are trying to do is to check if the TextView contains the correct answer and if yes, then proceed else remain in this page. One suggestion off topic would be to initialize the TextView variable within onCreate(). Here while it works for you, you are re-initializing it every time you click.
You have now inflated this view in MainActivity.
setContentView(R.layout.activity_main.xml); // This inflates the layout.
// Now you dynamically have set the flag. This is not part of the activity_main.xml
You have declared startFlagActivity() in MainActivity() and the logic behind it is that the new Activity should be started (when the button is clicked) with the answer passed in as a parameter to the intent. The newly started intent will check if the answer is correct and if yes, will display correct.
Now to answer your first question that the image view disappears. This happens because you have inflated activity_main.xml - but the ImageView was created dynamically in MainActivity and does not exist in SetFlagActivity (there basically is no image in this screen). This is why the map disappears but you see the rest of the layout as it remains the same.
Then, when you again click the button, the onClick() method (or in this case the startFlagActivity() method) does not exist for the activity SetFlagActivity currently being displayed and that was why you received the error log that said that the onClick() method startFlagActivity() does not exist for the SetFlagActivity screen. I hope this makes sense. Clicking the button now will not produce anything as there is no code to back it up (also produces error logs). I hope you see now where your logic is flawed.
You don't need to start a new activity. You can finish it off based on if-else conditions. Your algorithm would be:
If (answer = correct)
setImageView -> new drawable;
repeat process;
else
show wrong and repeat;
I hope this helps.
03-08 20:52:59.539: E/AndroidRuntime(9399): java.lang.IllegalStateException: Could not find a method startFlagActivity(View) in the activity class ivve.projects.flags.SetFlagActivity for onClick handler on view class android.widget.Button with id 'button'
03-08 20:52:59.539: E/AndroidRuntime(9399): at android.view.View$1.onClick(View.java:2131)
you forgot to declare startFlagActivity(View) inside SetFlagActivity. Maybe you have set the wrong layout in SetFlagActivity
I'm currently working in an Activity which saves text from three EditViews and constructs a SQL query. After that, the query is given to another activity to search and display the results.
Right now I've got two buttons, one to save the query, inside an onClickListener and another button to start the second activity:
searchButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//First the data from the editviews is saved
EditText searchName = (EditText) findViewById(com.pedro.books.R.id.search_name);
search_name = searchName.getText().toString();
searchName.setText("");
EditText searchAut = (EditText) findViewById(com.pedro.books.R.id.search_aut);
search_aut = searchAut.getText().toString();
searchAut.setText("");
EditText searchYea = (EditText) findViewById(com.pedro.books.R.id.search_yea);
search_yea = searchYea.getText().toString();
searchYea.setText("");
//here i construct the query
});
And with an onClick in the xml code, I start the activity with another button:
public void ReadResults(View view){
//The query is given to the ReadActivity to display the results
Intent intent = new Intent(this, ReadActivity.class);
intent.putExtra(ReadActivity.EXTRA_QUERY, query);
startActivity(intent);
}
I've tried with the same button for both without changing anything and it obviously doesn't work, and I've also tried to start the activity inside the onClickListener, but I got this error: "The constructor Intent(new View.OnClickListener(){}, Class) is undefined"
Is there a way to start the activity inside the onClickListener or to stop the second activity to start until the query is saved?
Thanks in advance!!
if you are putting the intent in the onClick of a button you cannot use this you need to use YourActivity.this to properly get context.
this in your button is your OnClickListener like the error says
Where/How do you call your ReadResults method? On a side note - does it need to be public? If you call it inside the clickListener handler then that's wrong.
1) Extract your code out of the clickListener handler and have it into a private method within your activity class.
2) Your clickListener should only call that private method.
3) You could have your 3 editboxes as memebers of your activity and instantiate them onCreate() instead of getting them each time you click the button, it's expensive parsing the UI if not necessary.
I'm a beginner in Android and I'm testing my code using Android JUnit test.
So, I have a test activity that extends ActivityInstrumentationTestCase2<Activity>.
Activity has it's own layout in onCreate() method. (Main layout)
In my XML, I have a onClick attribute for a button that calls foo() method.
Back to Activity, in the foo(View v), I set my content view to a different layout.
I want to test that layout.
How do I get the layout though??
I know for the main layout, I can do this.
Activity act = getActivity();
View mainLayout = (View) act.findViewById(bla.bla.bla.R.id.main_layout);
How do I get the layout that I set in foo(View v)??
I've already tried doing,
fooLayout = (View) act.findViewById(bla.bla.bla.R.id.foo_layout);
and
act.setContentView(bla.bla.bla.R.layout.foo_layout);
fooLayout = (View) act.findViewById(bla.bla.bla.R.id.foo_layout);
I think I got NullPointerException for the first one and android.view.ViewRootImpl$CalledFromWrongThreadException
for the second one.
In your first try you get a NullPointerException because you are searching for your foo_layout wihtin your main_layout. findViewById is used to search for views wihtin a layout and not to find/inflate layouts. In your second try you get a CalledFromWrongThread Exception because you access the UI (setContentView()) from outside the UI thread. This is how you change the layout wihtin your test class:
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
getActivity().setContentView(R.layout.foo_layout);
}
});
getInstrumentation().waitForIdleSync();
// now you can access your views from your foo_layout via getActivity().findViewById(...)
I don't know what you mean by "I want to test my layout". Either you want to check if your layout got successfully loaded through a button click or you want to access the views of the new (loaded) layout. In both cases you can do something like the following:
public void testLayout() {
// get your button that changes the layout of your activity.
// that button is in your main_layout
final Button btChangeLayout = (Button) getActivity().findViewById(R.id.yourButtonThatChangesTheLayout);
// perform a click in order to change the layout
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
btChangeLayout.performClick();
}
});
getInstrumentation().waitForIdleSync();
// get a reference of a view thats in your foo_layout e.g. a Button
Button aButtonInYourFooLayout = (Button) getActivity().findViewById(R.id.aButtonInYourFooLayout);
// now you can do what your want with your button/view.
//if you just want to know wheter your layout has successfully been loaded
//or not you can test your view if it's null
assertNotNull(aButtonInYourFooLayout);
}
i'm not sure ... but i think the first problem is:
act.setContentView(bla.bla.bla.R.id.foo_layout);
change to:
act.setContentView(bla.bla.bla.R.layout.foo_layout);
because in res/layout/ you have your UI, isn't it?