I have to implement a tree browser in Android. For this particular case, the tree will be a folders hierarchy. So the user will start in a root directory, and will be able to browse the whole hierarchy.
I have experience in iOS development, and this could be done using a UINavigationController, pushing a new controller each time the user taps a folder, but I am not sure if using the same strategy in Android is the right thing to do.
My first idea is to have a FolderViewActivity, create the first one with the root path, and every time the user taps a folder, create a new one with the new path. So you have a stack of activities, and if the user wants to go up, the current activity will be finished and the previous one will be shown.
Is this the right approach? Could be any problems with the back button doing this?
I have seen a few projects in github implementing a file browser, and it seems that everybody tries to reuse a single activity for doing everything, updating an adapter with new data when the user taps a folder. For me this is a poor implementation, unless there is a good reason for doing it (something Android specific?)
In Android you should use as less activities as you can. Activity is quite expensive object and it should be instantiate only if you need specific context with some different settings (orientation, action bar) or if you want to do some new things (for example, editing file content or displaying settings).
When you navigate through file tree you actually do the same action every time: show directory content with some path. For this routine you should use such lightweight and reusable objects as Fragments (http://developer.android.com/guide/components/fragments.html).
The benefits of such approach are: less memory, less expensive calls (create or destroy activity), more fast, more flexible, you can handle back button press as you like.
So you should not create a stack of activities, you should create one activity and then replace fragments for every new folder.
I'm doing the same using a recyclerview. No need for fragments or activities. Firs load the root, after a click you need to update the adapter of the recycler view with the new child objects. You can keep a navigation stack in order to have a navigation back strategie.
Related
If I have an app that refills a ListView with different data in response to a user selecting an item. Should I start a new Activity or just change the data, and call Adapter.notifyDataSetChanged()?
It seems like calling notifyDataSetChanged() is simpler, and would minimize my potential number of activities (and memory usage), but I want the Up/Back navigation to work.
My app works like File Explorer where there is a list of folders, and clicking on a folder changes the list to show the contents of the new folder. If the user clicks on a folder, I want the Up/Back buttons to take them back to the prior folder. I have implemented this with a single instance of the activity and using notifyDataSetChanged(), but can't get the Up/Back buttons working as desired. I am thinking I need to either override those somehow, or use multiple instances of the same activity. Any direction here would be appreciated.
Thanks
Using multiple instances of the same Activity is highly unproductive.
To solve your problem, the best way to do it would be to use a fragment using multiple instances of it, each one representing a folder in your arborescence. Then in the onBackPressed() of your activity, you can just
use popBackStack() while there is a fragment in the backStack, then call super.onBackPressed() to resume default behavior.
I am developing an application which should display a number of tiles on the first page. Tiles are generated dynamically from json, each should allocate itself according to size specified in json and should take as much screen as required. Each tile represents short summary of information. The requirement is that when tile is pressed user is redirected to another page which provides more detailed info (like a form) which takes the whole page. User then should be able to go back to previous page and choose another tile if needed or go back to the first one. I don't know in advance how many tiles there will be and what are their components, so everything is dynamic. There is also a possibility that small tiles(with different info) can be required to be drawn on detailed view.
At the moment I am on the stage where all small tiles are displayed on the first page and I need to find the best way to display detailed view and allow user to navigate easily and quickly. Each tile extends RelativeLayout because of absolute positioning of components inside. I am considering switching tiles from Layout to Fragments because they seem to be providing flexibility required and many articles and tutorials I search refer to them. In this case when user presses the tile fragment, all existing tiles would be replaced with required detail fragment. Pressing back button would replace detail fragment with previous smaller ones on the screen (would it be display all of them or only one?).
Another option I am considering is to leave layouts and on tile press redirect user to a separate Activity with detail view. In this case navigating back seems to be destroying activity and it will need to be redrawn again if user wants to come back to it (redraw is not desirable).
My question is what is better for performance. Each tile as well as detail view might have some images in it and full page will take time to load. But figuring out how to handle this with Fragments programmatically might take a while and the last thing I want to find is that Fragments are not suitable. Maybe you have other ideas for scenario described? Any good tutorials/articles where Fragments are created and managed programmatically completely(no XML).
I am relatively new to Android and completely lost now.
Edit:
Thanks everyone for your advice. I can't choose the best answer at this point. I have to do some more research and learning now. Will do that later.
Fragment should be the best way to go. because filling details in a fragment dynamically is easy. will help check some codes i have written that could solve this
Fragments are a new style in Android for creating GUIs, they should not be compared with simple Activity + xml layout's in performance terms. Fragments were created to make it easier to build complicated GUIs, on both phones and tablets. You can create low performance GUI using both methods.
From your description I suppose its best to create two fragments, and wire them in Master Detail pattern. Master will be your json list with short summaries, and detail will be your additional data fragment. You can still put both fragments in separate activities, and show detail fragment from master one (master actitity will get hidden) - this makes sense on small screen devices. But you can show both fragments on one screen on tablets. See 'Master Detail Flow Template', http://developer.android.com/tools/projects/templates.html.
So fragments gives you a lot of flexibility to modify your UI, without huge code rewrites.
Some new widgets like ViewPager will work only with fragments, so if you want to use it you better invest time in learning them.
From what you have described above you do not need Fragments to do this. On your main page you can use a GridView to display your tiles. You could create two other Activities. One called TileActivity which will open each time a tile is pressed. Then you could create a PopulateActivity which would populate the TileActivity with the relevant information depending on which Tile was pressed. In terms of performance instead of closing the TileActivity to go back to the main page you could use Intent Flags so that the TileActivity isn't closed it is just added to the stack and then restarted instead of recreated each time its called.
I would like to display a tree without using the tree component, since I don't know how many levels there will be.
I though about a list, that opens another list on item click, and so on...
Is it correct to open a new activity for each level?
Will it not overcharge the system?
Or is it preferable to have only one list that I clear and refill with children?
How the standard back button will behave on both case?
I would have open a new activity for each level. Unless your tree is extremely deep, it will save you time handling back's button correct behavior by hand if you do it with only one activity.
I think I didn't clearly asked this question before(because I didn't get the answer that I needed) and it was a mistake to post this version here, so I'll try one last time.
I have a big tree of activities where there is one root-activity with 6 list items, each item leads to its own activity with its own list of items, etc. One generation of the tree can be displayed in one activity. So there is only 1 activity for the root and 1 for all of its children(just different list items which are displayed during the runtime depending on the previously chosen item). Navigation obviously should work in both directions - forward(get closer to the leaves of the tree) and backwards(get closer to the root). Hops between generations are also possible(eg we can jump from the 1 generation straight to the 3 and backwards). I think that creating intents every time user goes to another activity is not reasonable. Is there any pattern or good practice to manage multiple activities like in this case? Maybe in each activity should be stored a static class which returns its intent or another management class created?
In Android activities are managed on a (back-) stack. Which means you can start a new activity and it is pushed onto the stack and is the activity shown. When going back via finish() this top activity is popped from the stack.
Stacks and trees work together quite well. When you move around in a tree you can keep the path to the root on a stack. This way managing trees of activities is what Android is actually made for.
Going down in the tree means calling the activity of the child node. Going up again is done by simply finishing your activity. You automatically appear at the activty one level up in the tree.
I am working on an Android app that has multiple screens the user will need to navigate between and I am curious what the best practices are when switching between those screens. I am torn between creating a new Activity for each screen and simply changing the view (setContentView(R.layout.whatever)). The screens all share at least some variable values so I'm leaning toward changing views and using class level variables, but I'm worried a single activity could become very large and confusing with logic for multiple screens in a single file. I'd like to keep the code clean and separated, but I also don't want to be passing several variables around between views if that isn't needed.
Being new to Android development, I'm hoping some more experienced members of the community could share their thoughts and let me know how best to handle it.
Thanks!
Note:
I wasn't planning on using a viewflipper. My thought was to use a button click event and then call setContentView() to a new view for the page I wanted to bring up next.
Example: My application starts up using R.layout.main as it's view. User clicks the Help button and it calls a method that runs setContentView(R.layout.help); to display the help screen as opposed to switching to a help activity.
You should use an activity per screen as this will make the best use of the framework and allow the OS to selectively kill off screens if things get tight.
If you have a single activity and resources get tight the OS has two choices; kill everything or kill nothing, and if the user is not using your app then it's most likely it'll kill everything.
If you use an Activity per screen the OS can kill off some of the screens the user hasn't visited for a while, whilst still allowing others to remain active which allows the user to go back to them quickly.
As for sharing variables and values, you could use the SQLite database or SharedPreferences stores for passing them around if they are widely shared, or use the putExtra methods in Intent if they're only of use from one screen to the next.
If you have variables that you will reuse make a base class for them, that you will extend.
This can be a your custom activity that extends Activity.
As far I can tell you have to create separate activities for each views, only a few situation can be handled by viewflippers.