I have numerous activites in my Android app., and most should contain the same, relatively complex set of UI widgets on the screen's top area (lets say that its a kind of toolbar that you can find on most screens).
Right now, every screen's layout contains the markup for this toolbar, along with its logic inside every Activity's source, so it's damn redundant. Could you recommend a more efficient / less redunant way to do this?
I would take advantage of the <include> tag in the layout's xml. This will let you reuse that toolbar very easily and effectively. As for the code I would subclass Activity and place the logic in there, then each of you activities can subclass your custom Activity class.
There are 3 very useful articles on the dev site about this topic. Here is the first one link
I would create a custom View object (subclass View) and then include it in all of your layout xml. You can actually pass parameters, etc. just like built in views. Then define XML for that view that will always be used when that view is drawn on the screen. Also, this allows you to change the view and have that change populated across all of your Activities without having to manually modify all of the code.
Related
In an Android application I'm building, I have a single activity which has multiple buttons and textviews. Based on user actions, I hide the elements and/or show them. This is intentional, cause I don't want the user to change activity.
For further clarity, the activity is a type controller. So when a user enables an option different buttons show up. This is why I want all of them in the same activity.
I am concerned about performance. Currently everything is in a Constraint Layout. Is there an effective way of having mutliple UI elements in the same activity, and having the ability to hide and show them at will? Should I look into Fragments?
Thank you in advance.
As it turns out there isn't a clear answer.
There are a few solutions that may prove useful, I list them below for anyone who might stumble onto this:
Fragment is useful when you have multiple independent parts of your layout. You are limited in the communication between elements of different Fragments.
ViewStub is used when you have some elements which are rarely used in your layout. This makes the initial loading of the layout lighter by not inflating the elements in the ViewStub. You can then inflate the elements on demand.
ViewFlipper allows you to cycle through a list of elements (or display them selectively using setDisplayedChild). It's mostly used for single elements, so I'm not sure about its performance if you were to use it for showing and hiding nested layouts.
ConstraintLayout is probably the best solution for cases similar to mine, where you have a layout of buttons and text which are hidden and displayed in a complex manner.
I am new to android development and currently struggling with fragments and layouts (Xamarin.Android for what it's worth).
I am adding fragments to my View programatically in the OnCreate method of my main view. One of the fragments holds the controls for navigation and implements a fly-over Idiom. Now my problem is, that I haven't found a way to make the width of the navigation fragment, say, half of the width of the parent control. In every override I have been able to access the layout has not been performed and hence the width of the fragments and the main view are both 0. Setting the size of the fragments decleratively in the layout files did not work either (neither for the translate properties which I'll nees to access in the same way to hide the fragment initially). Xamarin/VS complains that setting the size or translate properties to a string (i.e. parent_width or the like) was not valid.
Every tutorial on fragments I've read omits this point.
If I am understanding your problem correctly you are having an issue with layout sizing of fragments added dynamically.
It may be helpful if you were able to paste your code outlining how you are adding your fragments and what override methods you attempted to use. However, here is a best attempt to assist without seeing any code.
There are two approaches to sizing dynamically added elements that I have used in the past consistently. One is to use a base container for your layout of LinearLayout and specify weights for your fragments dynamically. This would allow you to specify that your fragments should consume portions of the layout easily. For instance if you have fragment A and B and you wish for fragment A to consume 25% of your layout space - you can set its weight to 1 and Fragment B's weight to 4. You can find support for dynamically setting weight of an element (such as your fragment) here: How to set layout_weight attribute dynamically from code?
Another option would be to use the an OnGlobalLayoutListener that will "fire" when the control is laid out. This will ensure when you try to measure the layout to determine its width/height that it has already laid out and consumed the proper space for measurement and you will not get back 0. There are a number of articles outlining how to write up the code for this listener scattered throughout the web. I It may also be useful to subclass out some of the listener functionality for easy reuse if you find you have a need often to know when the control has laid out. Here is a link to the Android documentation on the subject http://developer.android.com/reference/android/view/ViewTreeObserver.OnGlobalLayoutListener.html.
Hope it helps.
I would like to know if it is wise/possible to have one activity that displays multiple different UI elements dynamically in a single layout?
So I want to have a single activity that loads a blank layout and then from code I add various UI elements such as buttons, text views etc. Then when a button is pressed, for that layout to clear and then from code draw the next set of UI elements on that same layout and so on and so forth?
Or would it be better to have multiple xml layout files and just inflate them each time I want to use a different layout, so then not create them from code?
Hope that makes sense.
Thanks,
Wihan
You should look into Fragments.
Activities are not intended to do what you would like them to do.
Instead you use one Activity and add a Fragment(s). Those Fragments can then be dynamically switched via code.
Take a tour => http://developer.android.com/guide/components/fragments.html
Yes this is very much possible. But Android xml layouts give a very easy way to use and manage different views. You could add views to ViewGroup and clear the ViewGroup.
I would also suggest using Fragments . This could be dynamically added and replaced.
I typically organize my code/logic by a fragment represent one layout. Now I am in need of few relatively simple forms to get input data from user, which are somewhat related in purpose.
Say I hav 3 screens, and I could create 3 fragments to handle them (display view, read input, submit, ..). Or should I use one fragment, and use FrameLayout create a stack of layouts. I was thinking like, stacking all 3 views and hide/display the view I like. But the documentation say
Generally, FrameLayout should be used to hold a single child view,
because it can be difficult to organize child views in a way that's
scalable to different screen sizes without the children overlapping
each other
Any good way to do this or should I create multiple fragments for this (the down side of this is lot of small classes and repeated code. I may use a base class, still like to explore other options)
Thanks.
It sounds like you don't really care that much if the views overlap each other in the FrameLayout, or in fact they are supposed to overlap because you expect to be showing only one at a time. FrameLayout can certainly display stacked child views that each take up its full width and height just fine, and if you set the visibility of the unused views to INVISIBLE or GONE, they will not intercept screen presses or take focus if they happen to be located above the visible view the user is interacting with.
On the point of readability and code maintenance, I think swapping fragments makes more sense though, even if there is more memory overhead. The layout management can be encapsulated within the individual fragments, and you do not need to worry about showing/hiding views, as fragment transactions will take care of that aspect.
What are the differences between <\include> tag and <\ViewStub> tag and which one is preferrable while designing the layout.
The < include /> will just include the xml contents in your base xml file as if the whole thing was just a single big file. It's a nice way to share layout parts between different layouts.
The < ViewStub /> is a bit different because it is not directly included, and will be loaded only when you actually use it/need it, ie, when you set its visibility to VISIBLE (actually visible) or INVISIBLE (still not visible, but its size isn't 0 anymore). This a nice optimization because you could have a complex layout with tons of small views or headers anywhere, and still have your Activity load up really fast. Once you use one of those views, it'll be loaded.
include
It is used to reuse layout resource
ViewStub
It is used to lazily inflate layout resource
Sharing and reusing layouts is very easy with Android thanks to the tag, sometimes even too easy and you might end up with user interfaces that contain a large number of views, some of which are rarely used. Thankfully, Android offers a very special widget called ViewStub, which brings you all the benefits of the without polluting your user interface with rarely used views.
A ViewStub is a dumb and lightweight view. It has no dimension, it does not draw anything and does not participate in the layout in any way. This means a ViewStub is very cheap to inflate and very cheap to keep in a view hierarchy. A ViewStub can be best described as a lazy include. The layout referenced by a ViewStub is inflated and added to the user interface only when you decide so.
Another important difference is related to layout inflating. with it is not possible to change the layout already static inflated in XML, it is necessary to replace the view and set programmatically al the layout parameters.
With it is possible to define (for e.g.) height, width, etc... and inflate different layout at runtime time