Should I just initialise and keep both, and set visibility to VISIBLE or GONE depending on the state? Is there a better method? What about memory issues? I would like to have a RecyclerView and a WebView alternately. I want to avoid Fragments - I tried that already and separation of responsibility between Activity, UI and Fragments is a hell.
I keep my UI (inheriting from AnkoComponent) in a separate class, if that matters.
Related
After spending a fair bit of time figuring out that the reason my fragments chosen from a drawer layout weren`t displaying sometimes due to the choreographer skipping frames (I was using transaction.replace rather than show/hide) it made me wonder -- what are the situations where one would want to use replace rather than show/hide or detach/reattach? My problem went away when I switched to using show/hide btw.
Taken from this thread I got this on what happens when you call FragmentTransaction.replace():
Android will effectively perform a sequence of
FragmentTransaction.remove(...) (for all Fragments currently added to
that container) and FragmentTransaction.add(...) (for your supplied
Fragment). Removing a Fragment from the FragmentManager will cause the
Fragment to be destroyed and its state will no longer be managed. Most
noticeably, when you re-add the Fragment all of the views will have
been reset. Note: since you are reusing the same Fragment instance,
the Fragment will still keep the value any instance variables.
and from this thread I got that it is probably better to show/hide rather than replace if you plan on using that fragment again. My question is, in which situations do you use FragmentTransaction.Replace()? The only place I could see it really being useful is for something you know you won`t need again, kind of like a dialog picker with options but I use dialog fragments for those situations.
Does anyone use FragmentTransaction.replace regularly, and if so, why did you choose that over another method? Cheers
It maybe useful, for example, when implementing a deep fragments hierarchy in Multi-pane pattern (when click on item in the right fragment moves it to the position of the left).
Also, since hiding a Fragment keeps it in FragmentManager, it maybe expensive if you have a heavy content in it or hide multiple instances. Calling remove() or replace() and properly saving fragment's state is more Android-way, I think.
In my Android project I have an Activity that uses a Master-Detail view, created with two fragments.
My detailfragment is giving me some "problems" though.
It consists of 50+ controls (TextViews, EditTexts, CheckBoxes, Spinner). Of this 50+ controls I programmatically get a reference to 32 of these controls in my detail-fragment and load their data from my SQLite database.
When I run this and initialize my controls by using
(SomeControl).findViewById(R.id.mycontrol);
LogCat keeps warning me about that I might be doing too much on the main thread.
I know that findViewById and inflating views is an expensive operation, so I had an idea!
I was wondering if there was some way to use the viewholder pattern or view-recycling on my detail-fragment like I'm doing on my ListFragment. that way I could avoid reinitializing my detailview each time I select another item in my ListView. And avoid calling .findViewById as much as I do. Does anyone have an idea on how to implement something like this. Would it make any difference if I did initialization of the controls in the onCreate-method of my detailsfragment? I was also thinking about making my detailsfragment a "singleton" and then just use getLoaderManager().restartLoader when the selection of my listfragment changes. Any thoughts on all of this would be very much appreciated.
Well unless you're using the exact same layout for each control then I'm not sure if there's a way to do that.
But there may be a way to solve your problem: using an AsyncTask.
As long as those controls aren't necessary for your program to crunch data (and from your explanation I don't think the UI elements would be triggered until the user has interacted with it) you should be fine and the main thread will be free to do whatever it needs. The only downside I see with this method would be that some UI elements might appear maybe a half a second late (not so bad if you think about it).
Found a solution. Had to change my implementation entirely though.
Now my implementation is using loaders on both ListFragment and DetailFragment.
Here's a list of changes I've made:
Created a interface for my ListFragment with one method (onSomethingClicked(SomeObject obj)) and made ListFragment observable through this interface.
Implemented the interface in my DetailFragment and registered a listener on the ListFragment.
Implemented the method onSomethingClicked() in DetailFragment. When this is triggered i pass data from ListFragment to DetailFragment and restart my DetailFragment-loader and load data into my already initialized controls in OnLoadFinished.
No need to inflate the view every time the selection in the list changes and no need to .findViewById's AND MOST IMPORTANTLY no more Choreographer warnings :)
Currently, when I click on a row of a list view, I would like to have a new screen for user to edit the detail of the selected row.
I realize I can merely implement the "detailed window" using Activity. However, in the future, I may / or may not need to support Tablet UI. Hence, I was wondering, in that case, should I implement all my logic and UI within a fragment, with another dedicated FragmentActivity to host the fragment?
I found there are good and bad
Good
Easier code reusing and UI reusing, to cater different layout requirement, like new Tablet UI layout.
Bad
Need to take care 2 classes (FragmentActivity and Fragment), instead of Activity only.
Personally, I'm more incline toward FragmnetActivity + Fragment design. But, I'm not sure whether there is any catch in my chosen design?
You got it partially wrong - if all is done done right, your FragmentActivity is almost dummy host with interface to let fragments communicate their needs and all the code should stay in Fragment. And if you want the advice - go for fragments - it's much more flexible and not complicated.
I have a question about whether to use View or Fragment with ViewPager.
Background:
I have an Activity A that contains a ListView. Each ListView item opens Activity B. Activity B shows different content depending on which ListView item is tapped in Activity A.
Activity B's content is shown inside a ListView.
Question:
Now, instead of going back and forth between Activity A and B to switch contents, I have a requirement to implement horizontal view swiping to switch contents all within Activity B.
One solution I found (tried it and it works) is to create many instances of Activity B's ListView and use it with ViewPager + PagerAdapter.
Another potential solution found on the doc (haven't tried it) is to bring that ListView into a Fragment, create many instances of the fragment and use it with ViewPager + FragmentPagerAdapter or FragmentStatePagerAdapter.
My question is, what's the benefit of using each approach? Should I go through all the trouble of bringing the ListView into Fragment or just simply use ListView with ViewPager?
Thanks
A Fragment is a useful approach, I think, when you want to tie some UI business logic to a particular View (or group of). As you know, that individual Fragment has its own lifecycle callbacks and so forth, just as an Activity would.
Rather than having a single Activity host many ListViews through a single PagerAdapter, it may be cleaner to use the Fragment approach because the Fragment only needs to deal with the logic behind driving a single ListView.
This is a very similar situation to one I've just been facing. I'm showing various vertically scrolling forms (consisting of lots of input fields) within a ViewPager. In my case I have gone for the Fragment approach because in my case, it's possible that the ViewPager will actually need to display a completely different kind of view on certain pages. For example, on the first few pages, user input forms might be displayed. But on the final page, a graph will be displayed. A whole separate set of logic is required to drive that graph. To drive those input forms and one graph from a single Activity would get a bit messy, and I would probably need to contain the business logic in several delegate classes or something. So for me, Fragments were the obvious choice in the end. I have my InputFormFragment and a GraphFragment, and they each contain only the applicable logic for the Views that they supply.
Another thing to consider is that in the near future you too may want to display a different kind of View in your ViewPager. Or, you might want to have another UI layout altogether, perhaps one that doesn't use the ViewPager but displays them all side-to-side (e.g. a layout used on a large tablet in landscape mode). With Fragments, things are just far more modular and you could factor the code to do this quicker. If on the other hand you achieved your objective by using a single Activity that contains a simple PagerAdapter and all the logic for the ListViews within, you might find it takes more work in the future to support new kinds of Views or special tablet layouts.
One thing I will say is having implemented Fragments in a ViewPager myself through FragmentPagerAdapter and FragmentStatePagerAdapter, things can get a bit awkward if you have any special requirements; managing Fragments can be tricky sometimes. For example, for my UI I needed to be able to programmatically add and remove the ViewPager containing the Fragments. I also needed to ensure that the adapter in use didn't destroy Fragments once they had been shown, because I needed to collect data from all Fragments simultaneously at a certain point. Furthermore, I had to extend and modify FragmentPagerAdatper to make sure that the Fragments go through their onDestroy() properly and are removed from the FragmentManager when the ViewPager was removed.
Fragments enable a very modular way of constructing UIs for various screen sizes and orientations, and are excellent in how they allow you to encapsulate business logic and lifecycles for individual UI elements. However if your scenario really is just as simple as several ListViews in a ViewPager and you know that you will never need the modularity, then the overhead of Fragments could be an overkill.
I'm writing an app for phones and tablets. Like the Contacts app, there are multiple tabs (2 in my case). For the phone UI, they're managed by a ViewPager, with a fragment for each tab.
But for the tablet UI, each tab is an activity, rather than a fragment. They have to be, because you can't put fragments inside fragments. (Right?)
I realize I could just call setContentView() on the tab listener, but wouldn't that destroy the activity every time it was changed? I'm confused by a lot of this.
What's the best way to do this without breaking my phone UI?
A well designed tabbed UI never uses Activities for tab content.
You're correct in that you cannot nest Fragments in the current implementation, but that doesn't mean your only alternative is Activities. Tabs should always act as a view switch; a tab switch never creates navigation history and tab navigation should always happen within the same Activity.
Remember that Activities and Fragments are just controllers from an MVC point of view. They exist to respond to lifecycle events and manage elements of your application in response to those events, including views within your UI. The content of your UI is wholly determined by the view hierarchy of the current window and you can manipulate the view hierarchy in whatever way makes sense for your app. (While preferably still following the design guidelines!)
Since Fragments have a built-in mechanism for managing a view sub-hierarchy they're often a natural choice for factoring your UI but they're not the only way. ViewPager PagerAdapters can manipulate view sub-hierarchies by inflating them from the resource system, recycling views the way a ListView does, or any other mechanism you can come up with and not use Fragments at all if the lifecycle events they provide aren't needed. Different layout resources may include or exclude certain elements based on screen size using different layout variants for different resource qualifiers.
In short, don't get stuck on the idea that Fragments are the only way to do multi-pane UIs, or the only way to implement each page of a ViewPager. They're powerful options for both, but depending on the information architecture of your Activity you may find yourself using them in a different way than another app and that's OK.
Overall, if you're having trouble determining where the logical cut points are when factoring your Activity's UI, you may be building an overall UI for your app that is going to be as awkward to use as it is to implement. Let the UI design guide your implementation. If each tab is naturally switching out the entire content of the Activity window, then each tab might be well suited to a Fragment. Perhaps those Fragments in tablet mode expand their capabilities and present more than one pane in their respective layouts using different layout resources.