I am doing an activity, in which there will be a View in a center.
Here is how will it work. When I will be dragging my finger randomly across the screen, this view should make action only when my finger is in bounds of this view.
My code(not correct just want to know if my thinking is correct):
firstlayout.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
float x = event.getX();
float y = event.getY();
if ( (firstlayout.getLeft() <= x <= firstlayout.getRight()) &&
(firstlayout.getTop() <= y <= firstlayout.getBottom())
)
{
Log.i("A", "Motion Event is currently above firstlayout");
firstlayout.dispatchTouchEvent(event);
}
return true;
}
return false;
}
});
There is an error: Operator <= cannot be applied to 'boolean','int'
Please write some code example if you could
Any help will be appreciated
This is not valid Java:
firstlayout.getLeft() <= x <= firstlayout.getRight()
Instead, you must do
(firstlayout.getLeft() <= x) && (x <= firstlayout.getRight())
Additionally, your view can only receive touch events when that touch occurs within the bounds of the view. There is no need for you to manually check the bounds.
Related
These are the FAB dimensions following google specs.
In my application case I need a click listener which is fired by clicking in the FAB's circle only, avoiding clicks inside the square container (56x56).
I was already thinking about get X,Y in each onClick event in my "entire" button and then verify if it's inside my Fab's circle, but i would like to escape from this workaround because it could cause accuracy-click problems with different devices resolutions.
Do you have any idea for an alternative solution?
Thanks in advance.
EDIT:
I've actually implemented this javascript-solution translated in Java
LINK
Do you think i will always get the same accuracy on device screen changes?
I don't think there is a way to actually make a clickable area other than rectangular.
You should make your floating button have a width and height set to wrap_content if your circle is an image. Any way you should set it's width and height to match the diameter of the circle. And process the event like this:
view.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
ViewGroup.LayoutParams layoutParams = v.getLayoutParams();
float radius = layoutParams.width / 2f;
float x = event.getX() - radius;
float y = event.getY() - radius;
if (isInCircle(radius, x, y)) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
// perform your action
}
return true;
} else {
return false;
}
}
private boolean isInCircle(float radius, float x, float y) {
if (Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)) < radius) {
//touch was performed inside the circle;
return true;
} else {
//touched ouside the circle
return false;
}
}
}
);
This will work on any device, as long as your button is tightly wrapped around your drawn circle.
If you don't need the touch event falling deeper, under your floating button when you miss the circle, you can avoid some redundant calculations like this:
view.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
ViewGroup.LayoutParams layoutParams = v.getLayoutParams();
float radius = layoutParams.width / 2f;
float x = event.getX() - radius;
float y = event.getY() - radius;
if (isInCircle(radius, x, y)) {
// perform your action
}
}
return true;
}
private boolean isInCircle(float radius, float x, float y) {
if (Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)) < radius) {
//touch was performed inside the circle;
return true;
} else {
//touched ouside the circle
return false;
}
}
}
);
Keep in mind that for this to work your button should be strictly rectangular. if you want a button to be an ellipse the math should be different.
I'm trying to develop an android application similar to "on color measurement" or "color grab" which are already on google play.
I have problem with getting the exact position of a view (which acts like focus square) and move it to the position where the user touches the screen. I have done a lot of searches but all of them ended in onTouchEvent() which I used it but it does not work properly or maybe I have done something wrong.
Actually the view moves but it won't be placed exactly where the user touch, it will go below the touched area in y axis with a distance.
here is my code where the mFocusRectangle is the custom view which I want to move to the touched position:
#Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
if (event.getPointerCount() > 1) {
// handle multi-touch events
} else {
// handle single touch events
if(action==MotionEvent.ACTION_DOWN){
}
if (action == MotionEvent.ACTION_UP) {
int pointerId = event.getPointerId(0);
int pointerIndex = event.findPointerIndex(pointerId);
// Get the pointer's current position
float x = event.getX(pointerIndex);
float y = event.getY(pointerIndex);
mFocusRectangle.showStart();
mFocusRectangle.setX(x);
mFocusRectangle.setY(y);
}
}
return true;
}
I have also tried MotionEvent.ACTION_DOWN but the result is the same.
Thanks in advance.
try this
float x = event.getX(pointerIndex) - (mFocusRectangle.getWidth() / 2);
float y = event.getY(pointerIndex) - (mFocusRectangle.getHeight() / 2);
credits:
Manitoba - Android move view on touch event
I have a list View in my Main Activity, which contains a list of full size images. i am trying to implement onTouchListener on that image view of list view to get the points where user touched. and i am getting it correct by implementing onTouchListener in get View method of Custom Adapter for list view. but when i touch screen for scrolling list it still gives me the points while scrolling the list. but i don't want to get onTouchListener called while scrolling the list. How can i do this.
you may try this, this might work
float posX, posY;
imageView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN){
posX = event.getX();
posY = event.getY();
}
if (event.getAction() == MotionEvent.ACTION_UP){
if (((posX >= event.getX() && posX <= event.getX() + 10) || (posX <= event
.getX() && posX >= event.getX() - 10))
&& ((posY >= event.getY() && posY <= event.getY() + 10) || (posY <= event
.getY() && posY >= event.getY() - 10))){
//Do your thing
}
}
return true;
}
});
I think the proper way to do this is by implementing onClickListener instead of onTouchListener.
And yes, the very reason is because the View will be touched when the user only intent to scroll the ListView.
override this method and done with respect to your requirement.
#Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (isScrooling) {
return super.onInterceptTouchEvent(ev);
} else {
return false;
}
}
I want to have possibility to change position of items(textviews/imageview) on the screen by using touch. So I made OnTouchListener which looks like this:
float x = 0,y = 0 ;
private void clickOnObjectTaker() {
cream.setOnTouchListener(new OnTouchListener(){
#Override
public boolean onTouch(View v, MotionEvent event) {
boolean touched= false;
if(event.getAction()==MotionEvent.ACTION_DOWN)
{
messageMaker("touched");
x= event.getX();
y= event.getY();
}
if(event.getAction()==MotionEvent.ACTION_MOVE )
{
Animation anim =
new TranslateAnimation(x, event.getX(), y, event.getY());
anim.setFillAfter(true);
anim.setFillEnabled(true);
cream.startAnimation(anim);
x= event.getX();
y= event.getY();
}
if(event.getAction()== MotionEvent.ACTION_CANCEL)
{
cream.setX(x);
cream.setY(y);
}
return true;
}});
}
My problem is that when i change the position of object, the listener don't get new position, so I see the object in different place on the screen, but when I want to move it I must click on old position. I thought i solve it by adding this lines:
if(event.getAction()== MotionEvent.ACTION_CANCEL)
{
cream.setX(x);
cream.setY(y);
}
but nothing changed.
UPDATE: I tried with this code. There |I haven't any problems with updating position element of layout, everything works properly except the process of moving object by touch.
What I don't like it in this method:
touched object vibrate when I move it (it doesn't look nice),
object doesn't follow perfectly my finger, like somewhere I should scale the coordinates ( for example I moved object from right to left side of screen, when my finger stops at the brink of screen, the object is lag behind of it.)
this two things makes this method useless for me.
#Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction()== MotionEvent.ACTION_DOWN){
dx = event.getX()-v.getX();
dy = event.getY()-v.getY();
}
if(event.getAction()== MotionEvent.ACTION_MOVE)
{
v.setX(event.getX()-dx);
v.setY(event.getY()-dy);
}
return true;
}
}
The moving of oobject in method with animation looks great for me, everything works fluently. Only problem is connected with update layout, when I add code like this
if(event.getAction()==MotionEvent.ACTION_UP )
{
v.setX(event.getX());
v.setY(event.getY());
}
It put object at random position (I can't figure out, from what place he take this position), If somebody can give me any advice I would be grateful
EDITED
This code almost perfectly I could make repeatedly moves on view. It have two flaws:
small reallocation after Move gesture ends
During moving the view if I stop the finger on the screen, I can see the flashes of view at old position.
the code
OnTouchListener dealingwithproblems = new OnTouchListener()
{
#Override
public boolean onTouch( View v, MotionEvent event) {
if(event.getActionMasked()== MotionEvent.ACTION_DOWN){
//values for
dx = event.getX()-v.getX();
dy = event.getY()-v.getY();
x= event.getX();
y= event.getY();
}
if(event.getActionMasked()== MotionEvent.ACTION_MOVE)
{
Animation anim =
new TranslateAnimation(x, event.getX() , y, event.getY());
//anim.setFillAfter(true);
anim.setFillEnabled(true);
v.startAnimation(anim);
x= event.getX();
y= event.getY();
}
if(event.getActionMasked() == MotionEvent.ACTION_UP)
{
v.setX(event.getX()-dx);
v.setY(event.getY()-dy);
}
return true;
}
};
If somebody knew how to improve it, leave the answer pliz
it maybe animation problem, you are using ViewAnimation try to use change that in Object animator. it supports form API 11.
ObjectAnimator.ofFloat(view,"Translate",x,y,toX,toY);
I had a similar problem (touched object vibrates on move) and resolved it by using getRawX() and getRawY() instead of getX() and getY()
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