Bypass touch listener events to layout - android

I have a LinearLayout that contains some other views. I have implemented onTouchListener over it and I want to move it with user gesture. but it has some other views inside it, that have there on click listeners. I have an ImageView and 2 buttons in this layout and these views have there own click listeners. just have a look at layout.
I can only move my layout when user click on Free space and then start dragging. whereas I want to move layout even though user start dragging from over
Imageview,btn1 or Btn2.
I know because BTN1,2 and ImageView are set to be clickable that is why they are consuming onTouchListener of LinearLayout. Here is some code of touchListener
#Override
public boolean onTouch(View mView, MotionEvent event) {
View view = null;
if(!(mView instanceof LinearLayout) && !(mView instanceof RelativeLayout)){
view = (View)(mView.getParent().getParent().getParent());
}else{
view = mView;
}
final int X = (int) event.getRawX();
//final int Y = (int) event.getRawY();
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
RelativeLayout.LayoutParams lParams = (RelativeLayout.LayoutParams) view.getLayoutParams();
_xDelta = X - lParams.leftMargin;
Log.d("TTP", "X_Delta " + _xDelta + " X " + X + " left margin " + lParams.leftMargin);
break;
case MotionEvent.ACTION_UP:
int notMoved = X - _xDelta;
if(notMoved == 0){
Log.d("TTP", "ACTION UP ");
return false;
}
break;
case MotionEvent.ACTION_POINTER_DOWN:
break;
case MotionEvent.ACTION_POINTER_UP:
Log.d("TTP", "POINTER UP ");
break;
case MotionEvent.ACTION_MOVE:
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) view.getLayoutParams();
int mTotalMargin = X - _xDelta;
boolean isMovingRight = mTotalMargin > 0;
if ((isMovingRight && mTotalMargin < (getScreenWidth() / 2)) || (!isMovingRight && mTotalMargin > (getScreenWidth() / -2))) {
layoutParams.leftMargin = mTotalMargin;
layoutParams.rightMargin = mTotalMargin * -1;
view.setLayoutParams(layoutParams);
Log.d("TTP", "Mov X_Delta " + _xDelta + " X " + X + " getScreenWidth " + getScreenWidth() + " TotalMargin " + mTotalMargin + " " + isMovingRight);
}
break;
case MotionEvent.ACTION_CANCEL:
Log.d("TTP", "CANCEL ");
return false;
}
return true;
}
**So my question is how can I bypass dragging operation from BTN1,2 and ImageView to LinearLayout regardless of their click events. Please help me I am stuck here **

Related

onTouchListener is not working properly in ImageView

