I wast just wondering if the standard practice is to create an activity/fragment class for each layout file (new page).
Example:
MainActivity.java
onCreate(){
setContentView(R.layout.**start_page**)
}
And than when the user clicks a button in the action bar (or some other button on the screen):
onOptionItemSelected() {
switch XX -> case XX: setContentView(R.layout.**next_page**)
}
So could i do the above instead of launching a new activity.java (that contains a new layout.xml) with an intent, or inflating the view with a fragment.java (that also contains a new layout.xml).
I can see that the up/back navigation wouldn't work with the above code, but is that the only reason why you basically have to create two files (.java & .xml) for each new page in your app.
Yes you could do it technically but beware that if you already create an instance of view lets say Button and you change the layout button will be null because button is not located in your View and also it will take time to render again the layout. So it is a best practice to start a new activity or just create a fragment.
You can do that, but every view will be on the given Activity, and the event handlers would be in the same class, which isn't really modular. It could get extremely bloated and you'll have a 2000 line superclass because it handles every single button click in arbitrary functions (or even worse, in a single onClick function).
Related
I have a gallery app, with some categories: animals, flowers... each gallery I created one activity, this activity in all galleries has the same content:
onCreate:
tSpeak = new TextToSpeech(this, new TextToSpeech.OnInitListener() { ...
AdView adView = new AdView(MainActivity.this); ...
//some checks to change images:
if(fase == 1) { imageView1.setImageResource(R.drawable.flower1); ...
if(fase == 100) ...
some setOnClickListener
after that some onRewardedVideo functions, a next() function that will intent to the same activity to show next image on this gallery (`fase` + 1)
What I'd like to know is, can I instead of repeating all this things (TextToSpeech, listeners, rewardedvideos functions, adview functions) just change the if checks in each activity gallery? this is the only thing that will change in each activity gallery, and I don't want to use just one activity for all categories because in this case I may have more than 2000 ifs and it is not good to work.
I'd like to just inject in each category the ifs to set imageresources there, without need to copy all activity again and again in each category. Any ideas?
You can create your common functionalities in a BaseActivity and extend your activities from this BaseActivity.
For the ifs conditional checking you can have a boolean field in your BaseActivity which you can override in your each subclass (In this case, your actual activities).
A better option could be having one activity only where your category is passed in the Bundle. Now based on your category, you can switch over the value and keeps your variations.
I suggest you use a single activity and pass a gallery ID as a parameter to your activity via an Intent extra.
You could get the image resource ids of the current gallery from a static map in your activity.
You could also use a ViewPager with one gallery per fragment, to enable your user to navigate quickly accross galleries.
Look at this for more info:
https://developer.android.com/training/animation/screen-slide
Normally I would use a separate activity for each "screen" I wish to display, using different XML files.
However I'm working with Dynamically loading jar files into an android application, so therefore at runtime, I am not aware of how many activities there will be, or how many screens there will be.
At the moment, using java reflection, I am able to return a list of strings from the dynamically loaded java file, and draw each list item, as a separate button onto the screen. If one of these buttons is clicked, i want to be able to load a different "screen" on the stack. So when I press back from this new screen, it goes to the previous screen that called it.
Is it possible to do this without creating a new activity and passing a new intent to it and of course making relevant changes to the android manifest file?
To use blackberry functionality as an example - Is there an equivalent in android to blackberry's push and pop screens? Where the screen ur pushing/popping, would simply extent MainScreen?
If anyone has questions, or If I've been vague, please comment and I will try my best to explain myself, any help is very much appreciated.
The Android equivalent to BB's push/pop screen is startActivity()/finish(). However, you can manage your own views in a single activity by either using a container view (such as ViewSwitcher, as #hasanghaforian suggests) or by simply calling setContentView() with a new view hierarchy whenever you want to change the screen. Be aware that when you call setContentView, any view references that you obtained by calling findViewById will be stale.
In my opinion you should use Fragment. I assume that you have some piece of code where you iterate over the strings:
for(String def : definitions) {
Fragment f = new CustomFragment();
Bundle b = new Bundle();
b.putString("STRING_DEF",def);
f.setArguments(b);
fragments.add(f);
}
in above piece of code a collection of Framents is just created. Let's look at the CustomFragment implementation:
CustomFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
String def = getArguments.getString("STRING_DEF");
//write code to create view
return view;
}
}
Now in your ListActivity you have to implement on click listener more or less like this like this
public void onListItemClick(ListView l, View v, int position, long id) {
FragmentManager fragMgr = getFragmentManager();
FragmentTransaction t = fragMgr.beginTransaction();
t.replace(R.id.id_of_view_place_holder_for_fragment,
fragments.get(position),"FRAGMENT_TAG");
t.commit();
}
you can use ViewSwitcher. ViewSwitcher is a ViewAnimator that switches between two views, and has a factory from which these views are created. You can either use the factory to create the views, or add them yourself. A ViewSwitcher can only have two child views, of which only one is shown at a time.Or you can use fragments.
If you refer to if it is possible to have different layouts in the same activity, the answer is yes.
Activities are independent of layouts, you don't assign the layout for an activity in the manifest, you define what layout to use in the activity calling setContentView() method from Activity class to set a layout.
So if you want to have some layouts (screens) the only thing you have to do is define various layouts and use them when you want calling setContentView(R.layout.the layout), after this call, the layout chosen will be displayed.
If you can't create the layout statically by xml, you can create it dinamically by code as needed by demand each time you want.
In addition you can have a stack of layouts, each time you need a new screen, build it, push it to the stack and call setContentView() method, when you don't need it more, pop off the stack and call setContentView() with the new layout in the top of the stack.
Hope it help you
I'm very new to Android development, and want to make sure that I'm structuring my application correctly. First, let me explain what is needed.
The application starts off prompting the user for an access code, depending on their response there are two resulting menu's which can appear. One menu has 5 buttons, while the other adds two extra buttons making seven. Each one of those buttons brings me to a different view where more information will be displayed.
I originally starting writing it with one activity and a different XML file for each view. However, the more I have been researching online it seems that I should have a different Activity for each individual view. But now I'm relatively confused how I can prompt the user for input before initializing any of the Activities.
If anyone has any input I'd really appreciate it.
Thanks
You will need to initialize an activity before getting user input. And I think it is common that if you go to a new view that it uses a different class and xml layout. So for each of the new views you could make a new class that extends an activity and then has an xml file related to that view.
So have these 2 files for each new view you show.
Java file:
public class Activity1 extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout1);
}
}
XML file:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/layout1"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
//add any views
</LinearLayout>
Try:
-push activity1 with layout1
-pop inputDialog
-when inputDialog is closed by clicking ok...
-push Activity2 with layout2, proceed with you input from activity1 using extras
...and so on ;)
I have been trying to break up my programs into an activity and a corresponding xml layout for each view. If you have one activity and all those layouts, you have the potential to have a monster block of code in that one activity. I find that breaking it up makes it easier to read and debug.
As for prompting the user before initializing activities, i'm not entirely clear on what you mean. You need to load an activity before anything happens, in your situation it could easily be a simple password acception activity. If you're talking about passing information between activities, you can package data in an intent, and use that to start a new activity. Then in that new activity pull the information out of the intent.
I'd like to recreate a functionality similar to a Swing GlassPane to be able to display animations while the user uses the app "below" normally. I cannot simply create a separate layout and attach it to each activity since the animation state would be lost when switching activities.
Is there a way to keep a persistent view over all the activities of an Android application ?
Thanks.
No its not. Every Activity runs in its own thread and is by design supposed to be runnable standalone.
But you could persist the animation state into the DB or into sharedPreferences and start it over at the new activity.
What you could also do is to use a Spinner or another control instead of seperate activitys. Then you could have a persistent view.
why not think in a TabActivity?
hi! i do this before with a TabActivity, never with an only activity, always with many activitys wich i started, get theirs windows and setting as my TabActivity window´s decor view... i dont tested the code below, since is an idea, but maybe more lately (when i'll be on home) i'll write an example...
So, my idea...
a TabActivity is composed by a TabWidget and a FrameLayout where the activity´s windows is allocated.
the TabWidget can be any view, so, you can put the animated view here.
the most difficult thing is the fact that, if you start an activity from the TabActivity´s child, then the new activity will be on top of the TabActivity. In order to overrides this behavior the TabActivity must know when a nested activity wants to start another activity. When this happens the TabActivity must clear his decor view (with the old window activity) and put the decor view of new one. Something like this:
on the child activity, launch a new activity when we click on a button:
... on click listener...
((MyTabActivity)getParent()).createNewActivity("NewActivity", NewActivity.class);
now, we´re saying the TabActivity that it has to start a new activity, get the new activity decor view and put that view inside the TabActivity decor view... so, the createNewActivity will perform something like this:
public void createNewActivity(String activityId, Class<?> class1) {
Intent intent = new Intent( getIntent().getAction() ).setClass(MyTabActivity.this, class1);
Window wList = getLocalActivityManager().startActivity(activityId, intent);
getWindow().setContentView(wList.getDecorView());
}
hope you understand me.
i'll write an example later
I have a problem that I can't seem to find the solution to.
I have an app that loads the main.xml file on startup, of course. In it are several buttons, and I want the buttons to take me to a different XML file. I just used setContentView(R.layout.newlayout.xml) method for that, and it works great.
The problem comes in after that. If I reference any of the buttons or other objects in the new layout, the app won't even finish loading before it errors out and closes on the emulator. However, if I take all references to objects out, the app runs fine.
I can navigate TO the new layouts, but their buttons can't do anything. Do I need to create a separate Java file for each layout? Or am I doing it all wrong? I'm trying to be as specific as I can. I suppose you could say I need to have different "pages" in my app as a website would.
I think what you are trying to do is best solved using multiple java files, each one defining it's own android Activity.
While it is possible to have multiple layouts/views in a single activity, this will generally make the code more complex and harder to read/debug in the future. By having each 'screen' in its own file, it will be a bit easier to manage all the different views you need to juggle.
The buttons and views only can refer to those mentioned in the current SetContentView() file..
u can test this by creating a button and initialising to an R.id... without setting the content view.. U will get a force close..
so if u change the XML file u shud initialise stuff again....
Ok, for anyone out there with the same problem and haven't figured out how to do it, as I said in my comment on ylebre, my Coworker and I have finally discovered how to do it. First off, we added
implements OnClickListener
to the class, after
extends Activity
then, we created a new java file, and at the beginning of the file it called
setContentView(R.layout.newlayout);
instead of main. Then, we made a button as follows:
Button button1 = (Button) findViewById(R.id.button01;
button1.setOnClickListener(this);
then later in the code:
public void onClick(View v) {
switch(v.getId()) {
case R.id.button01:
startActivity(new Intent(this, NEWJAVAFILE.class));
break;
}
}
And that's it! We just copied and pasted that code into NEWJAVAFILE, changed the names and such, and we were able to navigate freely back and forth. As ylebre said, all of the code for the new activity is in the NEWJAVAFILE.java. OH and don't forget to add the name of the java file to the manifest inside the tags:
<activity android:name=".NEWJAVAFILE">
</activity>
it all seems so simple now!