TL,DR: How to start from "Activity A" both the "Activity B" and the fragments that will be shown in it.
I'm new to Android Studio so I'm clueless about most things concerning fragments. I'm working on an app that calculates information about different shapes. At first the user can pick a shape, then they are taken to an activity where they input the dimensions. What I'm trying to do is, instead of creating an activity for every shape, I created a single activity in which I'd like to start different fragments. I created a single fragment for every dimension (say side a, side b and so on...).
It's a bit hard to explain for me but what I'm trying to do is, from the first activity - "Menu.java" through a button open up a second activity- "Input.java" activity (containing just a confirm button) along with some fragments as soon as the "Input" activity starts (depending on the shape the fragments may vary, whether just in position or over all in which are loaded and which not - the reason i think i need to do it like this).
To simplify (and hopefully make it a bit more understandable) - from "Activity A" start both the "Activity B" and the fragments that will be shown in it.
I don't have any code besides the fragments themselves and the buttons set up because like I said I'm mostly clueless and I'm thankful for every advice or at least clarification that it isn't possible. Hovewer if there is any other information that can help or you want me to try to explain it a bit better just make a comment and I'll and what you need.
Thanks a lot
--EDIT--
here is all the code I have ready:
public class Menu extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_menu);
}
public void inputSquare(View view){
Intent intent = new Intent(this, Input.class);
//Here is where I'd like to start let's say fragment "Input_A_Fragment" in the Input class (or even if this isn't the way/place to do it please le me know)
startActivity(intent);
}
}
Related
I am currently working on an android app that has 2 pages, the first page has a slider whose input/value I am unsuccessfully trying to transfer to a canvas on page 2. the general framework of the code in question is as follows:
public class MainActivity extends AppCompatActivity {
int sliderVariable = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//... SliderVariable updated using slider's ontouchListener//
}
}
This code works fine, the slidervariables are set properly, my main struggle is finding a way to transfer these variables to the MyCanvas class on the second page. This is how the canvas is set up:
public class MyCanvas extends View{
//how do i get the sliderVariable in here?
public MyCanvas(Context context, AttributeSet attributeSet){
super(context,attributeSet);
}
}
It seems like something that should be really simple, but I dont know how to transfer these variables between eachother.
I have tried to use get and set methods, these havent worked.
I thought maybe I could use sharedpreference session storage, but since these two classes are unrelated, I am unable to get them to 'sync' up (i am relatively new to java so ignore the weird lingo). I feel that this option had a good possibility of working but it just isnt. I believe one class needs to extend the other? i am not sure.
The last thing I tried was using Intent to send variables to MyCanvas, but this doesnt work. The second page is actually called Sheetpage, and MyCanvas is a view which I use in the layout of the Sheetpage, so the intent is directed towards SheetPage. I have also tried having MyCanvas being the 'receiver' of the intent but I get an error saying MyCanvas must extend android.app.Activity. Considering MyCanvas already extends view, I cannot have it also extend activity.
Are there any other ways to transfer these variables that I am missing? In the full app I have 3 sliders which only end up needing to transfer 3 two digit numbers, so if there are other ways that are usually frowned upon for being slow or resource intensive, that is not a problem here. thanks for reading and hopefully you can offer me some insight to this problem.
I think that you are looking for the concept of intent.
Intent is an object to pass info between views.
On the first view you create an intent object just before creating the second view. There are lot of options for intent, you can pass many types of info. Here is an example from https://www.javatpoint.com/android-intent-tutorial
Intent intent=new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(intent);
And on the other side, where the new activity is created you receive this intent and read it. Here is an example from How do I get extra data from intent on Android?
String subName = getIntent().getStringExtra("subjectName");
int insId = getIntent().getIntExtra("instituteId", 0);
Hope you find it useful.
I am executing maswebview class and I would like to finish only this activity. I tried maswebview.this.finish() but when executed, app is been closed. Then if I set a new view for the tab content, it is loaded properly and webviewmas dissapears but just for a while, then appears again fitting fullscreen. How to finish maswebview completely? ThanK you
public void onClick(View arg0)
{
/*
Intent intent = getIntent();
intent.addFlags(Intent.FLAG_ACTIVITY_TASK_ON_HOME);
startActivityForResult(intent, 1);
Intent intentmas = new Intent (maswebview.this, mas.class);
intentmas.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
intentmas.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intentmas.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intentmas.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
View vista = getLocalActivityManager().startActivity("maswb", intentmas).getDecorView();
setContentView(vista); */
maswebview.this.finish();
Do you have any other activities of your app in the stack by the time you call finish()? If you don't, you'll want to start the desired activity instead of finishing the current one.
But actually it seems to me that you're trying to accomplish something that can be done simpler. Can you provide more info on the task at hand and your app structure you're trying to go about it with?
From what you said, it seems like you have tabbed UI and you're trying to show a webview in one of the tabs, then hide it.
First, I don't see why you want the webview in a separate activity. Seems to me you could just have it in layout of one of the tabs and just call setVisibility(GONE) to hide it.
Second - and this is important - looks like you're trying to implement tabs the old way - TabWidget, TabHost, etc. Since Honeycomb has been released, there's much more convenient way to implement tabbed UI - Action Bar Tabs and Fragments - that approach is much more convenient and will render your webview problems obsolete: there's a thing called WebViewFragment which is basically a WebView but smarter - it will handle its own lifecycle with minimum effort required from you (i.e. pause when removed, resume when added). It will take some effort to study up on Fragments, but it's well worth it. You can get Fragments API for pre-Honeycomb android sdks as a static library - it's called android-support-v4 and you can download it in Android SDK Manager.
Are you calling "maswebview.this.finish();" before the new Activity is started?
Also if you want to just start this new activity without having the old activity in existence then you can add android:nohistory="true" to your manifest.xml. This will cause the current activity to be the only activity in the queue.
See HERE
You need to provide a little more information for us to better understand what exactly is going on.
I hope this helps.
Try following code
#Override
public void onBackPressed() {
if(childView != null && parentLayout.getChildCount()==2){
childView.stopLoading();
parentLayout.removeViewAt(parentLayout.getChildCount()-1);
if(webView.getVisibility() == View.GONE)
webView.setVisibility(View.VISIBLE);
}else{
super.onBackPressed();
}
Do you have a parent activity which is launching this one? If yes make sure you don't call finish() after launching maswebview, that way the parent activity will remain in the stack. Once maswebview would exit, onResume would be called for your parent activity.
In my application when i click the back button it passes through all the activities that i open them previously , i used the public void onBackPressed() method to make the back button back to the activity that i want as follow
public void onBackPressed()
{
startActivity(new Intent("com.MyDiet.Main"));
Tracker.this.finish();
}
is that true and safe way to code the back button ? how i can prevent the application from passing through all the previous opened activities when the back button is pressed ? and how i can make the application exit when i click the back button in the main activity?
In your application, and in ALL android applications, unless it's critical not to pass through unneeded steps (such as login if you're already logged in), it's VERY important not to override Android standard behaviour. Users normally complain about Android apps not having a common behaviour or style guideline.
Anyway, yeah, you can just override onBackPressed on all your activities and do whatever you want. But just don't.
This approach isn't good, because you're polluting the activity stack of your application
Example:
current stack: MainAct -> Act2 -> Act3 (we're in activity 3)
With your code above, when you press back, the stack now looks as follows:
MainAct -> Act2 -> MainAct
Because you ended Act3 and launched a NEW main activity, which may be not what you wanted.
To achieve what you want (Get back to main when the current activity is over) you need to work on the intermediate activities: In the example above, when from Act2 you call startActivity("Act3"), you should call "this.finish()". Therefore you don't have to override "onBackPressed()" of activity 3: simply the default value will terminate Act3 and the next activity in the stack will be MainAct
MainAct -> A2 (A2 launches A3 and then calls this.finish())
MainAct -> A3 (user now press back)
MainAct (the mainactivity is now on top)
To summarize, you don't have to override onBackPressed, you just have to correctly manage the lifecycle of the activity between the main one and the current one.
Generally speaking it's not recommended to make things work like user doesn't expect and that is considered as very bad practice. That's why it is not good to start activity from overriden onBackPressed().
When user press back by default activity will finish and one from back stack will be displayed. You as developer will (by writing code) decide which one is that. You can do it this way but later (or for somebody else) it will be a bit messy and difficult to find this unusual place for code which is starting other activity.
So..It would be useful to read about activity lifecycle and back stack to get impression how it works and understand terminology better.
If you want one of your activity not to stay on back stack you can add in manifest file file android:noHistory="true" for that activity.
Same thing you can achieve from code by adding appropriate flag to intent when you start activity: Intent.FLAG_ACTIVITY_NO_HISTORY
When user "go away" from ActivityOne (started using intent or defined in manifest like described), to new ActivityTwo and then press back, it will not go to ActivityOne because it will not be on back stack. Using this you can precisely control navigation through your activities.
More flags are available for use, but I guess this is what you wanted to achieve.
Hope you will find my answer useful. Cheers..
You can use a lot of tricks to exit your complet application for my part i use this start a intent and then from the androidmanifest i choose the category to home and than close the current activity such would be your mainactivity !
public void onBackPressed() {
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
finish();
}
I'm making an Android soundboard. I currently have 12 pages for this specific category. Each page has its own activity and each page as 10 buttons.
Someone asked me today why I don't just use one activity and switch the setcontentview (XML) between the pages rather then having so many activities.
I thought about it and it doesn't seem like a bad idea. But I'm curious on if it really would be better.
This means that this one activity would have a 100+ switch case statement for its onclick and onlongclick methods. It would have over 200 variables. I would have to add over 200 listeners (although I think i could set the 10 listeners as I load the specific page rather than all at the beginning. I could also release the current ones before the new XML is displayed).
Will Android be able to handle a single activity like this? I plan on adding more sounds so maybe one day I might have 20 pages or so.
Yes, make it all one activity. Different Activities should only really be used for completely different use cases. Consider using a ListView or a GridView, or a 'ViewPager` inside of one Activity.
If you do end up using a ListView or anything that takes an Adapter, your Activity should look like this:
class MyActivity extends Activity{
int mySounds[] = {R.raw.s1, R.raw.s2}; //etc. could also be a 2d array, one for each page of sounds.
protected void onCreate(Bundle b)
{
setContentView(R.layout.myactivity);
ListView lv = (ListView) findViewById(R.id.myactivity_listView);
lv.setAdapter(new SoundAdapter(this));
}
class SoundAdapter extends BaseAdapter{
Context cont;
SoundAdapter(Context c){
this.cont = c;
}
getView(int id, View convertView){
if(convertView == null){
...
//inflate view to be a row/gridcell
}
convertView.setOnClickListener(new SoundClickListener(mySounds[id]));
}
}
class SoundClickListener extends View.OnClickListener{
int resId;
public SoundClickListener(int resId)
{
this.resId = resId;
}
protected void onClick(View v){
playSoundWithId(resId);
}
}
}
I'll address a few of your points individually:
Will android be able to handle it. Yes. Nevertheless, you should be smart about the way you design things.
Depending on the version you're running, you should look into either TabActivity or Fragments. If you build your activity out of these, you can base which ten or so Buttons have listeners on them at any given time.
Here's an even more radical idea: create a mother class that extends Activity and pass its constructor information on which buttons to display. This way, you have only 10 buttons or so in an Activity, but you have 12 activities.
Even more radical idea: extend button and put it as an inner class of your extension of Activity. This could lead you some interesting places.
If you ask a slightly better question, I could give you a better answer, but here's some ideas, run with it. Good luck.
Is there a way to say if an activity is selected then do something?
I dont know the statement which is why i am asking this question, but similar to this:
if(myactivity.isselected(true)){
webview3.reload();}
If you are using tabs, then onTabChange() is the correct event for that. Not all tabs are individual activities. Not even necessarily different layouts. Then you can check to see if the selected tab is the activity like this
public void onTabChange(View v, int id) {
switch (v.getId()) {
case (R.id.tab1) {
//Do this
break;
}
}
The tabhost supports alot of functionality. Another funcitonis getTab() which will return the id (as an int) of the tab selected. Heres a link to the documentation http://developer.android.com/reference/android/widget/TabHost.html
When user moves through different user interface , he/she start different activities. Since you have different tabs, you should have three different screens and so three different activities , if user is moving from one tab to another, you should first pause the initial activity and should start other activity.
You can get the activities that the tabhost is running, with this:
YourActivity act = (YourActivity) getLocalActivityManager().getActivity(TABKEY_1);
then call any method you have in that activity. TABKEY_1 is just the name for the tab that you give when you initialized the tabhost.