I am developing an android application, in my application I dynamically create some ImageViews and set that ImageViews in to a RelativeLayout. So I want to drag each image in the layout independently.Now its working but not properly, when I drag image then the image start vibrating and moving slowly. And I wanted to implement Pinch Zoom in this image.Is it possible? And how how can I remove the vibration on moving the image ? If any one know it please help me..
Thanks
This is my onTouchListener()
canvasImage[i].setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
x1 = motionEvent.getX();
y1 = motionEvent.getY();
//Log.v("vvvvvv", "" + x1 + " " + y1);
final int action = motionEvent.getAction();
switch (motionEvent.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
String w = imglayout.getTop() + " " + imglayout.getHeight();
Log.v("wwww", "" + w);
x2 = motionEvent.getX();
y2 = motionEvent.getY();
dx = x2 - canvasImage[finalI].getX();
dy = y2 - canvasImage[finalI].getY();
//Log.v("cccccc", "" + x2 + " " + y2);
moving = true;
break;
case MotionEvent.ACTION_UP:
moving = false;
break;
case MotionEvent.ACTION_MOVE:
if (moving) {
canvasImage[finalI].setX(motionEvent.getX() - dx);
canvasImage[finalI].setY(motionEvent.getY() - dy);
//Log.v("qqqqqq", "" + canvasImage[finalI].getX());
}
break;
}
//mainLayout.invalidate();
return true;
}
});
This is my setCanvasImage() method used to set images into RelativeLayout
public void setCanvasImage() {
int screenSize = getResources().getConfiguration().screenLayout &
Configuration.SCREENLAYOUT_SIZE_MASK;
final int imgCount = dbobj.getFromTemp();
canvasImage = new ImageView[imgCount];
imglayout = (RelativeLayout) findViewById(R.id.canvas);
final String[] strImage = dbobj.getdImage();
imglayout.removeAllViews();
for (int i = 0; i < imgCount; i++) {
canvasImage[i] = new ImageView(this);
canvasImage[i].setTag("img_" + i);
boolean tabletSize = getResources().getBoolean(R.bool.isTablet);
if (tabletSize) {
int imgWidth = 130;
int imgHeight = 130;
RelativeLayout.LayoutParams paramss = new RelativeLayout.LayoutParams(imgWidth, imgHeight);
paramss.setMargins(posLeft, posTop, 0, 0);
canvasImage[i].setLayoutParams(paramss);
canvasImage[i].setScaleType(ScaleType.FIT_XY);
canvasImage[i].setTag(strImage[i]);
setImage(strImage[i], canvasImage[i]);
imglayout.addView(canvasImage[i]);
}
if( screenSize == Configuration.SCREENLAYOUT_SIZE_NORMAL){
int imgWidth = 100;
int imgHeight = 100;
RelativeLayout.LayoutParams paramss = new RelativeLayout.LayoutParams(imgWidth, imgHeight);
paramss.setMargins(posLeft, posTop, 0, 0);
canvasImage[i].setLayoutParams(paramss);
canvasImage[i].setTag(strImage[i]);
setImage(strImage[i], canvasImage[i]);
imglayout.addView(canvasImage[i]);
}
posLeft = posLeft + 15;
}
}
RelativeLayout xml file
<RelativeLayout
android:layout_below="#+id/btnhorscrolvw"
android:layout_width="match_parent"
android:layout_height="500dp"
android:id="#+id/canvas"
android:background="#ffff"
android:orientation="horizontal"
>
</RelativeLayout>
I think this will work.
float dX, dY;
#Override
public boolean onTouch(View view, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
dX = view.getX() - event.getRawX();
dY = view.getY() - event.getRawY();
break;
case MotionEvent.ACTION_MOVE:
view.animate()
.x(event.getRawX() + dX)
.y(event.getRawY() + dY)
.setDuration(0)
.start();
break;
default:
return false;
}
return true;
}
You need to use scalx and scaley factor of imageview for implementing pinch zooming
imageview.setScaleX(scalefactor);
imageview.setScaleY(scalefacto);
Android you can adjust the margin left and margin top to for draging the imageview

Perform action on certain Y coordinate

