Currently, I have a bottomSheetBehavior layout that is reused in several activities, but requirements have changed and logic inside it has increased. My question is, is there a way to keep the functionality of bottom sheet collapsed, but when expanded, transition to an activity?
Specifically, when the bottom sheet is collapsed, allow clicks and scroll on the rest of the view, but when expanded, start a new activity so logic can be handled there.
Any advice is welcome.
What I ended up doing was to set the Bottom Sheet Behaviour inside a View Model, and then, the view model posts whatever data to the view using Live Data, at least that ensures logic is contained in one place.
Related
It's 2022, and I'm having the same issue with ViewPager2 that folks had with ViewPager (see NestedScrolling inside a Viewpager inside a BottomSheetDialog ) - 5 years ago.
Although I'm not using a BottomSheetDialogFragment, just a regular old bottom sheet (with a FragmentContainer).
ViewPager2 is a bit different in that it itself uses a horizontal RecyclerView. BottomSheetView.findScollingChild() sees this as the scrolling child!
So, the approach I took to solving this is:
added a page change listener to my ViewPager2 that gets the hosting
CoordinatorLayout, and calls requestLayout() on it after the page change.
copied the BottomSheetBehavior class that matches my current material components version (1.5) into my project, renamed it, and made findScrollingChild public.
subclassed that copy, and set the sub-class as the behavior on my sheet.
Why sub-class and not just change the findScrollingChild method directly? Well, this way it's relatively easy to update the copy of BottomSheetBehavior when we update our material components.
My implementation of findScrollingChild() in the sub-class checks specifically for a ViewPager2.
If it is, it gets child 0 of the ViewPager2 (the horizontal RecyclerView), and then uses recycler?.layoutManager?.findViewByPosition(pager.currentItem) as the view to then search for the scrolling child.
If the view is not a ViewPager2, it uses the same algorithm from the original findScrollingChild()
This basically works. I have a pager with 2 tabs, one containing a ScollView that has nested scrolling enabled, and one containing a RecyclerView. The bottom sheet expands as its scrolled, and then the contents of the nested child scroll down properly once the sheet is open.
The problem is if after the sheet has expanded if the finger gets lifted, then any attempt to scroll up causes the bottom sheet to close rather then scrolling up -- no matter how far it's been scrolled down. At least this is the case for the RecyclerView in the second tab, I don't have enough content in the first tab at the moment that it actually needs to scroll.
The sheet gets closed with the list still scrolled down several pages (or wherever you stopped scrolling). If however you scroll down -- even just a little bit -- scrolling up works again! And you can swipe a couple times and it will work - until it doesn't, and the sheet moves to the half expanded state.
I'm not sure where this behavior is coming from or how to resolve it. It doesn't happen when the bottom sheet has a direct RecyclerView (no ViewPager2 I'm the way).
I tried disabling swiping in the ViewPager2 thinking it might be interfering with touch events, but to no avail.
I'm trying to use the BottomSheetBehavior from Material. The problem is that it is not well described and no enough examples of it are available.
One example on Meduim, but it only shows the basics and very simple implementation.
What I exactly need is something like the one from Material here. But instead of clicking on the menu item to show the BottomSheet, I want to show it when user selects an item from RecyclerView. Also the peek height should show only the first element in the BottomSheet layout until the user pulls it up.
How to get this approach? Are there any useful example?
Make the bottom sheet hidden when you start your activity or fragment by calling bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN).
And in your adapter's onClick, make the bottom sheet visible, by calling bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HALF_EXPANDED)
This is a question regarding the use of Android Transition API.
I am trying to animate the height change of a list, just like a dropdown menu.
I tried 2 approaches
Use a RecyclerView and animates its height change
Use a ScrollView > LinearLayout hierarchy and animates ScrollView's height.
The 2nd approach works perfectly.
But the 1st approach has a serious glitch - when the collapse transition starts, items disappear immediately.
By looking at the below GIF you can observe clearly the difference:
To be exact, items' visibility changes at the moment I change RecyclerView's LayoutParams, without waiting for the transition to finish, whatever it is expanding or collapsing
Code
I have created a minimal project on Github.
If you just want to look at the code, here is the MainActivity.
Question
Is it possible to achieve ScrollView's effect with a RecyclerView?
If yes, how?
My Idea is to do the transition of all the recycler view rows individual rather than the whole RecyclerView:
So when collapsing iterate through each ROW of a RecyclerView and do a transition. Remember to check for null if some rows are recycled they may return null. So after that collapse the whole recyclerView.
And like wise for the expanding do the same for the views.
This issue is cause by RecyclerView has many views with it but Scroll View has only one View nested in it.
I have a vertically scrollable list using a RecyclerView. The layout I'm trying to implement is that when you scroll down far enough and reach a specific item, if you keep scrolling past this item it will stick to the bottom of the screen while the rest of the list continues to scroll behind it. Currently it's implemented by having a scroll listener on the RecyclerView and manually adjusting the position of the sticky view as required, but this is hacky and hard to build on.
Is there an easier way to have this kind of layout? I am currently investigating using a CoordinatorLayout but I'm not sure if it's the right tool for the job.
You can accomplish this using a CoordinatorLayout with a custom behaviour. The behaviour should be applied to the sticky view and make it appear/disappear as the RecyclerView scrolls. You have to override onStartNestedScroll in your behaviour to return true to receive calls for scroll changes.
I am looking for some ideas on how to best achieve this effect. I have two fragments, one containing the map (and all controls) and another fragment that contains my RecyclerView to display the results. In my activity layout I would like to position my map and list fragments exactly how it is shown in this video. The map fragment shall stay aligned with the topmost edge of the list unless the user is actively scrolling the list upwards. The video I recorded should demonstrate what it is I am trying to achieve.
From an explanatory standpoint, I need view and layout ideas. I have already implemented all the necessary callbacks for all user interactions between the two fragments and the activity. One item in particular I am most interested hearing feedback on is how to align two views and then have the lower slide over the view when the user starts scrolling. Notice how the list (when showing) will not scroll downward.
One method I can suggest is to have both the map and the ListView in the same fragment and try this. It's the sliding drawer animation in Play Music.
For the part where touching the map shrinks the list view to a bar on the bottom. I suggest you create animations in the listView to shrink and to expand and call them on event Down and Up respectively. Here is the MotionEvent.