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! :)
Related
I wan't to develop game named "Balda".
I have a 2d grid of imageviews (or buttons, maybe).
User should be able move his finger on the grid, and app should know wich images in grid was touched in this move.So, in the picture below is what I'm trying to achieve. A - is start point where user pressed on screen. B is end point where finger leaves the screen. And I need to know what images were touched (There are blue in the picture).
I know that I can do something like this. But I think that this is a wrong solution, because It contradicts the principle of giving functionality by responsibilitys.
I think that it is responsibility of the imageView to know when finger enters its borders and when it is leaving its borders.
I thought, that this would be in android API. And it has MotionEvent like EVENT_HOVER_ENTER and EVENT_HOVER_LEAVE but it's not working with finger. After finger is pressed on some View it will recieve all other MotionEvents, if I get it right.
I think that this is wrong. What can I do to get this functionality? Maybe I could create some custom listeners and custom Views, that supports them?
I think your requirement is slightly similar to custom gridview.
You can try below steps-
1)Create Custom view
2)Attach TouchListener to it.
3)Divide this view into 4*3 matrix.
4)Map your images to this 4*3 matrix
5)Write a function which gives the cell number respective toTouched Co-ordinates
6)After getting cell number;get the mapped image for that cell number
7)Put this image in arraylist
8)When user lifts his finger you will get arraylist of touched images(do whatever you want with it).
9)Remember to put this custom view in your activity
Tell me,if you have any doubt or concern
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 am developing a mobile game for iOS and Android with Starling. I am very new to this framework. I need to add a sprite to the screen and then have the initial point on the screen that was touched be anchor point 1 and then the user will drag there finger which will adjust the second anchor point until they release their finger from the screen. Imagine several nodes that need connected by a line and you can picture what I am trying to do. The problem is that I can change the pivot to be at the beginning of the line but I dont know how to make the other anchor point work. I also cannot use anything other than a sprite as the line is animated by a sprite sheet. Any help that can be provided is greatly helpful, I have been thinking about this for a while now and can't seem to figure it out. Code is helpful and preferred but just giving me an outline of the concept would help as I can probably figure out code. Thanks!
I don't know actionscript but I'm sure if it is for android the touch event has 3 phases (generally): touch down, touch move, touch up.
You say you only have a sprite so define some variables:
initX, initY, finalX and finalY. All floats (or ints if you cast them). And a couple of booleans: set1 and set2 all false
On touch down you ask if set1== false if so, set initX=eventX and initY=eventY (eventX and eventY would be here the X and Y of the touch event). Then set set1=true
On touch move you do the same as above, with set2. if set2==false, set finalX=eventX and finalY=eventY, then set2=true.
and you draw your sprite from (initX,initY) to (finalX,finalY) or if you're using width/height then finalX-initX for the width, finalY-initY for height.
I hope this helped. I didn't even know starling existed but since it's actionscript it must be pretty close to java in its syntax
Is it possible to detect every pixel being touched? More specifically, when the user touches the screen, is it possible to track all the x-y coordinates of the cluster of points touched by the user? How can I tell the difference between when users are drawing with their thumb and when they are drawing with the tip of a finger? I would like to reflect the brush difference depending on how users touch the screen, and would also like to track x-y coordinates of all the pixels being touched over time. Thanks so much in advance for any help.
This would be very tricky primarily because every android phone is going to behave differently. There are some touch screen devices that are very, very sensitive and some that are basically "dull" by comparison.
It also sounds more like you are wanting to track pressure - how hard is the user pushing on the screen - which is actually supported on android devices.
I think some of your answer may be found by monitoring all of the touch events - in practice, most applications ignore a great number of events or perform some kind of "smoothing" of the events since there is literally a deluge of touch events when the user is manipulating the screen. Doing this may negatively impact your applications performance though.
I would recommend that you look into pressure sensitivity and calculate a circular region around the primary touch point based on pressure, then build your brush around that.
Another idea would be to incorporate more of a gesture approach to what you are trying to do - for example, visualize touching the screen with the tip of two fingers together (index and middle) and rolling the middle finger around the index finger or simply moving the middle finger up and down in relation to the index finger. Both fingers would be moved together for painting. This could be used to manipulate drawing angle on the fly or perhaps even toggle between a set of pre-selected brushes or could change brush size on the fly as you are painting.
Some of the above ideas I would love to see implemented - let me know when you have your app ready.
Good luck!
Rodney
If you have a listener on your image it will respond that there was a touch within that bounding box, basically.
So, to get what you want, you could, but, I would never do this, create a box around every pixel, or small group of pixels, and listen for a touch.
Wherever you get a touch, it may fire off an event, then you can react accordingly.
I can't think of any other solution that will give you each pixel that a person touched, at one time.
You may want to read up on multitouch though, as there are some suggestions in here that my help you:
http://android-developers.blogspot.com/2010/06/making-sense-of-multitouch.html
If you're looking for a way to get your content view as a View after Activity#setContentView(int), then you can set an id on the outer-most element of your layout:
android:id="#+id/entire_view" and reference it in your onCreate() method after setContentView:
View view = getViewById(R.id.entire_view);
view.setOnTouchListener( ... );
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.