Displaying view/progress spinner/error view - android

I have a frame layout with 2 children. A custom view and a progress bar.
Only 1 at a time is visible. Works as I need.
I want to also add some error view which will display an error and the other components would be hidden.
Is using a FrameLayout a good idea or should I switch to RelativeLayout?

If the layout works for you I would stick to FrameLayout. Since there are only 3 children (and assuming that none of them has children) the difference in performance should be really minimal (if any), but one difference I noticed digging into the source code of both FrameLayout and RelativeLayout is in the onMeasure method, FrameLayout will iterate twice all of its children, RelativeLayout iterates from 3 to 7 times (!)you can check FrameLayout onMeasure and RelativeLayout onMeasure yourself

Related

How to use View.layout() method to change view size?

I have problems doing a small game which adds a lot of views in a ConstraintLayout (I already tested with FrameLayout, RelativeLayout and LinearLayout. First two with same result and Linear with very rare behaviour) and changes the size and position of the views.
Each game loop (33ms) some of the views are changing it's size and position, so I do this on the LayoutParams variable applied on the View on each loop with the new size.
params.width = realWidth;
params.height = realHeight;
and I do this for the position:
view.setX(realX);
view.setY(realY);
The problem is that the change is not reflected if I didn't call view.requestLayout() and that is a huge problem because requestLayout() is repaiting the parent layout and all its childrens, slowing down the game.
How can the size changes of a view be reflected without calling requestLayout? I read that you can achieve that with view.layout(). So I changed my code with this:
view.layout((int)realX, (int)realY, (int)realX+realWidth, (int)realY+realHeight);
The problem is that it works without calling requestLayout() but the view has a very rare behaviour using layout(), and when I add more views, the views become some milliseconds invisible and appear on the left top corner, after that they appear in the correct position, but suddenly they become invisible again and again and again etc in a very rare behaviour loop.
ConstraintLayout is slow, particularly if it contains many Views and much slower if it contains nested ConstraintLayouts.
Because of you are manually setting the position for your Views, you can use a different ViewGroup than ConstraintLayouts and set the absolute position with setX(), setY(), setTop(), etc.

Overlay's height does not match_parent when adding view dynamically

I have a RelativeLayout (A), inside which I have 2 children:
- LinearLayout (B) (with some stuff)
- below it I have another RelativeLayout (C)
I wanted to add an overlay on top of it. So all I did was added a View with match_parent as it's width and height, and transparent background. All works great, as long as I do not add views dynamically to the nested RelativeLayout (C).
When I do that my overlay stops at the last element that was not added dynamically to the RelativeLayout (C). So the height of the overlay does not match_parent anymore.
I tried to go around it, and add the overlay after I add those dynamically added views to (C), but that also didn't do the trick.
What does the trick is if I set height explicitaly to the overlay after all views are created by getting getHeight of the main root of the view. That is however not the solution I want, as I want a clean solution, that I explained above.
Currently what I did to bypass it for the moment, is I added an overlay with a humongous height(like 2000dip) and set it's bottom alignment to RelativeLayout(C). That does the trick perfectly (the effect of it), however I still would preffer to know the reason why adding dynamicaly those views does not update the height of the overlay (also if I add it dynamically after previous views).
Just to mention, I tried to do requestLayout(), invalidate(), and postInvalidate() on the main container after all views were added. No change.
ps. Might be important piece of information: this root RelativeLayout stated in the beginning is inside a LinearLayout, which is a single child of a ScrollView

Parent view draw child view efficient

