I have a game menu, which is one activity, and an actual game, which is another activity.
I also have a custom Dialog class that displays a "Loading..." text and a spinning wheel. (I could add code, but it's almost identical to a normal ProgressDialog. Nothing special about it).
I wish to start displaying this dialog from the menu activity (when loading), and continue its display for after the transition to the game activity - until the game finishes loading.
Is that even remotely possible? I didn't fid a way to extend a Dialog over 2 activities. It seems to be bound to one.
Is that even remotely possible?
Not as far as I know. A Dialog is a UI element and as such exists withing the 'window' of the Activity which created it. Starting a new Activity obviously means it will cover the previous one and any Dialog it's currently showing.
It seems to me there are only two simple ways of doing what you want...
Make sure that what is 'loading' your game is running in some separate place (Service etc) and progress is accessible from both Activities then simply destroy the first Dialog when the second Activity is started, create a new Dialog and have it pick up from where the first one left off (with progress, messages etc).
If your menu and main game play can be hosted by Fragments then simply swap a menu Fragment to a game Fragment within a single Activity. That way the Dialog will continue to exist without interruption.
I don't think dialog can be extended with two activities, It actually requires a activity context to run. so if activity will be destroyed it will automatically leaked.
Please post answer if you find the way.
Related
So I've been really conflicted about whether to use fragments or just stick to activities while designing my app. From what I read a lot of issues/crashes can occur due to using fragments and it's much harder to debug/maintain.
I have a main activity which on it a handful of methods are performed. Each method is triggered after the previous one is completed, and upon initiation of each activity a dialog box pops up with variable content.
I was wondering if it would be possible to perform this using one main activity containing the primary methods to be executed and one dialog activity for popups, keeping in mind the content of the dialog box is a variable. Is that possible to achieve this without using fragments?
I want to be able to change which Activity is run when the user runs the application.
I know how to do this in the application's manifest file, but I would like to do it programmatically after install. The reason being, I want the user to be able to choose which screen loads when he opens the application.
How can I do this? The only way I know of seems very clunky: have an essentially empty Activity which has the MAIN intent-filter - which then reads the user's settings and transfers the user to the desired Activity. This creates a lot of mess, like the back-stack needs to be considered, and the overheads of loading one activity straight after another seems wasteful of time and resources.
You cannot change launcher activity dynamically.
As you said it is possible by saving user preferences and start desired activity each time. I have tried it and it is fast enough to not show itself. Don't remember to call finish on main activity. it will solve back stack problem.
Also you can use different fragments for different activities and decide which one should be added to main activity. It may be faster. However as I said it is fast enough to start a new activity and hide main activity because it is done in onCreate method. Don't worry about that.
Sorry, I know that this topic has been covered a bit. I've read the related posts and am still a bit confused. I am working on an app that while the prototype will have 3 main screens, it will eventually have dozens. Each screen will present either dynmically changing status or take user input. To visualize, it is required to be laid out similar to how MS Word or a typical PC is. It has a status bar at the top and a navigation bar at the bottom that is common to all screens (slight tweaks for some screens, like different icons) in the middle is what I would call a view pane that needs to be updated with a applicable layout.
The status, nav bar, and each screen are defined in their own layout xml file. For my first swag at it I just used a ViewFlipper and loaded the 3 screen layouts into it. However that means that currently I have one main Activity which will not be maintainable as I continue to add screens.
It feels right to me that each screen layout should have an associated Activity class that understands how to control that screen. I need to figure out how to load that into the center pane dynamically. However I thought I read in another post that using multiple Activities can be a CPU and RAM drain.
Currently I tried making one of the screens it's own Activity and kick that off from the main Activity by creating an Intent and than calling startActivity. However that causes the new screen Activity to reside on top of the main Activity. The interesting thing is that then pressing the back button dismissed that activity and returns me to the main.
So far I haven't figured out how to setup having a different Activity control what happens in the center pane.
If I continue down the multiple Activity path, should my main Activity be inheriting from ActivityGroup?
Are using View classes more applicable in this case?
I know this has been a long post. I'd appreciate any advice.
Thanks!
CB
As you noticed, Android will implicitly track a stack of started activities in a task, and the 'back' button ends the top one, reactivating the next one down. I would advise you to think about which kinds of things the user might expect the back button to do, and make it so that activities are separated along those lines.
I haven't played with ActivityGroup so I can't advise you there. If you go with completely separate activities, you can have them all use the same "shell" content view with the common nav/status bar. Have a superclass or utility class handle populating and managing that from there. Then use a a LayoutInflater (you can call getLayoutInflater()) to fill in the middle with your Activity-specific view.
If you want one of the activities to have multiple screens, you might still end up with a ViewFlipper in the center slot. Again, you want to have an Activity transition wherever you want the user to be able to go "back"; that also means you may NOT want to have a change of activities in cases where screens are closely related or part of the same logical thing-being-done. (You can override the back button's behavior, but unless you have a good reason to, it's best to just arrange the app so that Android's basic setup helps your app's UI rather than working at cross purposes.)
If you want to use activities in the fashion you talked about, you might look into using a tab activity. It actually works in the way you want, you just need to hide the tab widget and put your navigation bar there instead. Or, you could go a little deeper and make you own similar tab-like ActivityGroup like Walter mentioned if you have more time.
You could use a view pager with fragments to accomplish the flip between the different views but still allow your activity to have full control over it. The activity can control the menus while the fragment controls your viewing area. This way your back button will properly dismiss the activity containing all pages related to the activity instead of walking down the stack.
I was in the midsts of tinkering in android with the goal of trying to make this small exploration game. I actually got pretty far so far: a nice sprite system, a title screen with a main menu that is all in game code (no UI buttons or anything) that launch various activities. An activity that loads this cool map view, that when clicked on will load up another view of a more detailed "zoomed in" action part of a map. It all works pretty well but now I am left wondering how well I am going about this.
(What happens to a view when you instantiate and then move the set the context to a new view? I am guessing as long as the activity is alive all the instantiations of various views that an activity uses are still good? And in an activities onPause is when id have to save the data thats changed in these views to persist the state in the event the user quits the game etc.. ?)
I have three menu options at the start of the game. The main one is:
New Game
The new game, I launch my main map
activity that can launch three views:
First two are a loading screen for
the second, a map screen.
Third view is a more detailed action
orientated part that uses this sprite
engine I developed.
It all works pretty good as in the map view you click on a cell it tells the Calling Activity through a listener to start the detailed action view, and passes in the ID of the cell (so it knows what objects to load in the detailed view based on the cell clicked in second view). (This took me awhile to figure out but someone helped here on another question to get this.) Reference that helped me on this part here. I also used the various information here on ViewSwitcher.
I got even a yes no dialog box in the second view that asks if they really wanna goto that cell when they click on it, a yes tells the calling activity to set the new view. What helped me to get this working was this reference here. I also had to fiddle with the calls to getContext and that, I am still not 100% sure what getResources and getContext do for me.
So is it bad practice to call and load a dialog from a view? If it is, then I don't understand how if I have an event in the view that needs to pop up a dialog how I do that? Call back to the activity and let the activity handle it the dialog response and then call a method on the view for the response?
So far all this works great, I did have a bit to learn about threads too. I spawn a different thread for my MenuView (handles the detection of button clicks and responses), my CellMap view which handles the cool big map that users can click on to see the indepth view which is my SystemView view.
So basically the activity call list is like this:
Home.Activity -> ScrollMap.activity which listens to CellMap wher ethe Yes/No dialog apperas (in the view of CellMap) and if the answer is yes to the question, then the onTouchEvent starts up the SystemView view using
private CellMap.MapClickedListener onTouchEvent=
new CellMap.MapClickedListener() {
#Override
public void onMapClick(int id) {
setContentView(new SolarSystem(theContext,id));
}
};
To help anyone else, that listener had to be defined in my CellMap class. Then in the ScrollMap activity when I am about to start the CellMap I just call a method to CellMap sets the map click listener. So far this is the only way I have been able to get data from a dialog (in this case a it was clicked so set the new view) back to the calling activity. Is this proper practice?
Now my biggest question is, I have a playerObject class I want to initialize on new game event (I know how to detect that push) and that then is available to any view in any activity for the life time of the cycle. So far the game activity has just two (3 if you count the loading progress bar) views. I want to get the players name, is that another activity or view? I cannot find a decent tutorial of just how to make a simple input dialogg box that would return a string.
How do i go about passing this stuff around? After I get the players name from wherever that edit box is to be loaded, I want to set the players name in the class and pass that class instance off to another view or activity so they may get at that data. Everything I have searched on this seemed like overkill or not the right way. Whats the best way to pass this "playerClass" around so that I can access it from other views (to say display the players name in every view).
I also have my Home Activity that waits for an onClick on 3 buttons, it then launches their activity that shows the view. I realize a continue game and new game are the same activity and will just change in data loaded off the drive to restore a save game. When the new game button is clicked I would love to get the players name they want to use and of course set the member of the playerClass to this name so it persists.
Where do I call (an edit dialog is it?) the edit dialog from? (more over how do I build one that can take an okay button and input from keyboard etc). Id also like to make it pretty, maybe I could have a simple view that has one edit box in it and a nice image background (though I haven't figured out how to place the edit boxes to fit nicely matching a background i draw for it. I guess id like an edit dialog I can skin to look how i want it to and fit the look of the game).
I am actually kinda happy what I got so far its looking not to bad, just not sure about some specifics like getting user input for a name of the player. Storing that information and passing it then to other activities and views.
Is it better to have one GameMain activity, and a ton of views:
Map view
Character sheet view
inventory view etc etc?
Or Should there be diff activities in there somewhere as well?
You've written a lot here, so I'm go gonna go ahead and answer the questions I think you're asking.
First, how can one share information between activities and views? If you're just sharing it between views in a single activity, store it in the instance of the Activity subclass.
Sharing between activities requires a little bit more. Instead of using an instance of the default Application class, you can create a subclass of Application and use that instead. Put your data in fields of that subclass. To tell your app to use your subclass, modify the app manifest like so:
<application
....
android:name=".YourAppClassNameHere">
....
</application>
As for getting user input, the simple answer is use the built-in EditText view. since you seem to want to give your game a more "custom" style, though, you may need to go about creating your own editable textbox. That and buttons should allow for most sorts of basic user input.
Now, good practice vis-a-vis activities and views. I'm not aware of a standard for this, but when designing I generally try to think of activities as more conceptually separate elements, whereas views are conceptually interwoven. the line between the two is dependent, in part, on the scope of the app; an app with a narrow focus can afford to break more actions down into different activities than can one with a much broader focus.
Your "GameMain" example is a bit on the fence, but I think you've made the right choice: the activity is "playing the game," as opposed to a menu or high-scores table, and the views present different aspects of the game being played.
I have an NoContentViewActivity which has no Content View (i.e. I did not call setContentView() in the onCreate of my Activity).
My question is how can I keep the content view of the launching activity on the screen? Right now, I am getting a blank screen whenever I launch NoContentViewActivity? I want the content view of the launching activity (the activity which start the NoContentViewActivity) to show on the screen.
Thank you for any help.
Excuse me, people, but my guess is that hap497 wants exactly the thing he wants. There is a bunch of situations where invisible activity would fit while Service will not.
Imaging you want to show a set of dialogs, each next of them is shown after the previous one based on the user choices. And imaging you want to have this (exactly the same) functionality to be available when pressing different buttons on different (lots of them) activities.
To write the same dialog processing logic would be an overkill whether the transparent activity will deal nicely...
Anyway, as stated above, all you need to do is to specify:
android:theme="#android:style/Theme.Translucent"
or
android:theme="#android:style/Theme.Translucent.NoTitleBar"
(if you do not want a titlebar either)
It sounds like you'd be better off using a Service than an Activity. Activities are for code that is to be viewed; Services are for code that runs without a UI, which is what it sounds like you want.
An Activity with no Views assigned is an empty black screen, so it will still obscure the calling Activity. You could make your Activity transparent by assigning it a transparent theme:
android:theme="#style/Theme.Translucent"
Keep in mind though, that your invisible Activity will have focus, so the user won't be able to interact with the Activity underneath.
Why do you want to create a fully transparent Activity? As Daniel suggests, a Service might be a better solution to your problem if you genuinely don't want any user interaction.