Will Android be able to handle a single large activity like this? - java

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.

Related

How do I pass non-static variables between unrelated classes in java?

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.

Starting an activity and a fragment from a different activity

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);
}
}

Sending data from Fragment to MainActivity

I have a TextView in my MainActivity and a Button which is in a Fragment attached to the MainActivity. When I click the Button I want the TextView to say, "Button Clicked".
Is this possible?
I know two Fragments attached to the same Activity can easily communicate with each other and send data to each other. But can an object in the Fragment send data to an object in an Activity
Is it better programming to make the TextView its own Fragment and attach it to the Activity? Then I can simply have the two fragments send data to each other.
Sorry if this isn't a proper type of question for StackOverflow. I am new to Fragments and have not been able to find a clear explanation on this issue.
Thanks in advance!
The currently accepted answer (to use a static method in the Activity) is both odd and arguably "wrong".
The use of the static method is odd because there's just no need for it to be static.
It's wrong because the Fragment must have knowledge of the particular Activity in which it is hosted. This is "tight coupling", and also makes it so that the fragment is not re-usable.
There are two common solutions to this issue:
Create an interface containing the methods in the Activity that can be called by the fragment. Implement that interface in the Activity (all Activities that use the fragment), and then in the Fragment, use getActivity() to get the Activity, and cast it to the interface. In this pattern, one also typically checks (using 'instanceof') whether the Activity implements the interface, and throws a RuntimeException if it does not.
Use an Event Bus (e.g. Square's Otto, GreenRobot's EventBus) to communicate between the Fragment and it's parent Activity. I feel
that this is the cleanest solution, and completely abstracts the
Fragment from it's Activity.
You can create a static method inside your Activity which will have the TextView inside it. And when you need updatation just call it from fragment.
something like:
In Activity:
public static void updateText(){
//your textview
text.setText("Button Clicked");
}
Just call it when you will click on the Button from fragment.
something like:
From Fragment:
//Inside Button click listener
MainActivity.updateText();
Not tested, but hope this approach will work.
Have you tried the getActivity() method to retrieve a reference to the parent activity and use a method to set the data, something like:
// public final Activity getActivity ()
MyActivity activity = (MyActivity) getActivity();
activity.setText("...");
I may be wrong but I would try that.

Same Spinner in multiple activities and fragments. Which is the best way to implement it?

Let's say I have a Spinner view with 10 Countries (String).
I want to use this spinner in multiple activities, fragments, alertdialogs etc.
How can I do it efficiently and save code lines? Which is the best way?
What I first thought is to create a class that creates the spinner and extends the spinner widget class. Then create objects etc. However, as a begginer, it looks a bit complicated to me, is there an easier way?
EDIT:
The spinner is created dynamically ONLY. It has 10 items by default but is gradually populated according to database entries.
Create a public static method in any class (but probably one that is intuitive to find*) that populates the spinner. It can take context, database, etc. as inputs, as well as the Spinner itself. Then you can call this same method from any fragment or activity and always get the same thing. Just create your layout (such as with setContentView), get a reference to the spinner from the layout, and pass it to your populater method.
Example:
//in Activity
public void onCreate(Bundle bundle){
super.onCreate(bundle);
DatabaseHelper myDataBaseHelper = ...;//
setContentView(R.layout.my_layout);
Spinner spinner = (Spinner)findViewById(R.id.my_spinner);
Util.populateStandardSpinner(myDataBaseHelper, spinner,
getApplicationContext());
//...
}
//Another class
public class Util{
public static void populateStandardSpinner(DatabaseHelper dbHelper,
Spinner spinner, Context context) {
//Get cursor from dbHelper
//Create adapter for cursor data and apply it to spinner
}
I suppose you could also extend the Spinner class, but my preference is to avoid coding the data directly into the widget. That would break the model-view-controller design pattern.
*I sometimes just create a class called Util where I put convenient static methods like this. Or if you have a database helper class, that might be an intuitive place to put it.
You can create a separate layout file for this and only have spinner in this.
Wherever you require this you can include in your layouts like
<include layout="#layout/spinnerLayout" />
Extend Spinner class itself.
You can initialize adapter inside constructor, dynamically load database entries using AsyncTask, and manage resource usage with onAttachedToWindow and onDetachedFromWindow.
I usually do this when face similar problems, it is convenient, easy to develop and use.

Action Bar as Fragment

I have just started developing an Android app and have no experience at all. I have read a lot about Activities / Fragments / Widgets, but don't seem to find a clear answer to my question which is:
Can I create the Action Bar for the app as a fragment so whenever I change an activity I will simply call the one action bar (i.e. the one fragment)? I intend to develop a dynamic UI to create fragments for individual option and thought that it would be easy to have a general Action Bar appearing on all pages.
When you want to customize the ActionBar in all your Activities, the first step is to create a custom Theme in XML.
In this theme, you can customize nearly everything
Please refer to this excellent blog post: http://android-developers.blogspot.be/2011/04/customizing-action-bar.html
Using a Fragment for the ActionBar would be crazy!
If you want to add some code programatically in all your Activities, simply extends a custom Activity, for instance MyCustomActivity, that extends Activity.
public class MyCustomActivityextends Activity{
In this class, you can use getActionBar() and tweak it according to your needs
If you wanna have one ActionBar for all your Activities use inheritance. Create an Activity which simply handles the ActionBar like you wanna have and make it the Superclass like this.
public class ActionBarActivity extends Activity{
public void onCreate(... ) {
ActionBar actionBar = getActionBar();
// + some other method calls of your choice
}
public onCreateOptionsMenu(Menu menu){
// create your actionbaritems here
}
public boolean onOptionsItemSelected(MenuItem item) {
// handle your click events for the items here
}
}
Now you can use this Activity for all your Activities with inheritance:
public class MyActivity extends ActionBarActivity{
...
}
With this setup you are free to use Fragments as you like.
Keep in mind that every time you call a new Activity the callbacks of the super class will be invoked.
I think what you're thinking of is this:
You want your action bar to be the same on every screen, and only need to program it once.
The approach I use, is that the actionbar live in a root activity, containing a single viewpager. And all of the screens that the user interacts with are Fragments in that view pager.
If you create a blank android project in eclipse, and select actiobar with tabs, the project will set this up for you and you can see how that works.
In most cases this would be an unnecessary complication. Once you get started, you will probably find that just a few simple lines of code will create an "identical" Action Bar in each activity .Themes etc can be added later. Better questions at this stage might be should I use Action Bar Sherlock to enable better support of old devices ? and you should think about the overall structure of your app e.g activities / fragment activities / fragments / tabs so that you are able to get something working quickly that can be readilly extended as you develop you full solution.

Categories

Resources