I'm using layout_scrollFlags="scroll|enterAlwaysCollapsed" with a toolbar minHeight of 0dip, with the intention of only bringing back the Toolbar when my first visible item in the RecyclerView is visible (as opposed to enterAlways, which brings it back immediately whenever the RecyclerView is scrolled up). However, the toolbar is never showing again after I scroll it off the screen. What am I missing?
Please take a look at the design support library sample app: cheesesquare
The proper way to implement your described behavior is to just use the scroll flag by itself:
layout_scrollFlags="scroll"
Hard to say without seeing your code, as a guess this could be one of two things:
1.
It seems there is a bug with this, the view disappears from the screen when set with a min-height greater than zero.Then returns min height when scroll down begins, and full height when the scroll reaches the top.
I think that your min-height of zero may be interfering with your return. As if the scrollview vanishes with a non zero min height, who knows what is going on to cause that, the zero min height may make it impossible to return with this bug.
Have a look at this video found here http://inthecheesefactory.com/blog/android-design-support-library-codelab/en half way down the page.
I quote from this page:
enterAlwaysCollapsed - This flag defines how View enter back into the
screen. When your view has declared a minHeight and you use this flag,
your View will only enter at its minimum height (i.e., ‘collapsed’),
only re-expanding to its full height when the scrolling view has
reached it’s top. Use it with scroll flag like this:
scroll|enterAlwaysCollapsed
Anyway it seems like it doesn't work as described in minHeight part.
I added emphasis.
2.
You have not formatted your code correctly.
From Android's Developer Blog I quote on "CoordinatorLayout and the app bar":
One note: all views using the scroll flag must be declared before
views that do not use the flag. This ensures that all views exit from
the top, leaving the fixed elements behind.
This link also goes into more detail about how to use enterAlwaysCollapsed and is worth looking at.
Let me know if this solves your problem.
Related
I have a RecyclerView in my app. It is part of a fragment (one of several) in an activity. The problem is, when the keyboard is closed it will max out in height and use its internal scroller. When the keyboard opens, the internal scroller turns off and the RecyclerView shows all its children.
The RecyclerView has the option for elements to be added or removed by the end user. In my full implementation, it shows four elements before starting to scroll (with the keyboard closed). When it is the sole fragment, it will max out its height at the screen height.
I've tried setting setting the NestedScrollEnabled to false and while this does stop scrolling, the items it would normally scroll to are no longer accessible. The RecyclerView still changes height depending on keyboard status so the 'hidden' rows become visible when the keyboard is open.
So in short, my RecyclerView is changing its height depending on keyboard visibility. How do I always make it show all its children?
Simplified fragment code that still shows the issue.
Java: https://gist.github.com/anonymous/bd46e137a0fb52f79399c11ba5be61bf
XML: https://gist.github.com/anonymous/c9bfb3f7577f75befc7aa6d5569311ce
I'm using com.android.support:recyclerview-v7:24.2.1
I've encounter an issue using last RecyclerView version.. and even AOSP project don't use the last RecyclerView version.
So ,maybe this will solve your problem, use 23.x.x version and let me know if that resolved the problem :)
Is there a way I can get a context menu pop up when a user long presses on the blank space of a listview? I know that this can be done by setting wrap_content to the layout_height parameter of the listview. In fact I have been doing that successfully for a while. However, sometimes this wrap_content behaves very strangely and though there is enough space on the screen the listview restricts itself to a % of the screen and items scroll within that space. To avoid that problem I have moved to the path of setting the height as 0dp and weight as 1. However, that has disturbed the functionality I had in terms of long pressing the empty area of a list to add a new item to the list. Any help will be greatly appreciated.
Note: I have looked at multiple similar questions on SO throughout the day today but couldn't find any conclusive and elegant solution.
You can use ListView#addHeaderView() or ListView#addFooterView() to add extra view at the top or bottom of ListView, which you can make it looks like blank space.
Also I suggest you use match_parent to the layout_height attribute of ListView.
I'm experimenting to see if the layout scheme I want to use is possible. I want to have an XML layout that's scrollable. Within that scrollable layout, I want to have a single line going horizontally across the screen (I used just a View with a fixed height and different color). When that horizontal line reaches the top of the screen, and as I scroll down through the layout, I want it to stop and remain at the top of the screen while being able to scroll through everything below it.
I've been messing around in XML trying to get it to work, basically putting a bunch of junk before it and after it.
Any ideas as to how that might work? Would I have to do something fancy with the java code to fix the red line at the top when the scroll position reaches a certain point? Your help would be greatly appreciated.
I am assuming you want something like Gmail app where when you scroll a mail the header sticks on top... To do this, you need 2 views. You have your regular scroller below and overlay a fixed view on top (you can use a relative layout to do this). When your cell goes past a certain spot, you want to populate and set the visibility of the fixed view to VISIBLE. This would give the impression that the view you want to 'stick' to the top really just got stuck rather than scrolled out of view. You'll have to work out the opposite scrolling scenario too based on the location and height of the scrolled cell/view.
HTH
I'm trying to add a header view to my list, and hide it all the time unless we scroll to it (like the pull-to-refresh mechanism). The problem is: if the list is not tall enough to fill the screen - the header view is shown on top of the list.
Is there a way to hide it, and make it visible only when we scroll to it? I've been trying a lot of stuff, but I can't figure out a good and simple way to do so.
Thanks
Here's a blog post describing a simple way of hiding and showing the header view.
The idea is to to put the content you wish to hide in a LinearLayout that wraps it, and hiding the content only. That way, the wrapping LinearLayout will collapse when its content is hidden, resulting in a headerView that is technically still present, but 0dip high.
Note: If you would try to hide the content without the enclosing layout, you would be left with unwanted space in the header view.
An example layout with a spinner representing the content:
<LinearLayout
xmlns:a="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<ProgressBar
android:id="#+id/spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
Then you can hide the spinner (content) as follows:
spinnerLayout.findViewById(R.id.spinner).setVisibility(View.GONE);
You could look into ListView.setOverscrollHeader() or ListView.setOverscrollFooter(). Is this the behavior you are looking for?
If not, could you post some code showing what you have so far?
EDIT:
Ok so I looked into Overscrolling headers/footers and you're right, I don't think that's what you want at all.
Instead you should probably look into the Pull to Refresh mechanism from the Twitter app that others have tried to emulate. You can look into the answers from this question.
The most promising answer seems to be the custom ListView written by Johan Nilson, the code for which can be found here:
https://github.com/johannilsson/android-pulltorefresh
EDIT #2:
I took a look at the PullToRefresh custom ListView and what you want to do is probably possible, though not necessarily easy. Allow me to explain.
The PullToRefreshListView is essentially just a hack that exploits the optional Header in standard ListViews. The hidden "Pull To Refresh" that you see is really just the header of the ListView. When the list is displayed, this line is executed:
setSelection(1);
This scrolls the list to the first item on the list, effectively hiding the Header. When the List is short enough to be displayed entirely on screen, no scrolling is necessary, hence the "Tap to Refresh" button.
When this "Tap to Refresh" is visible, the pull to refresh mechanism is disabled, but it's easy enough to fix that. The pull to refresh effect is accomplished by increasing the top padding of the header view so that it appears that you are pulling the list down (when really it's more accurate to say that the Header is pushing the rest of the list down).
The amount of padding added is controlled by the applyHeaderPadding() function on line 199 of the source code. In that function there is an if statement on line 220 that only applies the padding when the list is in RELEASE_TO_REFRESH mode:
if (mRefreshState == RELEASE_TO_REFRESH)
{
//Some code that eventually adds padding to the header...
}
If you eliminate this condition or change it to apply padding no matter what mode you are in you can drag to refresh even if the list is short and the header says "Tap to Refresh"
if (true)
{
//Some code that eventually adds padding to the header...
}
However, this doesn't exactly create the effect you're looking for. If the list is short, you can drag it down to refresh, but the "Tap to Refresh" header is still shown. Now the problem is "How can I hide the header until the dragging motion begins?" This is a difficult problem on it's own, with several Stack Overflow questions dedicated to it.
If you want a header, you must add it BEFORE you set the adapter for the ListView, otherwise you get all sorts of errors.
I had some success with this, but I haven't come up with anything stable, because my solution is a kind of nasty hack on top of the already hacked PullToRefreshListView. I set an empty FrameLayout as the header and added the original pull to refresh header to that Frame Layout. Then, as I dragged the list, I edited the height in the LayoutParameters of the Frame Layout to grow and shrink much like the padding had originally. It sort of worked, but would eventually force close, and I haven't figured out why yet.
Anyway, if I get it to work I'll post the code, otherwise someone wiser than I might propose a solution based on the info I just provided.
Here is a solution for the current PullToRefreshListView (updated November 4, 2011):
https://github.com/johannilsson/android-pulltorefresh
based on the Hiding Header Views article:
http://pivotallabs.com/users/joe/blog/articles/1759-android-tidbits-6-22-2011-hiding-header-views
1) Copy pull_to_refresh_header.xml from the library's res/layout to your app's res/layout.
2) Edit your app's pull_to_refresh_header.xml. Wrap topmost RelativeLayout in a LinearLayout and then wrap the LinearLayout in a RelativeLayout again. Why? Topmost layout must be RelativeLayout because that's what's expected in code, second level layout must be LinearLayout because that's the only layout that collapses with View.GONE. Third level layout must be the same as original top-level RelativeLayout (except id) to preserve look.
3) Preserve same id on top RelativeLayout (pull_to_refresh_header), give second level LinearLayout an id of your choosing, give third level RelativeLayout another id (pull_to_refresh_header2 for example).
4) Move all padding from the topmost RelativeLayout to the second RelativeLayout.
5) In your code use findViewById and your LinearLayout id to set visibility to View.GONE. The LinearLayout will collapse, and if you moved all padding values appropriately to the inner RelativeLayout the header should take no space at all.
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!