What I want to achieve: I want to have a view inside a scrollable layout (Recyclerview with GridlayoutManager) with tiles (Views) in it. Dragging and dropping an item inside of the RecyclerView should adjust the position of the icon and swap with the other elements. When a drag starts, an icon above the RecyclerView will change to a trash icon and dragging the view to this icon will delete it from this RecyclerView.
I tried this excellent tutorial, but I didn't find a way how to handle dragging outside of the Recyclerview as the ItemTouchHelper.Callback uses only Recycler.ViewHolder elements as possible targets.
The method interpolateOutOfBoundsScroll() gives feedback if the view moves out of the boundaries, but will only give back the total size that is offscreen, but no coordinates. Also, trying to drag the view out of the Recyclerview always results in cutting of the View where it passes the borders of the Recyclerview.
Does anyone have an idea how I could achieve this effect?
You can achieve this simply by set this attribute for the parent of the RecyclerView:
android:clipChildren="false"
Edit: thank Adam Katz, I don't know why but sometimes you have to add this to the RecyclerView to make it work:
android:clipToPadding="false"
You are bound by the RecyclerView boundries. You have several options:
Make the RecyclerView's layout height to match_parent and to be on top of your upper view (is it a Toolbar?) and add a sticky header of the same size and have an empty transparent layout. That way you could drag ther and see the item floating over there.
Instead of dragging an item to a garbage can icon which is located too close to a legitemate upper-right item, make a long click to select the item (and apply a signal like a check mark or a red mask) and make the garbage can appear and delete uppon click (and maybe allow multi item deleting)
Related
I am building an android app with two recyclerviews, one with horizontal LinearLayoutManager and the other one with GridLayoutManager.
I want to allow the items recyclerviews to be dragged and dropped over a trash icon outside of the recyclerviews, obviously to delete the dragged item.
What I have done is:
Apply android:clipChildren in the parent of the two recyclerviews
Apply android:clipToPadding in the recyclerviews
This works perfectly in recyclerview with LinearLayoutManager. I can drag an item and drop it over an icon that is outside of the recylcerview.
I also works in the recyclerview with GridLayoutManager, but with a side effect. When I scroll in the grid recyclerview the scrolled items come out of the recyclerview.
At the ende of this GIF you can see the scrolling issue
So, Is there any way to allow dragging a recyclerview item outside of the recyclerview boundaries but preventing items comeout when scrolling?
Lots of thanks for your help and suggestions in advance
I tried putting the recyclerview with LinearLayoutManager on top of the recyclerview with GridLayoutManager, to hide the items which came out of the boundaries, but this make a strange behaivour when I drag an item, because the items are there yet, even they are hidden. I could make a GIF if needed
My last option is putting the trash icon inside of the recyclerview, as a header that appears when dragging an item, but I would prefer not do it that way
Finally what I have learnt is that you have two main options when face a drag and drop problem:
Easy way: Using the Android helper ItemTouchHelper
Hard way: Not using the helper and type all the code, using startDragAndDrop()
A scenario like this only can be solved by the hard way.
I have a RecyclerView with CardView as item in it. CardView has the Arrow icon to show details in the same CardView, but I don't want to set is GONE or VISIBLE because this action has no good looking animation. I tried to set android:animateLayoutChanges="true" on my CardView and I got this: (this is not my screen but it contains the same problem)
But once I click on the arrow again to collapse the supporting text, the card below overlaps the card I've clicked during the animation. How can I avoid this overlapping? I tried to call TransitionManager.beginDelayedTransition(CardView); but looks like it doesn't help me..
You can try removing android:animateLayoutChanges="true" and calling TransitionManager.beginDelayedTransition(MainRootView); (note that call parameter is RootView and not CardView).
If it wouldn't do you should do collapsing-expanging by your own. Here is a good example of view height animating.
I'm implementing the UI like the picture below. I'm using gridview to this layout. When user tap the item in gird. It show a circle overlap to the other item. I don't how to do it. at first I define a layout with the circle is gone and add onclicklistener. If user tap on that, I visible the circle, but the size of gridview also extend. Can you help me provide solution?
You can add this views in gridview parent layout preferable relative layout. You must add them after your grid view initsialisaton is done and onitemclick listener on grid item to make them visible. Exactly the one you've tryed but not in grid view but in the activity rootlayour.
My layout is a bit complex.
I have a SwipeRefreshLayout in which I host a ListView. Whenever the user drags the Listview's top, the SwipeRefreshLayout performs a refresh. I also listen for the last visible item of the ListView to load next page of records (Endless scroll)
In the list's adaptor I have 2 views that I am using. The first one will only be visible in first row, the other view will remain the same for all other rows.
What I want to achieve:
On top of the row with position = 1 I want to have a sticky header. This means that when I scroll Up, the header will scroll to the top of the screen and will remain in there.
This sticky header will only be at one row
if possible I'd like to use a simple implementation as my layouts and adapters are already complex enough.
Waiting for your suggestions.
I didnt quite get your question the first time, heres the answer attempt round 2.
In your layout add an empty viewgroup (whichever you prefer, though linearlayout seems to work just great), add a scrollListener to your listView and check the position of your sticky view. If its top anchor is below (meaning its visible in the listview) the top of the screen you set the viewgroup visibility to gone, if the top anchor is either touching the top of the screen or below it, you add that view or one just like it to the viewgroup and set its visibility to visible.
You can adjust the position 2 view visibility accordingly to allow for this change to appear seamless. Can help you a bit more once you have some code and are on your way with this change.
I want an expandable list in which I can drag a child item and drop it over some other parent list item which will result in child moving from one parent to other. I only need a direction how we can achieve this in general listview (let alone exapandable). Examples are available for picking up a listitem to change the order of listview i.e. to sort that list. How can I accomplish dropping over a view in order to group them.
Your best bet will be putting your effort on customizing and making your own listview, Consider extending AdapterView, this will give you more power over controlling child display and organizations, Putting animation such and drag and drop will be easier for you in this case, Otherwise with simple list view it might work but i doubt if it would generate the required result you want.
Here is a link for exending AdapterView and customizations, go through it it will give you enough confidance to put in your animation. I tried almost similar stuff and was succesfull by same way, unfortunately I dont have implemented code with me.
http://developer.sonymobile.com/2010/05/20/android-tutorial-making-your-own-3d-list-part-1/
Else with list view try doing following,
Your listview should be wrapped inside a framelayout, you will need layers
Enable drawing cache for childrens, coz animation you seek requires playing with bitmaps
Second, when you touch a child in listview, get the bitmap of child, and inflate it at same coordinates of touched child, you can get position of Child easily.
Now time for some animation, you enable drag and drop over inflated bitmap, now when you move it, first thing you need to do is, shifting all the childrens in list view either Up or Down depending upon movement of finger, you can define somekind of threshold like unless half the height of children is moved you wont shift childs in listview up or down.
Moving child will be easy, all you need to do is applying Transformation animation to all the currently visible child in listview, use childCount and ChildAt api for the same, and animation set for playing them together.
Thats it when you build space by shifting child, user will feel like drag drop and shift, all the thing you need, when user places it a place, just modify your dataset underneath listview reposition it based on recent changes by user and refresh it,so that listview reorders itself.