I'm trying to make a view invisible when it's dragged to a certain Y coordinate on the screen.
This is what I got now:
private final class dragTouchListener implements View.OnTouchListener {
#Override
public boolean onTouch(View v, MotionEvent event) {
final int X = (int) event.getRawX();
final int Y = (int) event.getRawY();
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
ContentFrameLayout.LayoutParams lParams = (ContentFrameLayout.LayoutParams) v.getLayoutParams();
_xDelta = X - lParams.leftMargin;
_yDelta = Y - lParams.topMargin;
break;
case MotionEvent.ACTION_UP:
trash_image.setVisibility(View.INVISIBLE);
break;
case MotionEvent.ACTION_POINTER_DOWN:
break;
case MotionEvent.ACTION_POINTER_UP:
break;
case MotionEvent.ACTION_MOVE:
trash_image.setVisibility(View.VISIBLE);
ContentFrameLayout.LayoutParams layoutParams = (ContentFrameLayout.LayoutParams) v.getLayoutParams();
layoutParams.leftMargin = X - _xDelta;
layoutParams.topMargin = Y - _yDelta;
layoutParams.rightMargin = -250;
layoutParams.bottomMargin = -250;
v.setLayoutParams(layoutParams);
if(v.getY() > trash_image.getY()){
v.setVisibility(View.INVISIBLE);
}
break;
}
contentView.invalidate();
return true;
}
}
So basically what I've tried here is simply an if statement to check if the Y position of the view has "passed" that of another ImageView placed on the upper part of the screen. This however result in becoming invisible as soon as I touch the view to be dragged, no matter where on the screen it's located. So it's far from accurate, or wrong all together.
As requested in comment, a suggestion (do note I had to change it, since this is for a client program, so I didnt test it again):
First, discover SCREEN_DENSITY
private static float SCREEN_DENSITY = getResources().getDisplayMetrics().density;
The onTouch function:
public boolean onTouch(final View v, MotionEvent event) {
case MotionEvent.ACTION_DOWN:
mainFinger = new Point(
(int) (event.getRawX() / SCREEN_DENSITY),
(int) (event.getRawY() / SCREEN_DENSITY)
);
break;
case MotionEvent.ACTION_MOVE:
movFrame(
(FrameLayout) v,
(int) (event.getRawX() / SCREEN_DENSITY),
(int) (event.getRawY() / SCREEN_DENSITY)
);
}
movFrame function:
private void movFrame(FrameLayout v, int movX, int movY) {
MyObject p = (MyObject ) v.getTag();
int[] x, y, h, w;
x = p.x;
y = p.y;
h = p.h;
w = p.w;
x = p.x + movX - mainFinger.x;
mainFinger.x = movX;
if (x + w > p.parent.w) {
x = p.parent.w - w;
}
if (x < 0) {
x = 0;
}
y = p.y + movY - mainFinger.y;
mainFinger.y = movY;
if (y + h > p.parent.h) {
y = p.parent.h - h;
}
if (y < 0) {
y = 0;
}
p.updateMyObject(x, y, h, w);
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
(int) ((p.w * SCREEN_DENSITY) + 0.5),
(int) ((p.h * SCREEN_DENSITY) + 0.5)
);
params.leftMargin = (int) ((p.x * SCREEN_DENSITY) + 0.5);
params.topMargin = (int) ((p.y * SCREEN_DENSITY) + 0.5);
v.setLayoutParams(params);
}

Android : WindowManager.UpdateViewLayout() not working

