I have drag and drop imageView(multiple imageView with same object) in layout and after that ImageView onTouch it move around layout. but after move imageView it overlapping with each other, how do prevent overalapping image?
also every image object is same. here is my code :
public boolean onDrag(View view, DragEvent event) {
recyclerViewFloorTiles = findViewById(R.id.rvfloortiles);
switch (event.getAction()) {
case DragEvent.ACTION_DRAG_ENDED:
break;
case DragEvent.ACTION_DROP:
dropX = event.getX();
dropY = event.getY();
final ObjectAdapter.DragData state = (ObjectAdapter.DragData) event.getLocalState();
final ImageView shape = (ImageView) LayoutInflater.from(this).inflate(
R.layout.layout_drag_image, dropContainer, false);
shape.setImageResource(state.item.getDrawableRes());
shape.setX(dropX - (float) state.width / 2);
shape.setY(dropY - (float) state.height / 2);
shape.getLayoutParams().width = state.width;
shape.getLayoutParams().height = state.height;
dropContainer.addView(shape);
shape.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View view, MotionEvent event) {
ImageView objectDropImage = new ImageView(DashboardActivity.this);
objectDropImage.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));
dropContainer.addView(objectDropImage);
float newX, newY;
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
dX = view.getX() - event.getRawX();
dY = view.getY() - event.getRawY();
break;
case MotionEvent.ACTION_MOVE:
newX = event.getRawX() + dX;
newY = event.getRawY() + dY;
if ((newX <= 0 || newX >= screenWidth-view.getWidth()) || (newY <= 0 || newY >= screenHight-view.getHeight()))
{
break;
}
view.setX(newX);
view.setY(newY);
break;
}
return false;
}
});
}
break;
default:
break;
}
return true;
}
Related
I simply want to touch and drag/move an object around on the screen.
I know there are plenty of given codes out there, using surface holder and imageview matrix. But these codes are not well notated, and I don't know what is going on. I want to just copy and paste them into my own code.
I know there is this documentation on Android Dev website that teaches you how to drag and scale. But for dragging, it only gives an example for the onTouchEvent(), but I don't how I can integrate this method into my MainActivity.java and activity_main.xml files. Specically, in the code snippet, there are mPosX and mPosY, and I don't know how to use these global variables.
I tried creating a new class extending View class and put onTouchEvent().
I know you can use onDraw() and override it to utilize mPosX and mPosY to redraw the object every time your finger moves, but how exactly i don't know. I need some example codes implementing onDraw().
This is the code snippet I am talking about:
// The ‘active pointer’ is the one currently moving our object.
private int mActivePointerId = INVALID_POINTER_ID;
#Override
public boolean onTouchEvent(MotionEvent ev) {
// Let the ScaleGestureDetector inspect all events.
mScaleDetector.onTouchEvent(ev);
final int action = MotionEventCompat.getActionMasked(ev);
switch (action) {
case MotionEvent.ACTION_DOWN: {
final int pointerIndex = MotionEventCompat.getActionIndex(ev);
final float x = MotionEventCompat.getX(ev, pointerIndex);
final float y = MotionEventCompat.getY(ev, pointerIndex);
// Remember where we started (for dragging)
mLastTouchX = x;
mLastTouchY = y;
// Save the ID of this pointer (for dragging)
mActivePointerId = MotionEventCompat.getPointerId(ev, 0);
break;
}
case MotionEvent.ACTION_MOVE: {
// Find the index of the active pointer and fetch its position
final int pointerIndex =
MotionEventCompat.findPointerIndex(ev, mActivePointerId);
final float x = MotionEventCompat.getX(ev, pointerIndex);
final float y = MotionEventCompat.getY(ev, pointerIndex);
// Calculate the distance moved
final float dx = x - mLastTouchX;
final float dy = y - mLastTouchY;
mPosX += dx;
mPosY += dy;
invalidate();
// Remember this touch position for the next move event
mLastTouchX = x;
mLastTouchY = y;
break;
}
case MotionEvent.ACTION_UP: {
mActivePointerId = INVALID_POINTER_ID;
break;
}
case MotionEvent.ACTION_CANCEL: {
mActivePointerId = INVALID_POINTER_ID;
break;
}
case MotionEvent.ACTION_POINTER_UP: {
final int pointerIndex = MotionEventCompat.getActionIndex(ev);
final int pointerId = MotionEventCompat.getPointerId(ev, pointerIndex);
if (pointerId == mActivePointerId) {
// This was our active pointer going up. Choose a new
// active pointer and adjust accordingly.
final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
mLastTouchX = MotionEventCompat.getX(ev, newPointerIndex);
mLastTouchY = MotionEventCompat.getY(ev, newPointerIndex);
mActivePointerId = MotionEventCompat.getPointerId(ev, newPointerIndex);
}
break;
}
}
return true;
}
Create a class MoveViewTouchListener
public class MoveViewTouchListener
implements View.OnTouchListener
{
private GestureDetector mGestureDetector;
private View mView;
public MoveViewTouchListener(View view)
{
mGestureDetector = new GestureDetector(view.getContext(), mGestureListener);
mView = view;
}
#Override
public boolean onTouch(View v, MotionEvent event)
{
return mGestureDetector.onTouchEvent(event);
}
private GestureDetector.OnGestureListener mGestureListener = new GestureDetector.SimpleOnGestureListener()
{
private float mMotionDownX, mMotionDownY;
#Override
public boolean onDown(MotionEvent e)
{
mMotionDownX = e.getRawX() - mView.getTranslationX();
mMotionDownY = e.getRawY() - mView.getTranslationY();
Log.d("imageview"," down");
return true;
}
#Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)
{
mView.setTranslationX(e2.getRawX() - mMotionDownX);
mView.setTranslationY(e2.getRawY() - mMotionDownY);
if((distanceX==0)&&(distanceY==0))
{
Log.d("imageview"," zoomed");
}
return true;
}
#Override
public boolean onSingleTapUp(MotionEvent e) {
Log.d("imageview"," tapped");
return true;
}
};
}
In activity call:
ImageView imageView= findViewById(R.id.imageView);
imageView.setOnTouchListener(new MoveViewTouchListener(imageView));
I have a library which handles onTouchListener Events for a ImageView.
view.setOnTouchListener(new View.OnTouchListener() {
int lastAction;
float dX = 0;
float dY = 0;
int DELTA = 50;
private static final int MAX_CLICK_DURATION = 200;
private long pressStartTime;
#Override
public boolean onTouch(View view, final MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
pressStartTime = System.currentTimeMillis();
dX = view.getX() - event.getRawX();
dY = view.getY() - event.getRawY();
lastAction = MotionEvent.ACTION_DOWN;
break;
case MotionEvent.ACTION_UP:
if (lastAction == MotionEvent.ACTION_DOWN) {
break;
}
break;
case MotionEvent.ACTION_MOVE:
lastAction = MotionEvent.ACTION_MOVE;
break;
}
return false;
}
});
And then once installing the library into my app i also wanted to set my own onTouchEvent for that ImageView.
view.setOnTouchListener(new new View.OnTouchListener(){});
The problem is that only the library touchListener event gets called and the app one is lost/neglected. If I remove the library then the app touch event gets called. How can I make it so that both the library and the app touchListeners are called?
I have got this simple code to rotate an image with onTouchListener, but it seems to be zooming in and out on the image as well. I am really new to using onTouchListener. Could someone tell me what is happening, or how to fix this. Anything helps thanks:)
public class MainActivity extends Activity implements OnTouchListener {
private ImageView dialer;
private float y=0;
public boolean onTouch(View v, MotionEvent event) {
double r=Math.atan2(event.getX()-dialer.getWidth()/2, dialer.getHeight()/2-event.getY());
int rotation=(int)Math.toDegrees(r);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
//x=event.getX();
y=event.getY();
updateRotation(rotation);
break;
case MotionEvent.ACTION_UP:
break;
}//switch
return true;
}//onTouch
private void updateRotation(double rot){
float newRot= new Float(rot);
Bitmap bitmap=BitmapFactory.decodeResource(getResources(),R.drawable.round_button_big);
Matrix matrix= new Matrix();
matrix.postRotate(newRot,bitmap.getWidth()/2,bitmap.getHeight()/2);
if(y>250){
Bitmap reDrawnBitmap=Bitmap.createBitmap(bitmap,0,0,bitmap.getWidth(),bitmap.getHeight(),matrix,true);
dialer.setImageBitmap(reDrawnBitmap);
}
else{
Bitmap reDrawnBitmap=Bitmap.createBitmap(bitmap,0,0,bitmap.getWidth(),bitmap.getHeight(),matrix,true);
dialer.setImageBitmap(reDrawnBitmap);
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dialer = (ImageView) findViewById(R.id.image);
dialer.setOnTouchListener(this);
}//onCreate
}
Try to use this code on touch event:
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// reset the touched quadrants
for (int i = 0; i < quadrantTouched.length; i++) {
quadrantTouched[i] = false;
}
allowRotating = false;
startAngle = getAngle(event.getX(), event.getY());
break;
case MotionEvent.ACTION_MOVE:
double currentAngle = getAngle(event.getX(), event.getY());
rotateDialer((float) (startAngle - currentAngle));
startAngle = currentAngle;
break;
case MotionEvent.ACTION_UP:
allowRotating = true;
break;
}
// set the touched quadrant to true
quadrantTouched[getQuadrant(event.getX() - (dialerWidth / 2), dialerHeight - event.getY() - (dialerHeight / 2))] = true;
detector.onTouchEvent(event);
return true;
And here you can find an example :http://code.tutsplus.com/tutorials/android-sdk-creating-a-rotating-dialer--mobile-8868
I have a button for which I am using onTouch so that I can move it around. But the button is now failing to load the contents in onClick. How to make it happen ?
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
//some code which dosent work
}
#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:
Voice v1 = new Voice();
v1.putVoice();
return true;
case MotionEvent.ACTION_MOVE:
params.x = initialX + (int) (event.getRawX() - initialTouchX);
params.y = initialY + (int) (event.getRawY() - initialTouchY);
windowManager.updateViewLayout(chatHead, params);
return true;
}
return false;
}
I finally found out that if we differentiate with ACITON_MOVE position we can get a click event.
Here is the snippet which did the trick -
case MotionEvent.ACTION_UP:
if(Math.abs(event.getRawX()-initialTouchX )<=2){
floatingFaceBubble.performClick();
return false;
}
i have a problem with an OnSwipeImageListener (implements OnTouchListener). I use the OnSwipeImageListener in two activities.
On the one activitiy on the ImageView is the OnTouchListener and an OnClickListener and on the other activity on the ImageView is only the OnTouchListener.
If i change return v.onTouchEvent(event) to true under the MotionEvent.ACTION_DOWN then the OnClickListener on the first activity doesn't work and in this way the Swipe of ImageView on the second activity doesn't work. I debugged some times and see that MotionEvent.ACTION_UP is never called.
public boolean onTouch(View v, MotionEvent event) {
switch(event.getAction()) {
case MotionEvent.ACTION_DOWN:
dX = event.getX();
dY = event.getY();
return v.onTouchEvent(event);
case MotionEvent.ACTION_UP:
uX = event.getX();
uY = event.getY();
float deltaX = dX - uX;
float deltaY = dY - uY;
// horizontal
if(Math.abs(deltaX) > MIN_DISTANCE) {
//Left to right
if(deltaX < 0) {
this.onLeftToRight();
return v.onTouchEvent(event);
} else if (deltaX > 0) {
this.onRightToLeft();
return v.onTouchEvent(event);
}
else {
//Swipe too short
return v.onTouchEvent(event);
}
}
// vertical
if (Math.abs(deltaY) > MIN_DISTANCE) {
if(deltaY < 0) {
this.onTopToBottom();
return v.onTouchEvent(event);
} else if (deltaY > 0) {
this.onBottomToTop();
return v.onTouchEvent(event);
}
else {
//Swipe too short
return v.onTouchEvent(event);
}
}
}
return v.onTouchEvent(event);
}
If you want to get the ACTION_UP, you should hijack the ACTION_DOWN.
Instead of returning "v.onTouchEvent(event)", return "true" when you are just handling the ACTION_DOWN.