What is the best approach for navigating between "windows" in an android app?
I say "windows" because I dont the proper terminology in java. I just started.
Lets say the first screen the user sees is a username and password input with a button. On successful login, it shows a whole new "window" with relevant logged in information?
I attempted putting 2 EditTexts and a Button inside a view (using the Main.xml graphical layout tab[eclipse]) in main.xml, but it did not like that.
This is a excerpt from the page http://developer.android.com/guide/topics/fundamentals.html
Activities
An activity represents a single screen with a user interface. For example, an email application might have one activity that shows a list of new emails, another activity to compose an email, and another activity for reading emails. Although the activities work together to form a cohesive user experience in the email application, each one is independent of the others. As such, a different application can start any one of these activities (if the email application allows it). For example, a camera application can start the activity in the email application that composes new mail, in order for the user to share a picture.
Here's an tutorial on how to switch between activities: http://www.warriorpoint.com/blog/2009/05/24/android-how-to-switch-between-activities/
Don't for get to add every activity to AndroidManifest.xml!
You can consider activities as being "windows" for android.
Create different layout XMLs for your different activities and on a button click from activity A start activity B and close A... to give an example:
// in activity A for the button click:
public void onButtonClick(View view) {
Intent intent = new Intent(this, B.class);
activity.startActivity(intent);
activity.finish();
}
// in activity B you have:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.B); //using your B.xml layout
}
The Android way of doing it is to use an Activity for each 'window', as you call them. You move between Activities by using startActivity().
You shouldn't have any problem putting 2 edittexts & a button inside an xml layout, so the problem you're having is probably related to something else. Have you checked the log output for errors? Something that gets a lot of newcomers is that you have to declare every Activity in your mainfest file, otherwise Android will not load it.
The "windows" in Android are called Activities and you move between them with Intents.
Intent intent = new Intent(GroupPickerActivity.this, SmsActivity.class);
startActivity(intent);
There's a lot to understand, I'd recommend going through some tutorials before diving right in. For each "window" (called content views in android), there should be an underlying Activity.
The Labs taught here from a college course at Cal Poly SLO helped me get very familiar with Android quickly.
Intent intent = new Intent(this,
otherclassname.class);
intent.putExtra("userid", userfield); //sends the userid
startActivity(intent);
public void onCreate(Bundle
savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.showhistoricweek);
senduserid = getIntent().getIntExtra("userid", 0); //gets the userid
Related
I have a problem for implementing up navigation on an app with this navigation tree:
The standard implementation of the back button is fine.
The problem start when trying to implement the Up button.
What I expect:
when the user is on Detail 5 Activity and press the up button the app goes to List 3 Activity
when the user is on Detail 7 Activity and press the up button the app goes back to Home Activity
So in different terms, I'd like to have this behaviour on the back stack:
The Android documentation (Implementing Ancestral Navigation) advice to use the following code to handle up navigation:
Intent parentActivityIntent = new Intent(this, MyParentActivity.class);
parentActivityIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(parentActivityIntent);
finish();
But because the parent activity of the Detail Activity differs on the different navigation path I don't know which one it really is. So I can't call it in the Intent.
Is there a way to know the real parent activity in the Android back stack?
If not, is there a way to implement a correct up navigation in this app?
I will stick with my comment on Paul's answer:
The idea is to have a Stack of the last Parent Activities traversed. Example:
public static Stack<Class<?>> parents = new Stack<Class<?>>();
Now in all your parent activities (the activities that are considered parents -e.g. in your case: List and Home), you add this to their onCreate:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
parents.push(getClass());
//or better yet parents.push(getIntent()); as #jpardogo pointed
//of course change the other codes to make use of the Intent saved.
//... rest of your code
}
When you want to return to the Parent activity, you can use the following (according to your code):
Intent parentActivityIntent = new Intent(this, parents.pop());
parentActivityIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(parentActivityIntent);
finish();
I hope am right (:
That's a tricky question and in my opinion really shows the difficulties in coping with the UX decisions of Android for the "up button". Therefore, there's not a clear-cut answer to your problem.
I have two possible solutions for you.
1. Mimicking the back button behavior.
You could consider adding an extra to the intent for launching Detail from one of its various parents. This extra would inform those activities which activity they would need to launch when android.R.id.home is pressed.
This would effectively mean that your app "goes back" to its common ancestor, instead of simply relaunching Home.
Another way of implementing this may be simply executing onBackPressed() instead of launching Home with Intent.FLAG_ACTIVITY_CLEAR_TOP, but bear in mind that the associated animation would be different than a normal "up" action.
2. Skip intermediate activites and go home.
Some apps treat the "up button" as a "home button". You might want to consider having it simply always relaunch Home with Intent.FLAG_ACTIVITY_CLEAR_TOP.
this is an old post for sure, but as I was studying the SharedPreferences, I think it could be a possibility to stack this information within a sharedPreferences data, and to modify its value each time before going down the 2 parents.
Then by reading it, you should be able to directly know your parent, and this without having to build a whole class for that.
This is my very first post on StackOverflow.
Basically, my app starts by checking to see if a user record exists in my Sqlite Database. If yes, I would like it to display my main application screen. If not, I would like another screen to be displayed, prompting the user for a password.
This password screen is a new addition to my app. It originally just displayed the main screen like so:
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Then I would run the check for a user. If no user is found I display the password screen like so:
Intent myIntent = new Intent(this, loginScreenActivity.class);
startActivityForResult(myIntent, 0);
The problem is, if I decide to hit the BACK button to exit out of the application from the password screen, it goes back to the main screen.
How can I first run the check, then display one of the two views??
Hope this makes sense.
Thanks in advance.
When you navigate to the login screen, call finish() on the first screen
read the Activity documentation, it will be very helpful.
You need to set the FLAG_ACTIVITY_CLEAR_TOP if you never wan1t go back to this screen.
Or the secont one, override the onbackpressed() method and use finish() method inside in.
I intend to start 3 activities in a chain (like from main open Activities A, B and then C, which will be visible for the user), but I wasn't able to find some way how to do that in Android. Do not ask me why, I just have to do that for restoring my application state, where is was before.
Thanks for any ideas
Waypoint
Edit:
Ok, I have tried opening activities in For cycle, but they aren't opened properly. They are chained, but recreated only when I press back button and they display to me. I need some solution which leads to: open A, if A is opened check if needs to open B -> YES, open B, check if needs to open C -> YES, open C, no need to open another activity -> FINISH
prior to start any activity , decide which activity should be start .
Lets take your case >>first check for B , if yes check for C , now open the required 1 .
i understand comparable data is inside the activities, but a right data structure will always allow you to access the data wherever and whenever it actually requires .
For future readers: if you want to start activity with proper back stack, you should use TaskStackBuilder.
define the natural hierarchy for your activities by adding the android:parentActivityName attribute to each element in your app manifest file
create an instance of TaskStackBuilder and call addNextIntentWithParentStack(), passing it the Intent for the activity you want to start.
For more details see official documentation
Override the onResume-method in each activity. Add the check and the start of the activity there.
public void onResume() {
if( condition )
startActivity( intentForTheNextActivity );
}
Where condition is whatever condition you might have (in your example if B should be started, C should be started etc.) and intentForTheNextActivity is the intent for the following activity in the chain (e.g. if now in A, the intent is for B etc.).
I'm having a very hard time understanding exactly what it is you're trying to do. Sometimes it seems like it's a chain (A opens B, B opens C and so forth) sometimes it seems you want some random flow (A opens B, B opens A, A opens B, B opens C) - which makes it really hard to give you a specific answer.
What I can do, is recommend that you read up on the following:
Activity Lifecycle
Starting Activities and getting results (in particular the methods startActivityForResult and setResult)
If you need more help than this - you need to explain yourself better (maybe with a diagram or some sample code of what you have tried so far).
You didn't provide any information of what you've tried, so i'll give you the simplest answer:
method startActivity(Intent intent), more info here.
Edit: Hmm, how about this? I don't have SDK around me now, but i can provide a concept. I'm not sure if it works, but i hope it'll guide you to soultion.
Let's imagine this is ActivityA's code:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (doINeedActivityB) {
Intent activityC = new Intent(this, ActivityC.class);
this.startActivity(activityA);
}
if (doINeedActivityC) {
Intent activityC = new Intent(this, ActivityC.class);
this.startActivity(activityC);
}
}
in the main activity of my app i have placed a button named as setting, if i click the button it moves to a new page where i have placed two buttons.
if i click in any of those buttons i want its corresponding operations to be done in another activity,how to do this...
in the same way if i click a button in Activity A, i need a button to be completely invisible in some other Activity...
how to do this....
The best way is to pass messages through the Intent that you use to start an activity. This answer gives a detailed code sample for this.
You can send some data along with the intent, which you used to start the other activity.
For eg, in Activity A
Intent i = new Intent(this, B.class)
b.setBooleanExtra("isButtonVisible", false);
startActivity(i);
Now in Activity B, in it's onCreate() method, use
boolean isButtonVisible=getIntent().getBooleanExtra("isButtonVisible);
if(!isVisible)
button.setVisibility(View.INVISIBLE) //Or do something with that
I think you got the idea now?
Is there a way to dynamically change the starting activity in Android based upon a conditionally? What I attempted to do (that didn't work) was the following:
remove the LAUNCHER category as defined in my AndroidManifest.xml
create a custom Application class that the app uses
override the onCreate method of my Application class to define some code like the following:
.
if (condition) {
startActivity(new Intent(this, MenuActivity.class));
} else {
startActivity(new Intent(this, LoginActivity.class));
}
Why not have an initial Activity with no UI that checks the condition in its onCreate, then launches the next Activity, then calls finish() on itself? I've never called finish() from within onCreate() though, so I'm not sure if this will work.
EDIT
Seems to work fine. Here's some code to make it clearer.
Initial Activity:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent;
if (condition) {
intent = new Intent(this, ClassA.class);
} else {
intent = new Intent(this, ClassB.class);
}
startActivity(intent);
finish();
// note we never called setContentView()
}
Other Activity:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
Here's what I personally did for one of my small mobile projects. Instead of creating a separate, screen-less Activity where the condition is and which launches the corresponding screen, I put the condition in one Activity and did a dynamic setContentView(), as in:
if (!userIsLoggedIn) {
setContentView(R.layout.signup);
} else {
setContentView(R.layout.homescreen);
}
Two important notes to this approach:
1: Instead of writing that in onCreate(), you want to put the decision-making inside onResume() precisely because the latter is always called whenever the screen needs to be displayed in front. You can see that from the Android activity life cycle. So if, for example, the user just downloaded my app and launched it for the first time, because no user is logged in, she will be led to the signup page. When she's done signing up and for some reason presses the HOME button (not BACK, which exits the app altogether!) and then resumes the app, the layout that she will see is already the home screen's. If I put the conditional inside onCreate(), what would have been displayed is the sign up screen because according to the life cycle, it doesn't go back to onCreate() when bringing back an app to the front.
2: This solution is ideal only if merging the functionalities of those two Activities would not produce a long diabolical block of code. Like I said, my project was a small one (its primary feature occurs in the background), so that single dynamic Activity didn't have too much in it. The screen-less Activity is definitely the way to go if you need your code to be more human-readable.