I am showing camera preview on top using system alert. And I am trying to make it draggable. Initially I am drawing it on top left conrner. But on dragging it, it just comes to the center of the screen and doesn't move after that.
Here is how I am adding relative layout :
RelativeLayout.LayoutParams sf_lp = new RelativeLayout.LayoutParams(xlen,ylen);
relativeLayout.addView(surfaceView,sf_lp);
WindowManager.LayoutParams wLayoutParams = new WindowManager.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT,0,0,WindowManager.LayoutParams.TYPE_SYSTEM_ALERT, WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, PixelFormat.TRANSLUCENT);
wLayoutParams.gravity = Gravity.TOP | Gravity.LEFT;
windowManager.addView(relativeLayout,wLayoutParams);
Here is the code for OnTouch :
public boolean onTouch(View v, MotionEvent event) {
int X = (int) event.getRawX();
int Y = (int) event.getRawY();
int xpos = relativeLayout.getLeft();
int ypos = relativeLayout.getTop();
if(X >= xpos && X <= xpos+relativeLayout.getWidth() && Y >= ypos && Y <= ypos+relativeLayout.getHeight())
{
Toast.makeText(this,"X="+X+", "+"Y="+Y+"-Touched inside",Toast.LENGTH_SHORT).show();
switch(event.getAction() & MotionEvent.ACTION_MASK)
{
case MotionEvent.ACTION_DOWN :
WindowManager.LayoutParams wlp = (WindowManager.LayoutParams) v.getLayoutParams();
dx = X - wlp.x;
dy = Y - wlp.y;
Log.v("onTouch", "Action Down:X=" + X + ", Y=" + Y + " ,dx=" + dx + " ,dy=" + dy);
break;
case MotionEvent.ACTION_UP : Log.v("onTouch","Action Up:X="+X+", Y="+Y+" ,dx="+dx+" ,dy="+dy);
break;
case MotionEvent.ACTION_POINTER_DOWN:
break;
case MotionEvent.ACTION_POINTER_UP:
break;
case MotionEvent.ACTION_MOVE :
//windowManager.removeView(v);
Log.v("ACTION_MOVE","X="+ (X-dx) +"Y="+ (Y-dy));
//((TextView) v.findViewWithTag("tv")).setText("X="+ (X-dx) +"Y="+ (Y-dy));
WindowManager.LayoutParams wlp1 = new WindowManager.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT,WindowManager.LayoutParams.TYPE_SYSTEM_ALERT, WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, PixelFormat.TRANSLUCENT);
wlp1.x = X-dx;
wlp1.y = Y-dy;
windowManager.updateViewLayout(v,wlp1);
//windowManager.addView(v,wlp1);
//v.animate().x(X-dx).y(Y-dy).setDuration(0).start();
Log.v("onTouch", "Action Move:X=" + X + ", Y=" + Y + " ,dx=" + dx + " ,dy=" + dy);
break;
}
}
else
{
Toast.makeText(this,"X="+X+", "+"Y="+Y+"-Touched Outside",Toast.LENGTH_SHORT).show();
}
return false;
}
As you can see in Action Move I have already tried removing the view and the adding it again with new layout parameters but it does the same thing. I can drag a button in an activity with this same code but not this. What am I doing wrong?
I had tried the same using below code and using surfaceview directly rather than relative layout
preview.setOnTouchListener(new View.OnTouchListener() {
private int initialX;
private int initialY;
private float initialTouchX;
private float initialTouchY;
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
initialX = params.x;
initialY = params.y;
initialTouchX = event.getRawX();
initialTouchY = event.getRawY();
return true;
case MotionEvent.ACTION_UP:
return true;
case MotionEvent.ACTION_MOVE:
params.x = initialX + (int) (event.getRawX() - initialTouchX);
params.y = initialY + (int) (event.getRawY() - initialTouchY);
windowManager.updateViewLayout(preview, params);
return true;
}
return false;
}
});
Finally I found what was causing it. The problem was with the 'if' condition where I was trying to determine if user has touched inside the view or outside. It wasn't updating the location of relative layout after dragging.
int xpos = relativeLayout.getLeft();
int ypos = relativeLayout.getTop();
if(X >= xpos && X <= xpos+relativeLayout.getWidth() && Y >= ypos && Y <= ypos+relativeLayout.getHeight())
{
}
I commented the if condition and its working as expected. But I am not sure what was problem with 'getLeft()' and 'getTop()'. I also tried 'getLocationInWindow()' but it didn't update the relative layout's location in screen too. If anyone finds the problem please share. And thanks for your help.

Drag & Drop for older Android not precise

