I have a TabActivity with three tabs defined. The first tab is light-weight and renders in acceptable time. But the 2nd and 3rd tab, does need a couple of seconds to get visually rendered, after I click them. I would like to launch them, after I've loaded my first tab, in background for pre-cache. Once they are loaded, I can switch quickly between them.
So I am wondering how can I launch the 2nd and 3rd tab. They are new activities loaded in the view area.
Step #1: Get rid of all the activities being used as the contents of tabs.
Step #2: Rewrite them as being Views (children of your FrameLayout in your main layout file for the TabHost activity), and get it working. Having activities as the contents of tabs adds overhead for no meaningful benefit.
If that is insufficient of a performance gain, then...
Step #3: Move your second and third tabs into separate layout files. Inflate them in onCreate() but just hold onto them (don't attach them to the TabHost). When adding the tab specs, use the one that takes a TabContentFactory, and have the factory grab the pre-built Views.
If that simply shifts your performance problem into onCreate(), then...
Step #4: Try inflating and setting up those views in background threads. This may just blow up, because Android does not like UI operations on background threads. Even if it does work, you will need to have smarts to deal with the possibility that the user clicks on the 2nd tab before you are done with your work.
Or, you could just speed up whatever those tabs are trying to do so they don't take as much time, at least at the outset.
Related
I have an activity that has within it one fragment that takes up the whole screen. At some point in the app flow, the user can go to another screen in the same activity that is composed of two seperate fragments. So you can imagine it as:
Fragment A (100% of the screen) -> Fragment B (50%) + Fragment C (50%)
I can think of two ways of doing this and neither one of them is particularly good. The first is to set a layout for the activity that has in it one container that will hold Fragment A, and then have Fragment A open subfragments B and C inside it. I'm trying to avoid using subfragments because it leads to unusual lifecycle bugs and it also isn't supported by all version of the api.
The second way is to have two layouts for the activity - one layout having a single container, and the second one having two containers and then switch between them at the appropriate moment with setcontentview. I have to admit that I'm not too happy about that solution either, since it means the user will see the screen redraw white instead of a nice transition effect.
Does anyone have any suggestions on how to do this most efficiently? Note that I do want everything to remain under one activity - logically it should be this way. There's no logical point in having two seperate activities for this UI movement.
solved by having two containers and setting the top one to wrap_content height, visibility=invisible and not populating it at all. When I need to move to the two pane setup I populate the invisibile container and set it's visibility to visible which causes it to remeasure. When moving back from the two pane to the single pane call remove on the fragment that populates the top pane.
I've got a problem that I'm having problems solving. My app has 2 types of fragments. When the app starts, a fragment with main menu is added to a FrameLayout that I use as a fragment container. This fragment takes up the entire screen. Then, when I choose one of the items in the menu, a corresponding fragment should be loaded into the container, replacing the menu. However, this fragment must only take 1/4 of the screen from the left, and the space outside is to be used by some other fragment.
I was thinking about making 3 FrameLayouts, one for the left side, one for the right and one for the entire screen, but this is going to have problems with fragment transactions, since I would have to keep tabs on which fragments are where and remove them by hand.
Basically what I need is some way to change whether my fragments are loaded into a container that takes up full screen, or a container that takes up only some part of the screen. I probably could do it with tons of trail and error and some code, but I bet there is a really easy way to do this in android that I missed.
Instead of trying to dynamically load these fragments into the various containers, I would suggest having two different Activities.
It sounds like the main menu fragment will only ever appear on its own in full screen. So, make that a full Activity (let's call it MainMenuActivity).
The second activity will have two FrameLayouts as it's contents, with one taking up 1/4 of the screen and the other taking up the remaining 3/4. Load this second activity upon choosing a main menu option and populate the fragments in onCreate() of the second activity.
Hitting the back button from the second activity will return the user to MainMenuActivity.
I am trying to create a layout in an activity that will look different in landscape and portrait, however it will contain the same sections, just in different places on the screen.
Most examples I find on fragments is always the list and detail, which is not what I'm looking at.
In my example I have, amongst others,
a scrolling image section (carousel)
a page title with some brief details
a carousel of thumbnails
two buttons
full details of the page
Now in the landscape layout, the image section will always be on the left side with down the right side, the page title, carousel of thumbs, two buttons and full details.
In the Portrait the title will appear at top, with image carousel beneath, then thumbs, then buttons etc.
The way it works in my head, is that each section should be a fragment, and then depending on the layout file in the respective res/layout folder corresponding to land/port, the fragments are arranged accordingly. But I'm also thinking is each section a whole fragment? Or could it be a separate view that get's loaded in, but just in a different order depending on the screen orientation.
I hope that made sense?
Does anyone have any good tutorials that explain exactly when you should and shouldn't use fragments. All the usual suspects just list the list/detail example, which is not applicable in my case.
tl;dr Can I use fragments as modules/blocks in various layouts or should I just create other layouts and display them inside the main layouts.
Fragments can be used to have split screen and to store previous state unlike views. It is difficult to manage back button with views
If you just want to change how the screen is laid out, the answer is neither. You can define orientation-specific resources (either a separate layout file for each orientation or different dimensions/constraints for each orientation) and the system will just provide you with the correct resource set for the current orientation.
That said, it sounds like you may be describing a modified version of master/detail flow. If this is the case, fragments are a good way to go since the landscape view is actually several separate screens in the portrait version of the app, so each section needs it's own state and lifecycle, which fragments provide.
Now, I know you said you wanted an example beyond a list and detail view, so here's some more details on when to use fragments:
Fragment, like activities, have state and lifecycle. Custom views do not have lifecycle and are completely dependent on the activity or fragment containing them.
You might use a custom view when you have a widget on screen that is used in multiple places and is just like any other view – bound to the activity when the layout is inflated and controlled from there. It's a way to either reduce duplicating combinations of views in your layout or to draw a custom view that doesn't exist yet.
Fragments are good when you need some state or lifecycle for a section of the app that might get used in multiple places or shouldn't be logically connected to the activity it is contained in. If you use the new Navigation Component, you actually just define one activity and then each screen in the navigation tree is a fragment that gets swapped out as the user navigates around the app. Here each child component on the screen (each "screen" that the user navigates to) has it's own lifecycle, business logic, etc, so mixing the code for all of that in the activity wouldn't make sense.
So the question comes down to what you are trying to build, and this may be a case where the best way to learn the difference is to try each option out as bit. The differences become more clear with practice using them. As a general rule of thumb, personally, I only really use custom views when I am trying to make a new view that doesn't exist elsewhere. If what I'm trying to do is simply a matter of laying out existing views in a new way, the answer is probably some trick in the layout file or layout code inside the activity. If I'm trying to make a stand-alone piece of the app that does stuff, especially if it also appears in multiple places in the app, I'll probably be building a fragment.
I'm using FragmentPagerAdapter with a tabbed interface. My interface happens to have three tabs. I can see that as soon as my app is created, the adapter requests that both tabs one and two both be created immediately (I assume this is so swiping to the next tab appears smooth to the user).
Is there a way to stop the automatic loading of the next tab? My tabs are pretty heavy, and loading two right at startup is taking a good deal of time,
Thanks
Is there a way to stop the automatic loading of the next tab?
Sorry, no. This is driven by setOffscreenPageLimit(), and the minimum value is 1, meaning that ViewPager will always try to create and hold onto at least 1 page on each side.
It sounds like you need to move more logic into background threads.
The Android developer guide (http://developer.android.com/resources/tutorials/views/hello-tabwidget.html) states:
`You can implement your tab content in one of two ways: use the tabs to swap Views within the same Activity, or use the tabs to change between entirely separate activities. Which method you want for your application will depend on your demands, but if each tab provides a distinct user activity, then it probably makes sense to use a separate Activity for each tab, so that you can better manage the application in discrete groups, rather than one massive application and layout.
In this tutorial, you'll create a tabbed UI that uses a separate Activity for each tab.`
In my cases, it doesn't make sense to have separate activities for the tabs so I want to switch views, but it would be nice to see an example.
Gee, thanks Google!
In my cases, it doesn't make sense to have separate activities for the tabs
I have yet to find a good argument for having separate activities for the tabs.
so I want to switch views, but it would be nice to see an example.
Here is one. Here is another.
The recipe is pretty simple:
Step #1: Add the tab contents as child Views of the FrameLayout
Step #2: Use the setContent() (on TabHost.TabSpec) that takes an ID as a parameter
Step #3: There is no step #3