I have a very specific situation where i found that a single activity generating multiple views is the most correct approach:
The main activity receives a code from the server (XML like) saying what it should build. That XML can contain links to other views that use similar code.
To use this, i build only one activity that decodes the code sent from the server and builds the view...
When i pass from a screen from this activity to another screen of this activity, retrieving more server-code on press of a button, it's all ok. But... when pressing back, the last view has also been altered.
I understand this, the activity being used is probably the same.. how can i avoid being the same?
You can use a Singleton Class which is initiated only once and retain values.
Found the problem. Really stupid... I had a static variable that was accessed onResume so it messed all up...
Related
I've spent 8 years programming and for 8 years I've been pretty happy, but after using Android Studio for two weeks I already want to
So here's the deal. I made 2 layouts. One is the default, named activity_main.xml, the other is named graph_layout.xml. They are both ConstraintLayouts (but the same issue occurred when I tried making graph_layout a LinearLayout or RelativeLayout, so we can rule that out as a factor).
In activity_main, there's a button with the ID, graph_button_1. When I click it, it prints to the console "AAAAAAAAAAAAAAAAAAAA" (but with more A's) and switches from activity_main layout to graph_layout. As it should, that's precisely what I designed it to do.
Now, here's the problem. I also have a button in graph_layout with the ID, calc_button_3. When I click this button, it's supposed to print to the console "AAAAAAAAAAAAAAAAAAAAA2" (but with more A's) and then switch from graph_layout to activity_main. It doesn't do that, though. It prints to the console a little message that, "yes, you did click the button, here are all the details of how you clicked that button" (I'm paraphrasing), but it does not print "AAAAAAAAAAAAAAAAAAAAAAA2" to the console, nor does it switch back to activity_main. (If you're wondering, the AAAAA message is just to see whether the setOnClickListener functions are actually executing).
Speaking of which, here's what the setOnClickListener does for calc_button_3:
//final Context context = this;
calcButton3.setOnClickListener(new View.OnClickListener() { //I know I can use lambda funcitons, but I wanted to play it safe
#Override
public void onClick(View v) {
//Intent intent = new Intent(context, MainActivity.class); //This was one of the solutions I found online. It does not do anything.
//startActivity(intent);
System.out.println("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA2");
setContentView(R.layout.activity_main);
}
});
To be fair, I'm a step in the right direction. Before, this function made my app crash. Now, it just does nothing. So...that's a little better, and I'd like to thank the LayoutInflater class for making that possible. I'd also like to point out that I'm willing to supply you with any code or extra information you might want to see. I'd send the whole MainActivity.java file if I could, but I know from experience the longer I make my question, the less likely people are to answer, and it is a VERY long file.
I've scoured the internet for a solution to this, and while I've found people with a similar problem, none of their solutions worked for me.
Your help is greatly appreciated. Thank you.
Below, I will attach any code or additional info anyone in the comments asks me to give them:
You have to start a new activity using intent or if you want to use the same activity then use fragments. and replace fragment layout on button press. but you can not directly use setContentView();
All setContentView(R.layout.activity_main) does is inflate that layout file into its hierarchy of View objects, and display that in the current Activity. You're still in the same Activity, you've just changed its contents.
When you say you're doing this:
In activity_main, there's a button with the ID, graph_button_1. When I click it, it prints to the console "AAAAAAAAAAAAAAAAAAAA" (but with more A's) and switches from activity_main layout to graph_layout.
does that mean you're "switching" by calling setContentView there too, instead of starting a different Activity that displays graph_layout?
If so, and all your code for both layouts is in the same Activity, then your problem is probably related to the fact you're replacing your Views with a new set of objects when you call setContentView. If you set up your buttons like this:
// a Button from your current view hierarchy gets assigned to this at some point
val someButton: Button
// just use the lambda, it's literally the same as creating the object under the hood
someButton.setOnClickListener {
// do a thing
}
And then later you call setContentView(R.layout.some_layout), then whatever Button object someButton is referencing is no longer on the screen. So you can't see it, you can't click it. If you just inflated the same layout as before (creating an entirely seperate set of View objects) then there's another button in the same place - but you haven't set a click listener on it, so it doesn't do anything.
So if you are going to go replacing the view hierarchy like this, then you need to perform your View setup (like assigning click listeners) when you create those new views. If you just set things up when the Activity starts, then it's only applied to the view hierarchy in use at that moment. As soon as you replace it with setContentView, that stuff is gone.
So you could write functions that "switch" to one layout or the other by calling setContentView and then applying the click listeners. Generally speaking though, this isn't how you normally do things in Android. The old way would be to create separate Activities for each screen, a more modern approach is using Fragments which can be swapped out manually or by using something like the Navigation library.
Either way, both those approaches involve configuring your Activity or Fragment once during setup, making buttons do this or that, and then you're done. Everything's neatly separated and self-contained, instead of you having to swap views out and rewire everything according to the state you want to display. That's just complicating things, and it'll get much worse if you start adding more screens you have to juggle!
I'd recommend at least taking a look at the Fragments guide, or the Navigation component if you have time. The latter has more to learn, but it also handles a lot of complexity for you. It would help to at least have an understanding of the usual way of doing things, anyway!
Suppose an app project is already written, all you want to do is to additionally write a somehow standalone script that captures the onClick, onFocusChange or even onAppear in the app. Is that even feasible? How robust is the approach?
All answer I found was to fully add listeners (or global listeners, although less comprehensively functional) for each item or so, which is a boring work for a large project, and not always desired at the end of a production process(where I just cut in).
Another purposed approach was to locate the root of the nodes and scan from there? Correct me if that's a dead end. Other answer mentioned spying app, which is not the case, since it's the original developer who wants to track everything from inside the app.
I am not sure, if this solves your problem but have your extension of views. Eg: MyTextView extends TextView then just override the touchEventHandlers, log what you want and dispatch the event down to the listeners.
So instead of normal TextViews, use MyTextView.
My app has a creation page and an edit page. These two pages are almost exactly identical, save the difference you can't edit without first creating the page. It's working perfectly fine, except it seems a little redundant have two separate activities with the same actions.
My question is, what is the standard/best approach to this situation. Should I create a new class, from which both these classes could access methods from or could it be one activity? Also, there is some amount of calculations, (a small series of random number generators) being carried out, should this be running on a separate thread? Or is it fine running on the main thread?
An example of what I have is kind of like android contacts app, you can create new contact and you can also edit that contact, which is essentially the the create new contact page.
Approach 1:
Have a Base Activity that extends Activity.
Then add all the common code like inflation of layout, some logic, life cycle handling etc.
Then create 2 classes like CreatePage and EditPage. These two new classes will extend the Base Activity.
Just handle the little variations in xml page dynamically here at runtime. Maybe in onStart().
This approach show cases basic OOPS of 1 parent Activity and multiple children.
Approach 2:
Have a Base Activity, and put create page and edit page as Fragments.
Just replace the fragments on your activity according to your program flow.
P. S. My answer may be a little abstract since your question is generic :)
I have a very simple 2 screen android app.
Is there any downside to simply switching out the layouts via setContentView or should i be using intents?Don't want to bugger up my app if something is wrong with this.
Another thing to consider is that activities form a stack. If you want to be able to go back to the previous activity via the 'back' button, then you need to use activity. But if it is something simple like a 'loading' screen when your app starts and you don't have to go back to it again, setting content view would be a much better idea.
Well as stated on Android Dev http://developer.android.com/reference/android/content/Intent.html
An Intent provides a facility for
performing late runtime binding
between the code in different
applications. Its most significant use
is in the launching of activities,
where it can be thought of as the glue
between activities. It is basically a
passive data structure holding an
abstract description of an action to
be performed.
Therefore if your two screens are 2 different applications I would say you want to simply use setContentView.
it will simplify your code when you want to pass info from one to the other views
There is nothing wrong with having two views in a single activity. This approach is more light-weight, as you don't need to go through the phase of stopping one activity and then starting another one. However, it will make your activity code bulkier. Consider now if you are going to need more functionality or more views in the future and if the answer is yes, then it would be better to create separate activities.
If the view is light-weight (a bunch of text boxes), then it should not matter. On the other hand, if the two screens are largely independent and heavy, you could use two different activities. The primary advantages with this approach are:
If there is an error in the second screen (an activity in this case), your application will fall back to the first screen whereas in the case of using the view, the whole application crashes
Better readability
Easier to add more functionality in the future
This question actually has two parts.
The first part:
I've been developing my first app for a couple of weeks now. I have 5 screens and everything seems well. However, I'm considering changing the app's navigation to a TabView.
I haven't delved much into it, but I'm hoping someone can save me a little bit of time. It seems that people don't generally place Activities inside each tab. They simply point the tab content to a View. This is where my major setbacks are. 1) I already have Activity classes full of code and 2) I can't quickly guess how the structure of an app using TabView looks. For example, where do I put the handler code for clicking a button on a View? Does it all just get dumped into the TabView Activity somehow?
What I would like is if you could please give me a quick synopsis of what I'm looking at doing, answers to any questions you think I may have, and point me toward some resources for creating TabView applications. A quick Google search really just shows me how to create a TabView Activity and add a couple tabs to it. The code doesn't go any deeper. For example, say I have a layout xml to show in one of my tab's content pane, where does the code go for clicking a button I have in that layout?
The second part:
I've added a TabActivity to wrap the Activities I currently have in. At the moment I have Activities populating the content of my tabs (though ultimately I'd like to do this in the most efficient fashion, which doesn't seem to be having Activities be tab content). I've noticed something rather annoying. My MAIN Activity is an Activity I wrote for my user to log in to their account. After logging in, they are taken to my Tab Activity. Here is what happens:
When I am on my Tab Activity and I "minimize" the app by clicking the Home button and then launch it again, I don't get taken back to the Tab Activity. I get taken to my log in Activity. Why? I don't have the launchMode of my Tab Activity set to singleInstance... or is it singleInstance by default? How can I make the app re-launch showing the Tab Activity (ideally by setting some parameter, assuming I'm doing something wrong, and not having to save this data off somewhere and reading it and programmatically telling it what to go to)?
Thank you for all your time and help
I don't have a comment on the advisability avoiding the use of sub-activities in TabActivity. As for handlers -- if you aren't going to embed views instead of activities, then all the android:onclick type handler settings in your layout XML will call methods on the TabActivity. This is because they go to methods on the views' Context, which is the generally the nearest containing Activity. If you want to split your code up further without using Activities, I believe you'll have to use findViewById calls on the tab content views after you've set them up, and bind the handlers manually from there in your code.