I have a UI layout that's comprised of a single outer layout that contains three internal layouts. The internal layouts are essentially a header, body and footer.
I would like to cause the top, header view to become completely hidden if it's forced to shrink past a certain threshold. It contains a logo image, and if it shrinks past a certain point, I'd rather just hide it completely.
What's the best way to do this? Is there a way to accomplish this statically in a layout xml? If not, do I need to subclass the View and listen for resizes? Is there another way?
Subclass your View an override the onLayout or onMeasure methods. That is when the View itself decides its width and height. After onMeasure is completed, you can call this.getMeasuredHeight() and check if its below your threshold. If it is, just hide it.
I don't think you can do it in the XML, but whenever anything happens that could shrink it (you might need to use an onTouchListener() if it's shrunk by the user's finger), you can call getHeight(), and if it's less than a certain value call setVisibility(View.GONE) on it.
Related
Is it possible to animate RecyclerView height, or otherwise change it programmatically? For example, if I have a large header view that is sometimes visible, and other times not - I would want to animate the RecyclerView height to fill the screen when the header is animated out.
Changing LayoutParams.height does not seem to work. LinearLayout animateLayoutChanges causes a crash.
<LinearLayout>
<RelativeLayout (header)>
<RecyclerView>
</LinearLayout>
I want to make the RelativeLayout animate out the top (translationY) and then at the same time make the recyclerview animate to be taller to fit.
There are possible options to tackle this:
Follow suggestion from #Ari to start animation and on every animation tick update layout params. This will make an effect of recyclerview changing its size. However, this is a horrible idea from performance stand point. Layout and Measure process is quite expensive, so generally you want to minimize calls which trigger layout. Call to setLayoutParams will trigger layout & measure process for RecyclerView + all its children which means that on every single frame you will do really expensive work which most likely will lead to framedrop and bad user experience
There is another way though. It might not work in all cases - it all depends on your final layout, but still that's what I would recommend doing. The idea - is to make your recyclerView taller before you start animation. It requires some advanced Android skills though. Basically you need to override onMeasure & layout methods in your RecyclerView (you actually need to extend RecyclerView class to do that).
You can introduce some flag to your recyclerView to measure itself a bit taller than normal (how much taller - the exact height of your header view)
when you need to animate header out - set your flag to true and request new layout. This will re-layout recyclerView with some invisible part at the bottom.
Now you can just animate y translations of both RecyclerView & Header so header moves out of the screen and recyclerview goes higher. This will make user feel like recyclerview "expands"
Once animation is done - set your custom flag to false and change visibility of your header to GONE since it is off screen now
Here is some information about implementing custom onMeasure logic:
https://medium.com/android-news/perfmatters-introduction-to-custom-viewgroups-to-improve-performance-part-2-f14fbcd47c
I am trying to draw a View in a ViewGroup without adding it to the child list.
I am doing this because I want to display something like a ProgressBar in the exact center of layouts like a LinearLayout so I don't want the layout to handle the measuring and layouting.
I also don't want to complicate the view hierarchy by adding extra layouts just to achieve this effect so my solution was to extend the LinearLayout, create a ProgressBar and handle measuring, layouting and drawing for that view myself.
My implementation seems to work ok from what I tested but I am wondering if there is anything I am not noticing or if there are any problems that can appear in the future.
From what I understand calling addView also sets the child view's parent and calls dispatchAttachedToWindow, these methods are package-private so I can't call them myself.
Is there any side effect that can arise from calling measure, layout and draw on a view that has no parent and that was not "attached" to a window? Is there a safer way to achieve the same effect?
Thanks.
I have a vertical LinearLayout. It shall act as a quick jump bar. So the width is very small and the height matches nearly the whole screen height. When I touch it and move around inside, everything is fine. That means, my onTouchEvent() is called and I can get (and follow) the position of the finger. But since the bar is not very wide, the user can easily drift outside of that view. So it would be necessary to let the user continue the movement even when outside the view. In fact the same thing like a ListView does.
I don't know why a ListView's onTouchEvent() is called even when outside the ListView, but not in case of my LinearLayout. I tracked it down back to the dispatchTouchEvent(). Here the situation is the same that method is always called for the ListView (even when outside) but not in case of the LinearLayout (when moving outside).
I'd be very happy if someone could give me a hint. Thanks a lot!
Bernd
You could use Android's TouchDelegate feature. It supports a bigger touch area for single views. Here is an example: https://stackoverflow.com/a/1343796/636579
i think that you should try increasing the padding of a view from all sides so that when user will click near the view in area of padding the ontouch or onClick method will be called
android:padding="10dp"
In Android, Which is the light weight view ?
ex:- View, Textview, Edittext, etc....
In some case we need to use a view to fill the area without showing the view to the user.
At the same time the screen should load fast.
You can use Space.
android.widget.Space
Space is a lightweight View subclass that may be used to create gaps between components in general purpose layouts.
If by "lightweight" you meant memory footprint, then there is none exists on Android, because each view have to derive from View, which itself is a massive object (well, not massive, it is about 8kB), so it's not that big.
But in terms of measure, layout and draw time the basic View performs well. You just have to set its visibility to INVISIBLE. And so it will be measured and put into the layout (contrary to GONE with which the view would not take up any space).
Unfortunately ViewStub is not meant to be used for this purpose. Its default visibility is GONE.
If you are really picky, then you can extend View and override methods like draw() (to do nothing, do not even call super), dispatchDraw(), setVillNotDraw(true), etc. (Take ViewStub as a sample).
You should have a look at ViewStub.
Use ViewStub if it is sufficient or LinearLayout which may be somewhat light weight.
Does anyone know what android:isScrollCOntainer = (boolean) or $(View).setScrollContainer(boolean) do?
At first I thought this would be the answer to set a View inside a ScrollView NOT to scroll with ScrollView, but it doesn't seem to be the case.
On Android Developers it says,
"Set this if the view will serve as a scrolling container, meaning that it can be resized to shrink its overall window so that there will be space for an input method. "
Can anyone kindly explain what this description means?
What is a scrolling container in this case?
What kind of input method is available?
A scrolling container is one where the size of the container is independent of it's content.
For instance you can make a ScrollView or ListView of height 100 pixels, but you can fit as much content in as you want. Similarly regardless of the size of the content in the view, you can set the size the of the View to whatever you'd like.
If a container is scrollable, then Android knows it can shrink the size of the container without rendering parts of the content of the container inaccessible (since the user can just scroll down to see things not on screen). It uses this for when the SoftKeyboard is opened - if a container is scrollable it will shrink it as much as possible in an attempt to keep all of the elements on screen.
So ScrollView, ListView, GridView etc are all examples of scrolling containers.
I am looking in to the same thing and I am not sure exactly what it means either. The input method is however the soft keyboard. Changing it affects how the views resize when an edittext is clicked and the keyboard pops up. Look in to android:windowSoftInputMode for more information.
I hope this was at least a little bit helpful!