So I'm attempting to make a "magnetic poetry" type application. Users will move various Button widgets on the screen. I am using a Button widget since it is the closest to the look of the magnet, though I am open to other options!
The objects are not properly moving with my finger. They're close but they're not exactly in line with my finger. The X coordinate on my phone seems to be fine, but the Y corrdinate is off. Is this perhaps due to the title bar?
private final static int DRAGGING_OFF = 0;
private final static int DRAGGING_ON = 1;
private int dragStatus;
private GestureDetector mGestureDetector;
private int mOffsetX;
private int mOffsetY;
private LayoutParams mOldParams;
private RelativeLayout.LayoutParams lp;
#Override
public boolean onTouchEvent(MotionEvent event) {
if(!mGestureDetector.onTouchEvent(event)) {
if(event.getAction() == MotionEvent.ACTION_MOVE) {
if(dragStatus == DRAGGING_ON) {
Log.e(VIEW_LOG_TAG, "Dragging! RAW -- " + event.getRawX() + " : " + event.getRawY() + " NOT RAW -- " + event.getX() + " : " + event.getY());
int rawX, rawY;
int finalX, finalY;
rawX = (int) event.getRawX();
rawY = (int) event.getRawY();
finalX = rawX - mOffsetX;
finalY = rawY - mOffsetY;
lp.setMargins(finalX, finalY, 0, 0);
this.setLayoutParams(lp);
}
return true;
} else if(event.getAction() == MotionEvent.ACTION_UP) {
if(dragStatus == DRAGGING_ON) {
dragStatus = DRAGGING_OFF;
Log.e(VIEW_LOG_TAG, "Stopped dragging!");
}
return true;
} else {
return super.onTouchEvent(event);
}
} else {
return true;
}
}
private final GestureDetector.SimpleOnGestureListener mListener = new GestureDetector.SimpleOnGestureListener() {
#Override
public boolean onDown(MotionEvent e) {
int[] location = new int[2];
Log.e(VIEW_LOG_TAG, "Down! RAW -- " + e.getRawX() + " : " + e.getRawY() + " NOT RAW -- " + e.getX() + " : " + e.getY());
dragStatus = DRAGGING_ON;
// Sets the current location of the View in the int[] passed to it; x then y.
getLocationInWindow(location);
Log.e(VIEW_LOG_TAG, "Down location: " + location[0] + " " + location[1]);
mOffsetX = (int) e.getRawX() - location[0];
mOffsetY = (int) e.getRawY() - location[1];
mOldParams = getLayoutParams();
return true;
}
};
I think the issue is that you're not getting the DELTA of the current touch point Y and the cached, last touch point y. You need something like this:
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final TextView textView = (TextView) findViewById(R.id.text);
final ImageView image = (ImageView) findViewById(R.id.image);
matrix.setTranslate(1f, 1f);
image.setImageMatrix(matrix);
image.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
matrix.getValues(m); //copy matrix values into array
PointF currentXYTouchPoint = new PointF(event.getX(), event.getY());
switch(event.getAction()) {
case MotionEvent.ACTION_DOWN: //start of pressed gesture
lastXYTouchPoint.set(event.getX(), event.getY()); //save the last touchpoint
mode = DRAG;
break;
case MotionEvent.ACTION_MOVE:
//calculate the change in finger position
float deltaX = currentXYTouchPoint.x - lastXYTouchPoint.x;
float deltaY = currentXYTouchPoint.y - lastXYTouchPoint.y;
matrix.postTranslate(deltaX, deltaY); //move the entire image by the deltas
image.setImageMatrix(matrix);
// save this last starting touchpoint
lastXYTouchPoint.set(currentXYTouchPoint.x, currentXYTouchPoint.y);
break;
}
textView.setText("TouchPoint started at " + currentXYTouchPoint.x + ", " + currentXYTouchPoint.y + " & the matrix is now " + Arrays.toString(m));
return true;
}
});
}
Adapt it to your own purposes, but the basic idea is there.

How to read a pdf file from left to right position without scrolling up & down in android emulator(pdf viewer)?

I created a pdf viewer for android, in that the pdf files are open in scrolling position(up and down) but i need it in left to right position. I tried it in various combos but it's failed to open.
try this code
/**
* Handle touch event coming from Android system.
*/
public boolean onTouch(View v, MotionEvent event) {
this.lastControlsUseMillis = System.currentTimeMillis();
Log.v(TAG, ""+event.getAction());
if (!gestureDetector.onTouchEvent(event)) {
Log.v(TAG, ""+event.getAction());
if (event.getAction() == MotionEvent.ACTION_DOWN) {
Log.e(TAG, " - DOWN -");
Log.e(TAG, " getX: " + event.getX());
downX = event.getX();
downY = event.getY();
lastX = downX;
lastY = downY;
lockedVertically = verticalScrollLock;
maxExcursionY = 0;
scroller = null;
}
else if
(event.getAction() == MotionEvent.ACTION_UP){
Log.e(TAG, " - UP -");
Log.e(TAG, " getY: " + event.getY());
}
else if (event.getAction() == MotionEvent.ACTION_MOVE){
if (lockedVertically && unlocksVerticalLock(event))
lockedVertically = false;
float dx = event.getX() - lastX;
float dy = event.getY() - lastY;
float excursionY = Math.abs(event.getY() - downY);
if (excursionY > maxExcursionY)
maxExcursionY = excursionY;
if (lockedVertically)
dx = 0;
doScroll((int)-dx, (int)-dy);
lastX = event.getX();
lastY = event.getY();
}
}
return true;
}
I neaded Horizontal Scrolling with paging once and came across this,
With this class you can add views in code and swipe through them.
Hope this helps

Categories

Resources