In my application i have CoordinatorLayout with nested custom view, which has custom MoveUpwardBehavior. When Snackbar appears, I want this view to be pushed over it and it works.
The problem is, that CoordinatorLayout is nested in RelativeLayout which has flag animateLayoutChanges=true. When RelativeLayout animates its views, CoordinatorLayout shrinks a bit (vertically). It causes, that mentioned custom view also moves, but i want to make it stick to its position. Any thoughts, how I can accomplish it?
You need to set CoordinatorLayout to be top-level layout instead of wrapping it inside another parent. The animation and displacement of the views during layout animation is totally normal. You may want to tweak your MoveUpwardBehavior to get the target view to keep the intended behavior, in case that your custom view is not direct descendant of CoordinatorLayout.
Related
What is the difference between ScrollView and NestedScrollView? Both of them, extend FrameLayout. I want to know in depth pros and cons of both of them.
NestedScrollView as the name suggests is used when there is a need for a scrolling view inside another scrolling view. Normally this would be difficult to accomplish since the system would be unable to decide which view to scroll.
This is where NestedScrollView comes in.
In addition to the nested scrolling NestedScrollView added one major functionality, which could even make it interesting outside of nested contexts: It has build in support for OnScrollChangeListener. Adding a OnScrollChangeListener to the original ScrollView below API 23 required subclassing ScrollView or messing around with the ViewTreeObserver of the ScrollView which often means even more work than subclassing. With NestedScrollView it can be done using the build-in setter.
Other than the advantages listed in the answers given, one more advantage of NestedScrollView over ScrollView is its compatibility with CoordinatorLayout. The ScrollView does not cooperate with the CoordinatorLayout. You have to use NestedScrollView to get "scroll off-screen" behaviour for the toolbar.
Toolbar will not collapse with Scrollview as child of CoordinatorLayout
NestedScrollView
NestedScrollView is just like ScrollView, but it supports acting as
both a nested scrolling parent and child on both new and old versions
of Android. Nested scrolling is enabled by default.
https://developer.android.com/reference/android/support/v4/widget/NestedScrollView.html
ScrollView
Layout container for a view hierarchy that can be scrolled by the
user, allowing it to be larger than the physical display. A
ScrollView is a FrameLayout, meaning you should place one child in it
containing the entire contents to scroll; this child may itself be a
layout manager with a complex hierarchy of objects
https://developer.android.com/reference/android/widget/ScrollView.html
NestedScrollView is just like ScrollView, but in NestedScrollView we can put other scrolling views as child of it, e.g. RecyclerView.
But if we put RecyclerView inside NestedScrollView, RecyclerView's smooth scrolling is disturbed. So to bring back smooth scrolling there's trick:
ViewCompat.setNestedScrollingEnabled(recyclerView, false);
put above line after setting adapter for recyclerView.
I think one Benefit of using Nested Scroll view is that the cooridinator layout
only listens for nested scroll events. So if for ex. you want the toolbar to scroll down when you scroll you content of activity, it will only scroll down when you are using nested scroll view in your layout. If you use a normal scroll view in your layout, the toolbar wont scroll when the user scrolls the content.
<androidx.core.widget.NestedScrollView android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
// your Layout xml code
</androidx.core.widget.NestedScrollView>
Given an activity with multiple views, is there a way to have the background dimmed while one view retains its original state (not dimmed)?
I have an existing layout with views and I am adding a dimmed framelayout over the existing layout, and would like to keep one of the child views in the existing views "lightened up" in its state while the dimmed framelayout view encompasses around it.
The way I know how to do this won't be very elegant for your particular use case. But I'll explain it in case you don't find a better solution.
Wrap your entire layout in a RelativeLayout, and then add a LinearLayout with fill_parent parameters on top of it, and a partially transparent black background. Adjust the alpha and RGB to how you see fit.
Now you can add your undimmed view to the RelativeLayout on top of the dimming. Since you're no longer inside the FrameLayout container, you'd have to adjust the positioning of this layout, and manually remove and re-add these two views for dimming and undimming, hence this is not a very elegant solution.
Let me try to explain what I want to achieve. Currently, I have a ScrollView as the main view for my layout and a linearLayout within that to place all of my content into.
In my LinearLayout, I have a bunch of textviews and a gallery, which extends out of the screen, so the user can scroll to see everything. It works.
Now, I want to add an expandableListView to the bottom of all that content, which is still in the linearLayout. The problem is when you expand the list view groups it doesn't affect the ScrollView. I had envisaged that when you expand a group it would make the linearLayout bigger, which in turn makes the scrollview bigger.
Is what I'm thinking achievable?
EDIT:
Ok I think the situation is that listViews are normally placed in a layout by themselves and have scrollviews already enabled. You just set it to fill_parent and it works fine. However, in my case, I'll need the expandableListView to display all content without scrolling, because my ScrollView will deal with that. I don't even think it possible?
It's difficult to answert without seeing your layout xml, but I think that if you set the android:layout_height of the linear layout and expandableListView to wrap_content, the first scrollView must scroll the whole view.
have you tried putting your expandable list into another linear layout and than put it in the scroll views default linear layout?
I understand that View overlapping has been addressed for background images with components on top. However, what if I had the following, where the image from a button overlaps another view, outside of its container?
Example 1
View are not allowed to overlapped in LinearLayouts. It is used to arange child views in either vertical or horizontal manner. When views are bigger than its parent, it renders in the bounds of its parent and the rest is cut of.
You can stack child views on top of each other by using the framelayout. But from seeing your buttun, I think you can achieve it using a Relative layout. And telling the arrow to stay below button using layout_below attribute.
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).