Android : WindowManager.UpdateViewLayout() not working - android

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.

Related

Bypass touch listener events to layout

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 **

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);
}

Dragged ImageView, knowing when it's in an X Y area

I have a draggable image and I'm trying to get it so that if it goes within an X Y region of the screen that an event happens.
So far I can detect when I move a finger through the region but not when it is dragging the image.
The code so far: - this code works for the finger
public boolean onTouchEvent(MotionEvent ev) {
int x = (int) ev.getX();
int y = (int) ev.getY();
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
if (x >= 370 && x <= 500 && y >= 250 && y <= 420) {
Log.i(null, "--- Region 1 initiated ---");
}
What I've tried: - but when I try to adapt it to the image...
public boolean onDrag(View layoutview, DragEvent dragevent) {
int action = dragevent.getAction();
View getid = findViewById(R.id.image);
int x1 = (int) getid.getX();
int y1 = (int) getid.getY();
if (action == MotionEvent.ACTION_MOVE) {
if (x1 >= 370 && x1 <= 500 && y1 >= 250 && y1 <= 420) {
Log.i(null, "--- Region 1 initiated by image---");
}
}
...nothing happens. The logcat doesn't show the message. Does anyone know where I'm going wrong or if there's a way of doing this.
Some illustrations, sometimes my description of the problem is pretty bad:
It took a while but I actually got it working by doing this in onTouch:
final int X = (int) event.getRawX();
final int Y = (int) event.getRawY();
ImageView j = (ImageView) findViewById(R.id.image);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
_xDelta = (int) (X - j.getTranslationX());
_yDelta = (int) (Y - j.getTranslationY());
break;
case MotionEvent.ACTION_UP:
_xDelta = 100;
_yDelta = 100;
break;
case MotionEvent.ACTION_MOVE:
j.setTranslationX(X - _xDelta);
j.setTranslationY(Y - _yDelta);
if (X >= 370 && X <= 500 && Y >= 250 && Y <= 420) {
Log.i(null, "Region 1 initiated");
// Do whatever...
}
There is no MotionEvent.ACTION_MOVE defined in DragEvent class
OnDragListener interface defined the method
abstract boolean onDrag(View v, DragEvent event)
Action are:
ACTION_DRAG_STARTED
ACTION_DRAG_ENTERED
ACTION_DRAG_LOCATION
ACTION_DRAG_EXITED
ACTION_DROP
ACTION_DRAG_ENDED
Please refer to this page for more details

Android ScrollView (scrollable on both Horizontal and Vertical smoothly) on which content addable programatically and zoomable on pinch

I need a scrollview where I can add numbers of image and button programatically and on single tap, zoomable by pinch on both horizontal and vertical with smooth scrolling. Here a video what I need exactly. I have tried with Horizontal scrollview within a ScrollView. I can scroll smoothly. I can add item on single tap. I can't zoom now. Here is the sample code:
public void setUpNoticeBoard(){
canvasLayout = (FrameLayout) findViewById(R.id.frameLayout);
canvasLayout.removeAllViews();
FrameLayout.LayoutParams paramsImage = new FrameLayout.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
final ImageView noticeBoard = new ImageView(this);
noticeBoard.setLayoutParams(paramsImage);
noticeBoard.setAdjustViewBounds(true);
noticeBoard.setImageDrawable(getResources().getDrawable(R.drawable.noticeboard));
noticeBoard.setScaleType(ImageView.ScaleType.CENTER_CROP);
canvasLayout.addView(noticeBoard);
float xx = noticeBoard.getWidth();
float yy = noticeBoard.getHeight();
System.out.println("noticeBoard Width:" + xx + "And Height:" + yy);
for (int i = 0; i < 50; i++) {
int x= (int)Math.ceil(Math.random()*3000);
int y= (int)Math.ceil(Math.random()*2000);
FrameLayout.LayoutParams paramsNotice = new FrameLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
paramsNotice.setMargins(x, y, 0, 0);
final ImageView notice = new ImageView(this);
notice.setLayoutParams(paramsNotice);
Resources res = getResources();
String imageName = "pin" + (int)Math.ceil(Math.random()*8);
int resourceId = res.getIdentifier(imageName, "drawable", getPackageName() );
notice.setTag(imageName);
notice.setImageResource(resourceId);
canvasLayout.addView(notice);
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
float curX, curY;
newPin.setVisibility(View.INVISIBLE);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mx = event.getX();
my = event.getY();
break;
case MotionEvent.ACTION_MOVE:
curX = event.getX();
curY = event.getY();
vScroll.scrollBy((int) (mx - curX), (int) (my - curY));
hScroll.scrollBy((int) (mx - curX), (int) (my - curY));
mx = curX;
my = curY;
break;
case MotionEvent.ACTION_UP:
curX = event.getX();
curY = event.getY();
vScroll.scrollBy((int) (mx - curX), (int) (my - curY));
hScroll.scrollBy((int) (mx - curX), (int) (my - curY));
break;
}
return gestureScanner.onTouchEvent(event);
}
public boolean onSingleTapUp(MotionEvent e) {
int x = (int) e.getX();
int y = (int) e.getY();
FrameLayout.LayoutParams paramsNewPin = new FrameLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
paramsNewPin.setMargins(x + hScroll.getScrollX() - 98, y + vScroll.getScrollY() - 250, 0, 0);
final ImageView newPin = new ImageView(this);
newPin.setLayoutParams(paramsNewPin);
newPin.setImageResource(R.drawable.pin5);
canvasLayout.addView(newPin);
return true;
}
Now I need 1 thing Zooming on pinch(Whole content on layout will be zoom)
Thanks.

Categories

Resources