I am working on an online handwriting recognition tool . I have a custom view which i am adding to linear layout . how can i get the coordinates in custom view and transfer them to main activity file for storing them in linked lists or array lists
You need create a custom class that implements the OnTouchListener interface and set it to listen to touch events on your custom view. Its very similar to adding an OnClickListener to a button:
MyView view = (MyView) findViewById(R.id.myView);
view.setOnTouchListener(new MyOnTouchListener());
Where MyOnTouchListener looks something like this:
class MyOnTouchListener implement OnTouchListener{
public int x=-1,y=-1,prevX=-1, prevY=-1;
public boolean onTouch(View v, MotionEvent event)
{
prevX = x;
prevY = y;
int x = (int)event.getX();
int y = (int)event.getY();
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
// there is no prev touch
prevX = -1;
prevY = -1;
// touch down code
break;
case MotionEvent.ACTION_MOVE:
// touch move code
// add points to array here!
break;
case MotionEvent.ACTION_UP:
// touch up code
break;
}
return true;
}
}
You could override the method OnTouchEvent on your View.
public boolean onTouchEvent(MotionEvent event) {
float x=event.getX();
float y=event.getY();
}
And then if you want, you could construct a Array or a List.
ArrayList<Point> myList;
...
//Constructor
...
...
public boolean onTouchEvent(MotionEvent event) {
float x=event.getX();
float y=event.getY();
Point p =new Point();
p.set(x, y);
//And then add to the list
myList.add(p);
}
public ArrayList<Point> getMyArray(){
return myList;
}
And for call the method getMyArray of your custom view. You could use this code on your main activity
myView mv = (myView)this.findViewById(R.id.myView1);
ArrayList<Point> points = mv.getMyArray();
That's a possible solution for your problem but I don't know if it helps you.
Edit: This solution works for all customs View but, if I were you, I would use a View that extends SurfaceView. It's logical because , I think, it's the best way to create graphics in a handwriting tool.
Related
I have drawn piechart using canvas method of view , but now i want get click of individual pie ? how can i dot that?
I got perfect answer for this question:
get color code of click area and check if color match with your color code this will get click you want.
#Override
public boolean onTouchEvent(MotionEvent event) {
float touchX = event.getX();
float touchY = event.getY();
Logger.debug("X-->"+touchX+" Y---->"+touchY);
//get drawing cache of your view
Bitmap bitmap = getDrawingCache(true);
//Get color code of pixle where you have tap
int colorCode=bitmap.getPixel((int)touchX,(int)touchY);
if(colorCode == context.getResources().getColor(R.color.pie_blue)) {
Logger.debug("Color blue");
onPieClick.onBluePieClick(touchX,touchY);
}else if(colorCode == context.getResources().getColor(R.color.pie_green)) {
Logger.debug("Color green");
onPieClick.onGreenPieClick(touchX,touchY);
}
return super.onTouchEvent(event);
}
What you can do is,
Override onTouch event & You will get Motion event,
You will get x & y co-ordinates of the click by event.getX() &
event.getY() respectively.
identify where this x & y intersect in pie.
Sample code:
1)Simple
public boolean onTouchEvent(MotionEvent event) {
if(event.getAction()==MotionEvent.ACTION_UP){
float xCord=event.getX();
float yCord = event.getY();
....
Write condition to identify where this x & y intersect in pie.
...
}
return true;
}
2) Another way getting touch (good way)
OnGestureListener mGestureListener=new GestureDetector.SimpleOnGestureListener(){
public boolean onSingleTapConfirmed(MotionEvent e) {
float xCord=e.getX();
float yCord = e.getY();
....
identify where this x & y intersect in pie.
...
};
};
GestureDetector gestureDetector=new GestureDetector(context, mGestureListener);
public boolean onTouchEvent(MotionEvent event) {
gestureDetector.onTouchEvent(event);
return true;
}
You can't. Well, at least not directly.
You could do the following though:
In the click handler for the view, determine the xy coordinates of the click
Compare the drawing code you wrote, thereby determining in which piece of the pie the click was
I'm new to android, and I've been trying for a while to find out how can I retrieve the coordinates of a continuous touch on the screen. for example have 2 vars (x,y) that update in real time as finger moves around. I got it how to find it when the touch is made, but I really don;t get it how to make it return the result after that , when the finger is moving.
I've been trying switch statements, while/for loops in different combination with ACTION_MOVE./ UP/ DOWN .. .still nothing.
I've found like the same question on the website, but the answers only fit for the first step(showing the coordination from the touch only)
I'd really appreciate a solution to this! Thanks!
Without seeing your code I'm just guessing, but essentially if you don't return true to the first call to onTouchEvent, you won't see any of the subsequent events in the gesture (MOVE, UP, etc).
Maybe that is your problem? Otherwise please put code sample up.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final TextView xCoord = (TextView) findViewById(R.id.textView1);
final TextView yCoord = (TextView) findViewById(R.id.textView2);
final View touchView = findViewById(R.id.textView3);
touchView.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
final int action = event.getAction();
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN: {
xCoord.setText(String.valueOf((int) event.getX()));
yCoord.setText(String.valueOf((int) event.getY()));
break;
}
case MotionEvent.ACTION_MOVE:{
xCoord.setText(String.valueOf((int) event.getX()));
yCoord.setText(String.valueOf((int) event.getY()));
break;
}
}
return true;
}
});
}
You need to implement an OnTouchListener for whatever view you want to recognize the drag.
Then in the OnTouchListener you need to display the X and Y coordinates. I believe you can get those via MotionEvent.getRawX() and MotionEvent.getRawY()
You can use the MotionEvent.getAction() method to find out when a drag is occurring. I believe the constant is MotionEvent.ACTION_MOVE. Here is some psuedo-code:
Add OnTouchListener interface
public class XYZ extends Activity implements OnTouchListener
Register the listener in the onCreate method
public void onCreate(Bundle savedInstanceState)
{
//other code
View onTouchView = findViewById(R.id.whatever_id);
onTouchView.setOnTouchListener(this);
}
Implement the onTouch method
public boolean onTouch(View view, MotionEvent event)
{
if(event.getAction() == MotionEvent.ACTION_MOVE)
{
float x = event.getRawX();
float y = event.getRawY();
// Code to display x and y go here
// you can print the x and y coordinate in a textView for exemple
}
}
I am using view pager to swipe between the views in Android.
Now I need to capture tap event for each of the views. when I override the touch listener to capture the tap event, the swipe action doesn't happen and the screen remains in the first page itself. How do I add touch listener to view pager?
Code:
viewPager.setOnTouchListener(new OnTouchListener(){
#Override
public boolean onTouch(View v, MotionEvent event)
{
mDetector.onTouchEvent(event);
return true;
}});
For the above code I am able to capture tap event, but the swipe action becomes Impossible.
Here i leave you a snippet from my code to detect a "click" on the OnTouchListener, i hope it helps
mImagePager.setOnTouchListener(new OnTouchListener() {
private float pointX;
private float pointY;
private int tolerance = 50;
#Override
public boolean onTouch(View v, MotionEvent event) {
switch(event.getAction()){
case MotionEvent.ACTION_MOVE:
return false; //This is important, if you return TRUE the action of swipe will not take place.
case MotionEvent.ACTION_DOWN:
pointX = event.getX();
pointY = event.getY();
break;
case MotionEvent.ACTION_UP:
boolean sameX = pointX + tolerance > event.getX() && pointX - tolerance < event.getX();
boolean sameY = pointY + tolerance > event.getY() && pointY - tolerance < event.getY();
if(sameX && sameY){
//The user "clicked" certain point in the screen or just returned to the same position an raised the finger
}
}
return false;
}
});
We can use Gestures (Link1, Link2):
public boolean onTouchEvent (MotionEvent ev)
Hope this helps!
Nancy, you don't need to manually override the Page swipes or the touch events. Just add the pages to the ViewPager and the ViewPager will automatically take care of swiping.
You do, however, have to attach touch listeners to the object in each page. So if Page 1 has a Linear Layout with many buttons and you need to find out when those buttons are clicked, you need to attach OnClickListeners for each of those buttons.
Do let me know your use case so we can better understand, why you need to find out when a page has been clicked!
Just to add to Jorge's great answer, you may just use distance instead of sameX and sameY, which is a bit more elegant. Sample:
// Ignore events that are swipes rather then touches
float distX = event.getX() - pointX;
float distY = event.getY() - pointX;
double dist = Math.sqrt(distX * distX + distY * distY);
if (dist > tolerance) {
return false;
}
Put the click event on the item view of the viewpager inside the viewPagerAdapter in the method instantiateItem like -
#Override
public Object instantiateItem(ViewGroup container, final int position) {
// Declare Variables
ImageView jive_image;
inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View itemView = inflater.inflate(R.layout.list_item_viewpager, container,
false);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
onBackPressed();
}
});
// Add viewpager_item.xml to ViewPager
((ViewPager) container).addView(itemView);
return itemView;
}
Is there a way in android to get the area (a collection of points) of my finger when i touch the screen. Usually, the return is one point location. I need to get the several points which can represent the area of my touching. Any one knows? Thnaks
Just use View class's onTouchEvent() or implements OnTouchListener in your activity and get the X and Y co-ordinates like,
This is View class's OnTouchEvent()..
#Override
public boolean onTouchEvent(MotionEvent ev) {
final int action = ev.getAction();
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN: {
float x = ev.getX();
float y = ev.getY();
break;
}
case MotionEvent.ACTION_MOVE: {
float mLastTouchX = x;
float mLastTouchY = y;
break;
}
case MotionEvent.ACTION_UP: {
break;
}
case MotionEvent.ACTION_CANCEL: {
break;
}
case MotionEvent.ACTION_POINTER_UP: {
break;
}
}
return true;
}
EDIT:
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final TextView textView = (TextView)findViewById(R.id.textView);
// this is the view on which you will listen for touch events
final View touchView = findViewById(R.id.touchView);
touchView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
textView.setText("Touch coordinates : " +
String.valueOf(event.getX()) + "x" + String.valueOf(event.getY()));
return true;
}
});
}
For more details Android - View.
Does it have to be the real shape of the finger? Otherwise you could calculate a circle around the center of the touch.
I believe this is not possible in the touch's coordinate along with it's area. It's natively unsupported by Android API.
Ref:
http://developer.android.com/guide/topics/ui/ui-events.html
http://developer.android.com/reference/android/gesture/package-summary.html
Unfortunately not. I ran in to this a while ago - you could try normalising the data over several 'frames'. May be worth trying to figure out why you need an exact point, or set of points, and find another way of doing it.
While similar questions have been asked in the past they don't seem to really have been answered which might be due to confusion as to what's being asked.
Put simply, I'd like to detect which view is being entered as your finger slides over the screen. The best example of this in action is the soft keyboard on any android phone. When you press any key it shows up as a popup to tell you what letter is under your finger. If you now move your finger over the keyboard in a single gesture the various letters pop up as you move over the various letters of the alphabet.
What listeners are used for this type of behaviour. I've tried OnTouchListeners but they seem to be only when you 'touch' the button as opposed to 'finger past' them
Button button = (Button)findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {doStuff();}
});
button.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
doStuff();
return false;
}
});
OnFocusChangeListener don't help either.
create a Layout
add Views to your Layout
set the setOnTouchListener to your Layout
override the onTouch method with the following:
public boolean onTouch(View v, MotionEvent event)
{
LinearLayout layout = (LinearLayout)v;
for(int i =0; i< layout.getChildCount(); i++)
{
View view = layout.getChildAt(i);
Rect outRect = new Rect(view.getLeft(), view.getTop(), view.getRight(), view.getBottom());
if(outRect.contains((int)event.getX(), (int)event.getY()))
{
// over a View
}
}
}
EDIT:
I saw keyboard. I guess, it just one view and coordinates of every letter is known. So you can easily compute which letter the user slides through
AND NOW THE ANSWER:
I'm not sure, but probably this code helps your.
It's so far away, I wrote it for me. But the idea is following.
If I remember right, there is no gesturedetector for views, but you can combine touchlistener of the view with geturelistener of your activity.
Once you've touched your view, you have
private GestureDetector mGestureDetector;
// x and y coordinates within our view
private static float sideIndexX;
private static float sideIndexY;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
...
mGestureDetector = new GestureDetector(this, new SideIndexGestureListener());
}
class MyGestureListener extends
GestureDetector.SimpleOnGestureListener
{
#Override
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY)
{
// we know already coordinates of first touch
// we know as well a scroll distance
sideIndexX = sideIndexX - distanceX;
sideIndexY = sideIndexY - distanceY;
// when the user scrolls within our side index
// we can show for every position in it a proper
// item in the country list
if (sideIndexX >= 0 && sideIndexY >= 0)
{
doStuff();
}
return super.onScroll(e1, e2, distanceX, distanceY);
}
}
button.setOnTouchListener(new OnTouchListener()
{
#Override
public boolean onTouch(View v, MotionEvent event)
{
// now you know coordinates of touch
// store them
sideIndexX = event.getX();
sideIndexY = event.getY();
doStuff();
return false;
}
});
You may want to try GestureDetector.
http://android-developers.blogspot.com/2010/06/making-sense-of-multitouch.html
it's geared to multitouch, but this is a good start toward understanding android touch/gestures, next stop, api docs/samples
The simple answer is you can't - not like the iPhone when in accessibility mode.
Until Ice Cream Sandwich that is. It now has the iPhone-like capability of being able to identify elements under your finger without having to lift it.
It's fairly straight forward to handle this manually.
Using your parent layout as the onTouchListener (in the following example, I extend a RelativeLayout), you can check for collisions between a MotionEvent and the child Views using simple co-ordinate comparison logic:
/** Returns the View colliding with the TouchEvent. */
private final View getCollisionWith(final MotionEvent pMotionEvent) {
// Declare the LocationBuffer.
final int[] lLocationBuffer = new int[2];
// Iterate the children.
for(int i = 0; i < this.getChildCount(); i++) { /** TODO: Order. */
// Fetch the child View.
final View lView = this.getChildAt(i);
// Fetch the View's location.
lView.getLocationOnScreen(lLocationBuffer);
// Is the View colliding?
if(pMotionEvent.getRawX() > lLocationBuffer[0] && pMotionEvent.getRawX() < lLocationBuffer[0] + lView.getWidth() && pMotionEvent.getRawY() > lLocationBuffer[1] && pMotionEvent.getRawY() < lLocationBuffer[1] + lView.getHeight()) {
// Return the colliding View.
return lView;
}
}
// We couldn't find a colliding View.
return null;
}
Calls to getCollisionWith will return View references that may be manipulated arbitrarily.