This is an open question about Android ListViews, Gestures and Animations.
I'm really not familiar with the gestures in Android, so I'm just looking for ideas and grey matter on this.
Here's two screenshot and a video examples of the effect on what I'm trying to cogitate. Consider taking a look at the video, it's really worth it.
The screenshots are from an iOS open source project found here.
The question is, how would you implement a "listview opening" gesture like the one I see more and more often in iPhone/iPad apps, but for Android ?
Edit 1, idea 1:
Okay first idea, AFAIK the Pinch gesture is somehow like a dragging gesture, so I guess we can get the X and Y coordinates of the two fingers on the screen?
Next, the answer to this question may help, the basic idea is:
Get the index position of the first visible item in the list
Get the index position of the last visible item in the list
Iterate from the first index to the last with the getChildAt function
For each child, call the getLocationOnScreen method to get coordinates of the current iterated item
After that, some comparison between the pinch gesture coordinates and each item coordinates might be done inside the loop to get the two items between which the new row must me inserted.
Performances considerations appart I think it could work, but maybe there's a simpler way to get those two items(?).
Who's next? :)
Update:
Thanks for the tip #rhlnair, I take this occasion to tell everybody that I started to work on this on my spare time and you are more then welcome to help on this.
The project is at https://github.com/arnaudbos/Android-GestureListView. I started two different implementations on two different branches, and would enjoy anybody to create a new branch.
I have something really encouraging in branch "attemp-via-scale-gesture-detector" but some side effects from the ListView.
Come on folks!
seems to be a challenging idea..
i think some of the effect in clear app like dragging a selected row up/down can be taken from
https://github.com/commonsguy/cwac-touchlist
When doing a pinch gesture you have two fingers on the screen and therefore a point in the middle of those two points. That is simple euclidean arithmetic to find that middle point.
Then find as you say the element in the list that this point is above. You mention performance and I do not think this will be a problem. You are iteration a loop a few times and asking for coordinates. I have done much worse on touch events.
If the point between the pinch is above the middle of the list item you create the item above, and vice versa below.
See the section at the bottom where they use a scale listener:
http://android-developers.blogspot.com/2010/06/making-sense-of-multitouch.html
Using the scale listener you can use the scale to find out if you create a new element. If the scale is above (you are "zooming" out) a threshold you create a new element and let the view repopulate from the list adapter.
Related
I'm currently working on an small Android module and I'm facing a problem which maybe someone can solve. I need to create a calendar and allow the user to select a date range by 1) clicking on a start date (this will create a 2 days range by default) and then 2) touching one range border and dragging it to increase or decrease that range.
Currently I've created all the calendar days cells using a RecyclerView with a GridLayoutManager which has a lot of rows (all the weeks) with 7 items per row (the days). Then I've used the RecyclerView ItemTouchHelper (https://developer.android.com/reference/android/support/v7/widget/helper/ItemTouchHelper.html) and ItemTouchHelper.Callback (https://developer.android.com/reference/android/support/v7/widget/helper/ItemTouchHelper.Callback.html) to complete the drag&drop functionality. My approach was to use the drag&drop detection provided by those helpers (take a look at https://medium.com/#ipaulpro/drag-and-swipe-with-recyclerview-b9456d2b1aaf#.ib8r012gc) modifying it to avoid moving one item and only detecting the touch+drag+drop gesture I wanted. I've correctly completed the functionality by removing the default drag animation (overriding ItemTouchHelper onDraw/onDrawOver) and using the ItemTouchHelper.Callback callbacks to manage the drag movement (without swapping the adapter items, because I need them always at the same position). All works fine but I'm now facing a problem because the drag detection is not working as expected. I'll try to explain it: if I start the drag movement in the center of a given cell, and I move to the cell to its left, the drag movement isn't triggered until I've reached the center (the same position at where I've started the drag movement) of the left cell. This is a problem because I need to detect a drag as soon as I reach another cell (if the finger is inside the new cell bounds, the drag should be triggered). Another example is: if I start the drag movement in the leftmost side of a cell, the drag won't be triggered until I reach the leftmost side of another cell.
Now I'm trying to play a bit with the ItemTouchHelper.Callback.chooseDropTarget method to manually select the drop target as soon as the fingers enters a new cell but I'm not able to get it work. I think (but I cannot ensure it) that is something strange with the received x,y coordinates.
I know that some code example would be very helpful but I cannot paste it because it belongs to a private and protected repository :(
Any help that anyone could provide to me will be really appreciated. And, of course, I'll try to be pending of this topic to provide all the info I can. I will also take into account new different approaches and suggestions to get the "touch+move+up" movement which I need to move ranges borders :)
Many thanks in advance to all the Stack Overflow community!
After some more research, I found the solution to my problem. I'll post it so if someone faces the same issue, he can find some help here :)
My problem was that I was using the curX and curY parameters returned by ItemTouchHelper.Callback.chooseDropTarget (https://developer.android.com/reference/android/support/v7/widget/helper/ItemTouchHelper.Callback.html#chooseDropTarget(android.support.v7.widget.RecyclerView.ViewHolder,%20java.util.List%3Candroid.support.v7.widget.RecyclerView.ViewHolder%3E,%20int,%20int)) as if they were the current finger coordinates while dragging, but they are the coordinates of the top leftmost coordinate of the dragged view after applying any translation. Now I feel a bit stupid. I should have read the documentation better :|
As I didn't need that top leftmost coordinate but the finger position, my solution was to use a touch listener attached to the source view so I could detect the initial touch x,y coordinates (relative to that view) using the touchSrcX = MotionEvent.getX() and touchSrcY = MotionEvent.getY() methods and then I applied a point translation before selecting a target in the chooseDropTarget callback. I mean, something like:
curX += touchSrcX
curY += touchSrcY
If someone needs more details or a better explanation, please, contact me and I'll be pleased to help! :)
I see that the latest version of GMail has a slider. Basically, I can slide an entry to reveal what's behind it. I have been needing to do the same thing. I have tried to use onTouch to track displacement, etc. But my approach is very jiggery and the actual scrolling lags quite a bit. Does anyone know how to accomplish what I seek with horizontal scrollView or such? Or better yet, how GMail is doing theirs?
An important aspect of mine is to have some snap action. So if the user has scrolled to greater than X, I am to continue sliding to the left for her, for example, until the front image reaches the left edge.
Or could I use a navigation drawer to accomplish this? I don't think so as yet, but maybe someone has done it. I have been working on this for about a week now, and all my attempts are not quite there.
There are a couple Dev Bytes that discusses how to implement this from scratch (see "DevBytes: Animating ListView Deletion" and "DevBytes: Animating ListView Deletion: Now on Gingerbread!"). Alternatively, you could look at SwipeListView.
I want to create some kind of a tower defense map using a background image which is fourth as large as the screen of the device (twice horizontal, twice vertical).
my question is, how can I do this best. I'm new to Android, just got some Java basics , and want ti try out some stuff.
I want the user to scroll over the entire map using their finger and want him to zoom in via 2 finger pinch, and of course the objects (towers, sprites) should stay were they are.
I've been searching for hours for now and only found answers like " use Scrollview". I just want a food for thought to get in the right way, maybe with some examples.
You can use ImageView and set appropriate onTouchListener where you will detect pinch-to-zoom gesture using GestureDetector and change view coordinates when user drags the finger.
I have been trying to make a layout for an Android app that functions like a car Speedometer.
Something like this:
I basically want there to be 5 clickable Views across the radius of the dial, and have the dial point to the currently selected item. If possible it would be good to be able to click and drag the dial. I would also want this layout to work nicely with different screen sizes and resolutions, including tablets.
How could something like this be accomplished?
I don't know exactly how much this will help, but it goes over a similar design and shows how to place things at angles around a curve.
For each selectable view, I would also advise that you keep use keep track of the coordinates of each item, so you can use trig to calculate the proper angle for the dial to display (getting the dial to display at an angle is covered in that link).
So, you can set up OnClickListeners for each of your selectable items about the gauge, and in each instance, calculate the proper angle for the dial to spin to, and position it there using the information found in that link.
I'm not sure how much this helped, if at all, but it should at least give you an idea on creating custom Views and whatnot.
Good luck!
I'm fairly new to the Android platform and was wondering if I could get some advice for my current head scratcher:
I'm making an app which in one view will need an image, which can be scrolled on one axis, with a load of selectable points over the top of it. Each point needs to be positionable on the x and y (unlikely to change once the app is running, but I'll need to fine tune the positions whilst I'm developing it).
I'd like to be able to let the user select each point and have a graphic drawn on the point the user has selected or just draw a graphic on one/more points without user intervention.
I though for the selectable points I could extend the checkbox with a custom image for the selected state - does that sounds right, or is there a better way of doing this? Is there any thing I can read up on doing this, I can't seem to find anything on the net about replacing the default images?
I was going to use the absolute layout, but see that it's been depreciated and I can't find anything to replace it.
Can anyone give me some code or advice on where to read up on what I need to do?
Thank you in advance
This really feels like something you should be doing with the Canvas and 2D graphics, rather than trying to twist the widget framework to fit.