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.
Related
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);
}
}
I have an app that has a top menu as shown in the fig below. This is almost constantly used in all activities. For layout I have defined it in a single xml file and use <include>to include it in every layout file.I want to know if there is a way in java coding to avoid declaring all the imageButtons, and then using findViewById and onclick events for them , in each activity. The top four icons will act as menu and be available in all layouts and activities
First of all, what you are trying to achieve is against the android standards and this could affect the user experience for Android users. Instead, add the menu items on the action bar.
Anyway, you can achieve what you are looking for by defining a base class (named it like ActivityBase) and do all the initializations and listeners registrations on it. Then, extend from that base class. Bear in mind that each activity will have its own instance of the views of the base class and the state will differ from activity to another.
Although you have accepted an answer I disagree that the Application class should be used to host global methods. It can be used for maintaining global state but that's a different matter.
As others have said, use inheritance by creating a base Activity class then extend that for all of your other Activities. To make things easier, however, you can define the onClick method to be used for each of your buttons in the layout file itself by using (for example)...
android:onClick="myOnClickMethod"
As long as the base Activity defines a public method called myOnClickMethod (or whatever method name you choose) with a void return and which accepts a View parameter it will work without the need to implement View.OnClickListener and without having to set the listener in Java code. Example
public class MyBaseActivity extends Activity {
public void myOnClickMethod(View v) {
// Get the resource id of v and use switch / case to perform action needed
}
}
That's all you need.
Write it only in the first activity. Extend it to the other activities instead of extending with android.app.Activity.
Eg:
public class SecondActivity extends MainActivity{
}
Put that method in MyApplication class which extends Application. So, that it can be accessible by multiple activities.
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.
I'm creating an app for the Android OS, and I'm running into a bit of a stumbling block on one issue. Here's what I want to do:
I'm currently capturing the "Back" button event just fine, but I need it to behave slightly differently, depending on the current layout the user is viewing. I have four layouts that I'm using, and if the user is on layout 1, 2, or 3, I want "Back" to take them to layout 1; but if they are on layout 4, I want them to go back to layout 3 instead.
The problem is, I can't for the life of me figure out the code that will return the id of the CURRENT layout. I'm sure this is a pretty simple problem, so I'm hoping someone will have a quick solution.
Thanks for the pointers - for some reason I'm having trouble getting getCurrentFocus() to work, though...probably due to my own ineptitude in programming Java.
I've broken it down into the following:
View thisView = getCurrentFocus();
if (thisView != null){
int viewID = thisView.getId();
toastLong(Integer.toString(viewID));
} else {
toastLong("thisView is null.");
}
The problem now is that thisView is always null - it's not returning any values. I tried putting in the activity name that I'm using in place of myActivity (making it:
View thisView = myActivityName.getCurrentFocus();
but the IDE gives me the following error and won't compile:
Cannot make a static reference to the non-static method getCurrentFocus from the type Activity.
I'm obviously missing something, and my assumption is that it's a very basic something that I'm missing. Any pointers?
I had this problem too and found a very simple solution. Though this is an old question, I'll post it here for people who are searching for help for this problem.
Just create an integer as attribute in your class:
int layoutId;
Then override the setContentView method and save the ID from the parameter:
#Override
public void setContentView(int layoutResID) {
this.layoutId = layoutResID;
super.setContentView(layoutResID);
}
Very simple trick!
You can use ViewFlipper to hold your layouts and implement a simple state machine to control transitions.
another option might be creating a separate Activity for every one of your layouts - hard to tell without exact knowledge about what your app is doing.
I've tried this and it works, but I didn't know if this was a bad thing or not, as all the help on data transfers between Activities seems to use intents.
In MainActivity I have:
static PilotRecord pilotRecord = new PilotRecord(); //PilotRecord just contains data item declarations
In MainActivity.onCreate:
pilotRecord.fuel = 100;
In MainActivity.onClick:
Intent intent = new Intent(this, SubActivity.class);
startActivityForResult(intent, 0);
In SubActivity.onCreate I have:
MainActivity.pilotRecord.fuel = 200;
In SubActivity.onClick:
MainActivity.pilotRecord.fuel = 300;
setResult(RESULT_OK);
finish();
When I start MainActivity, the fuel value is 100
If I click in MainActivity, SubActivity is displayed, as expected
If I click in SubActivity, MainActivity is displayed and the fuel value is now 300
If I press the Back button, MainActivity is displayed and the fuel value is now 200
Does anyone know of any potential issues with this as it seems simpler to me than setting up intents etc.
Frink
It is my understanding that what you are doing will result in data loss.
The SubActivity should not be manipulating the data of the activity that called it. I don't think that there is any guarantee that your MainActivity even exists...
The system may decide to kill it at any time and restart it when your SubActivity signals that it is ready to return to the MainActivity.
You should pass back the data in a bundle and let MainActivity modify its data based on the results.
Bundle stats = new Bundle();
stats.putString("fuel","300");
setResult(RESULT_OK, "PilotRecord", stats);
finish();
Also, remember that you should be saving the "Fuel" level to some sort of persistent storage when onPause() is called in your MainActivity.
I would suggest reading the documentation for Activity carefully since it is quite important to implement the correct callbacks.
If you really want to hack it, create another class that hold all your static variables that needs to be shared.