How to alternate between fragment containers easily? - android

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.

Related

Display slidingUpPanel across all activities

I'm trying to add a slidingUpPanel(Sliding up panel) across all activities. This panel consists of a viewpager which in turn consists of two fragments. One of these fragments has a recyclerView (more than 1000 items) and the other fragment has some data that changes dynamically depending on the users' choice. This panel is very similar to that of google play music and soundcloud. Now to display this panel I tested two approaches:
1) I created a base activity and added the sliding up panel to it and then extended rest of the activities to base activity. So this way I have to create only one panel and viewpager.
2) I included the sliding up panel in all activities. But this approach is quite unmanageable as I have create viewpagers for all activities and if data changes in one activity I have to write the code to reflect that change across all activities.
Now the problem with both the methods is that each time I open a new activity, a new instance of the viewpager and fragments is created. So, suppose if I have 1000+ items in the recyclerview fragment, switching activities takes more than 2-3 seconds, because each time new instance of fragment is created and the data is loaded all again. This will definitely result in bad user experience.
Is there any way by which the viewpager and the fragments are created only once(when the app starts) and are destroyed only when user closes the app? And data should not load each time user switches activities. I just want to reduce the activity switching time. Any ideas?
Thank you.
Well, for such ui elements as your sliding panel, which stays the same for many items it is preferable to have a single activity.
So if you have 1 activity, you can have a viewpager inside sliding panel, and that part stays untouched. Next, inside your activity you can have FrameLayout wich can be used to host fragments. Doing this you can achieve single instance of sliding panel and navigation between content with fragments.
Having some heavy data collections makes you wishing minimum recreation of that items.
Two approaches for this are (assuming you're using SlidingUpPanelLayout by sothree)
With bottom navigation view
Easy way to do it is creating a bottom navigation view and keeping it in MainActivity and attaching the sliding up panel layout to the bottom navigation view ( layout_above = bottomnavbar_id ) since bottom navigation stays throughout the app so sliding up panel will also have to stay with it
Without bottom navigation view
Create a frame layout inside MainActivity give attributes width and height as match_parent and create slidinguppanelayout and give attributes gravity="bottom"
make the frame layout stay above that slidinguppanellayout , use that frame_layout to show content your want to show from fragments
that's all

Android: one fragment turning into two fragments on one page

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.

Changing layout files for a fragment during runtime

I am trying to develop an app in which fragments are involved. There are 2 fragments on screen. The list fragment containing a Start and Stop button and a detail fragment on the right side. On click of the Start button an audio processing code runs in the detail fragment. So depending on the result i get out of the process I want to change the layout of the fragment. Basically I want to change the layout file of a single fragment during run time depending on the results I get while doing some process. How can I achieve it?
Thanks!!
You cannot switch to a different layout file in a fragment, the view you returned from onCreateView cannot be replaced.
However, you have several options:
You can show and hide views at runtime with View.setVisibility().
ViewStubs can be inflated at a later time.
Or you could replace your detail fragment with a new fragment.

Android Honeycomb: layout problem - hide/show FrameLayouts

in my Activity, I have a layout containing 3 FrameLayouts, one at the top, one at the left and one at the "center".
Now, I sometimes only want to display one or two of them. Atm I am doing it this way:
FrameLayout frame = (FrameLayout) findViewById(R.id.framelayout_menu_left);
frame.setVisibility(...);
frame = (FrameLayout) findViewById(R.id.framelayout_content);
frame.setVisibility(...);
frame = (FrameLayout) findViewById(R.id.framelayout_menu_top);
frame.setVisibility(...);
However this can get really ugly results, e.g. when I switch the "content" Fragment and hide the top and/or left FrameLayout. It all starts flickering as the "content" Fragment jumps to the top and/or left and only afterwards is replaced.
Also, I can obviously not navigate back to another setup, so is there any other way to do this?
Kind regards,
jellyfish
Edit:
Maybe a little drawing makes my question clearer...
A shows a Layout of 3 FrameLayouts containing 3 different Fragments. Each color represents one distinct Fragment.
Now what I want to do is to switch from A to D.
I am doing this by replacing the blue Fragment with the yellow Fragment via a FragmentTransaction.
However, this still keeps the other Frames visible, so I hide them via the code above.
Now, Frame.setVisibility() is called way before commit(), so in B and C the blue Fragment "jumps" to the left and the top and only afterwards (in D) is replaced with the yellow Fragment. This produces a nasty flickering.
As a workaround, I now hide all three FrameLayouts before the transaction and re-show the ones I need once the transaction has finished. But there still is the problem that I can't go back via the back button as this isn't a real transaction.
I would have two suggestions. Firstly, if you both add a fragment transition effect and do the visibility changes after the transaction, that would probably substantially reduce much of your flicker effect
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
Secondly, I've simply given up on having the system manage the fragment stack for me -- it seems that this only works well with simple transactions. Override onBackPressed and do your own logic there.
--randy

Start all tab's activities for pre-cache

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.

Categories

Resources