For example, top level LinearLayout view has 300 child view. But device screen dimension only show 11 child view once. How android compute how many child views can show once? How a view know that it will be draw?
Edited
In my work, one case like this:
An parent LinearLayout view may be has hundreds child view. In order to better performance , my solution like this:like lazy load.
List list = new ArrayList();//contain entity object that use construct View object
Default load 5 child view.
Parent LinearLayout view last child view is custom Loading View, I have override it`s onDraw() method. If loading View is draw, that means i need get next 5 child view(get next 5 object from list,and create correspond view).
I want to know how android framework handle this case?
Have u used scroll bar inside the top level LinearLayout view and add child view on that layout that's simple...
An parent LinearLayout view may be has hundreds child view. In order
to better performance , my solution like this:like lazy load.
LinearLayout with(possible) hundreds of child views kind of contradicts better performance. I think what you're looking for is a ListView with an endless adapter(a simple google search will show how to implement it, not something that difficult). This adapter will start loading views(with a loading view showing while the new content loads) as soon as you get to the last loaded element.
If you still want to use a LinearLayout:
If you just want to make the LinearLayout fill the content of the screen when it's first laid out you could post a Runnable on one of your views in the onCreate method (if this is where you'll first populate the LinearLayout). In that Runnable find the height of the LinearLayout and compare it with the combined height of its currently present children. If the combined child height is smaller then the LinearLayout height then add more views to compensate.
If the LinearLayout is in a ScrollView and you want to add additional children when the loading view becomes visible then monitor the scrolling of the ScrollView and when the loading view becomes visible add new children. Seeing when the loading view becomes visible would be done by checking how much the user has scrolled compared with the combined height of the currently present children of the LinearLayout.
Initial response:
Your question is a bit ambiguous regarding what you want to know. If you have a specific problem you should start with that.
For example, top level LinearLayout view has 300 child view. But
device screen dimension only show 11 child view once.
Please don't get yourself in a scenario like this. That number of views is to big an will result in poor performance or even the app crashing if you run out of memory(as all those views will be kept in memory).
How android compute how many child views can show once?
Each View and ViewGroup has the onMeasure method to measure itself and its children if available. The LinearLayout will have its onMeasure method called and in this method it will measure its children(with the measure method) giving them some suggestions on how big should they be(the LinearLayout receives some suggestions on how big it should be from its parent). If you want to see how this is done have a look at the source code of the LinearLayout.
How a view know that it will be draw?
I don't understand what you want to know. To draw the view on the screen its onDraw method will be called.

How to restrict bounds for Translate Animation for a view in Android?

Let me explain the scenario that I want to achieve:-
Consider the below as the Layout I have inside a Parent_Linearlayout:
[Linear Layout] (Fill_Parent, Wrap_Content)
[ScrollView]
Activity's setContentView is set to the Parent_Linearlayout
In the application, when a condition is met, I want the Scrollview to be removed from the screen and instead put another View in its place.
I've been able to do this, & when I remove the ScrollView, I'm applying translate Animation to it so that it seems as if the View has gone to the top -before removing it.
But when the animation occurs, the ScrollView translates OVER the Linear layout present above it.
How do I restrict it, so that the scrollview does not go over the linear layout, but disappears at the base of the Linearlayout. I want the linearlayout to always stay visible..
I've been trying to do this from quite some time, but I've not been able to get desired results..
Could someone kindly help me out here??
I don't quite understand your description of your layout, but the Android view system is drawn based on the ordering of the views in the hierarchy. Views added later to a parent are drawn after those added earlier. So if you always want the LinearLayout to be drawn on top of the ScrollView if/when they overlap, then declare or add the ScrollView object to its parent before the LinearLayout object.
In thinking more about this, I suppose the ordering here is important because you want the ScrollView to be placed below the LinearLayout in the parent of both of these views. Putting the ScrollView first (and thus having it painted first) would then put it above the other LinearLayout, which isn't what you want.
There are various ways to achieve what you want. For example, you could use a RelativeLayout as the parent of the views, then the ordering is not important.
Alternatively, you could place the ScrollView inside another LinearLayout (and that LinearLayout would be the second child of the overall parent layout). Then when you animate the ScrollView, it would be clipped by its immediate parent, which I believe would give you the effect you're looking for (make sure that setClipChildren() is set to true on this new intermediate LinearLayout, which it is by default, otherwise it won't clip the ScrollView as it animates out of it). Note that this approach would necessitate different animation values, since you are now animating the view outside of its parent (the new LinearLayout).

Add view to XML layout programmatically and make its z order below an existing view

I have an XML layout with some custom tabs, a heading, and a ProgressBar(main.xml). I wish to add another XML layout(home.xml) to the main.xml layout, as i wish to keep main.xml re-usable for other activity's layouts and simply add things to it as necessary.
home.xml contains a ScrollView and a TextView. I am currently using my Activity's LayoutInflator to add home.xml to main.xml:
LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.home, rootLayout);
rootLayout is the root layout of main.xml and is a RelativeLayout
The problem: after inflating R.layout.home into rootLayout, it seems as though the ProgressBar contained in rootLayout is hidden underneath the content of home.xml
Is there a way to tell certain views(via XML) to float above other views when the layout is constructed in this way?
if not, am i forced to use methods such as progressBar.bringToFront() to raise targeted views to the top?
what alternatives do i have in z-ordering views when some layouts are constructed using inflation?
edit: it seems as though the bringToFront() method is not doing what i expect - i call it on one of my Button views and it still appears to be ordered below all other views(which were inflated) and remains unclickable
You could try using ViewStub instead of manually adding it and set the set the inflateId with setInflateId(R.layout.home)
http://developer.android.com/resources/articles/layout-tricks-stubs.html
Edit:
Google seem have to moved the android developer from their android page to blogspot.
Updated Link:
http://android-developers.blogspot.com/2009/03/android-layout-tricks-3-optimize-with.html
Views are drawn based on their order in the parent. For instance, the child at index 0 is always (at least with the current layouts, except Gallery) drawn first and the child at index count - 1 is always drawn last. bringToFront() simply moves a View from its current position in the parent to the last. Note that changing the index of a child can affect its position on screen (for instance in a horizontal LinearLayout, moving a child from index 0 to index count - 1 will also move it from the far left to the far right.)

Categories

Resources