Can anyone tell me please how can I make the whole blank screen clickable on the android ? Means wherever I can click on it and then the place where i click there one particular image has to appear where i can then make the notes. I am trying to first find the coordinates of that area and then putting the image. But i am not able to find the code for doing that. Means after finding the coordinates what can be done?
Or if there is some other way then also please help with that!!
For finding coordinates:
public class MainActivity extends Activity implements OnTouchListener{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final TextView xCoord = (TextView) findViewById(R.id.button1);
final TextView yCoord = (TextView) findViewById(R.id.button2);
final View touchView = findViewById(R.id.button3);
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;
}
});
}
Create an ImageView (or have one in your Layout)
Make sure it's invisible on initialisation
When the user clicks use the coordinates to set the location of the ImageView
Make the ImageView visible
Take a sigh of relief.
I need to create an Activity that while drag your finger across the screen, display the XY coordinates (where the finger goes). Could anyone help me?
OnTouch
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
}
}
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.
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.
My class extends View and I need to get continuous touch events on it.
If I use:
public boolean onTouchEvent(MotionEvent me) {
if(me.getAction()==MotionEvent.ACTION_DOWN) {
myAction();
}
return true;
}
... the touch event is captured once.
What if I need to get continuous touches without moving the finger?
Please, tell me I don't need to use threads or timers. My app is already too much heavy.
Thanks.
Use if(me.getAction() == MotionEvent.ACTION_MOVE). It's impossible to keep a finger 100% completely still on the screen so Action_Move will get called every time the finger moves, even if it's only a pixel or two.
You could also listen for me.getAction() == MotionEvent.ACTION_UP - until that happens, the user must still have their finger on the screen.
You need to set this properties for the element
android:focusable="true"
android:clickable="true"
if not, just produce the down action.
Her is the simple code snippet which shows that how you can handle the continues touch event. When you touch the device and hold the touch and move your finder, the Touch Move action performed.
#Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
if(isTsunami){
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// Write your code to perform an action on down
break;
case MotionEvent.ACTION_MOVE:
// Write your code to perform an action on contineus touch move
break;
case MotionEvent.ACTION_UP:
// Write your code to perform an action on touch up
break;
}
}
return true;
}
Try this. It works to me:
public static OnTouchListener loadContainerOnTouchListener() {
OnTouchListener listener = new OnTouchListener(){
#Override
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()))
{
Log.d(this.getClass().getName(), String.format("Over view.id[%d]", view.getId()));
}
}
}
Remember: the listener you´ll set must be a container layout (Grid, Relative, Linear).
LinearLayout layout = findViewById(R.id.yourlayoutid);
layout.setOnTouchListener(HelperClass.loadContainerOnTouchListener());
This might help,
requestDisallowInterceptTouchEvent(true);
on the parent view, like this -
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
view.getParent().requestDisallowInterceptTouchEvent(true);
switch(motionEvent.getAction()){
}
return false;
}
I was making a game with a custom view used as a thumb control. . . here is what I did
float x = 0, y = 0;
#Override
public boolean onTouchEvent(MotionEvent event) {
x = event.getX();
y = event.getY();
// handle touch events with
switch( event.getActionMasked() ) {
case MotionEvent.ACTION_DOWN :
if(cont)
{
// remove any previous callbacks
removeCallbacks(contin);
// post new runnable
postDelayed(contin, 10);
}
invalidate();
return true;
case MotionEvent.ACTION_MOVE :
if(!cont && thumbing != null)
{
// do non-continuous operations here
}
invalidate();
return true;
case MotionEvent.ACTION_UP :
// set runnable condition to false
x = 0;
// remove the callbacks to the thread
removeCallbacks(contin);
invalidate();
return true;
default :
return super.onTouchEvent(event);
}
}
public boolean cont = false;
// sets input to continuous
public void set_continuous(boolean b) { cont = b; }
public Runnable contin = new Runnable()
{
#Override
public void run() {
if(x != 0)
{
// do continuous operations here
postDelayed(this, 10);
}
}
};
A quick note however, make sure in your main activity that is calling this view removes the callbacks manually via the onPause method as follows
#Override
protected void onPause() {
if(left.cont) left.removeCallbacks(left.contin);
if(right.cont) right.removeCallbacks(left.contin);
super.onPause();
}
That way if you pause and come back touch events aren't being handled twice and the view is free from it's thread's overhead.
** tested on Samsung Galaxy S3 with hardware acceleration on **
All these answer are partially correct but they do not resolve in the right way the problem.
First of all, for everyone out there that decide to track when the event is ACTION_MOVE. Well that works only guess when? When user move his finger, so could if you decide to implement a custom thumb control is okay but for a normal custom button that's not the case.
Second, using a flag inside ACTION_DOWN and check it in ACTION_UP seems the logic way to do it, but as Clusterfux find out if you implement a while(!up_flag) logic you get stuck into troubles ;)
So the proper way to do it is mentioned here:
Continuous "Action_DOWN" in Android
Just keep in mind that if the logic you're going to write during the continuous press has to modify the UI in some way, you have to do it from the main thread in all the other cases it's better use another thread.
You can use the below code snippet as a reference in which I used the background to detect if the screen is held or not...
Main_Layout.setOnTouchListener(new View.OnTouchListener() {
#SuppressLint("ResourceAsColor")
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_MOVE:
Main_Layout.setBackgroundColor(R.color.green);
event.setAction(MotionEvent.ACTION_DOWN);
break;
default:
Main_Layout.setBackgroundColor(R.color.blue);
break;
}
return false;
}
});