简体   繁体   中英

Double event in imageView with OnTouchListener Android

I'm trying to build a drag and drop function using android 2.1 (sdk 2.1). I searched the web and could only find using android 4.0+. I have an ImageView (wrapped in a class with some attributes and properties) created and set dynamically using this code.

public void setTileImage(Drawable tileImage) {
    if (tileImage == null) {
        Log.d("Tiles", "Null");
    }
    this.tileImage = new ImageView(this.context);
    this.tileImage.setImageDrawable(tileImage);
    this.tileImage.setAdjustViewBounds(true);
    this.tileImage.setScaleType(ImageView.ScaleType.FIT_START);
    this.createImageMargins();
}

public void createImageMargins() {
    LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(this.imageSizeX, this.imageSizeY);
    this.tileImage.setLayoutParams(layoutParams);
    MarginLayoutParams marginParams = new MarginLayoutParams(this.tileImage.getLayoutParams());
    marginParams.setMargins(this.initialPositionX, this.initialPositionY, this.initialPositionX + imageSizeX, this.initialPositionY + this.imageSizeY);
    RelativeLayout.LayoutParams layoutParams2 = new RelativeLayout.LayoutParams(marginParams);
    this.tileImage.setLayoutParams(layoutParams2);
    this.tileImage.requestLayout();
}

I add this ImageView to a RelativeLayout.

RelativeLayout layout = (RelativeLayout) findViewById(R.id.playscreen);
Tiles t1 = this.createTitle();
layout.addView(t1.getTileImage());

And for each ImageView (which are several) created I add the OnTouchListener(unique for all of them)

private static TouchListener listener = new TouchListener();;

t1.createDragHandler(listener);

public void createDragHandler(TouchListener listener){
    this.tileImage.setOnTouchListener(listener);
}

And this the class that implements the OnTouchListener methods. This class change the position (updating the margins - method after the class) of the ImageView with the position of the event that it received.

public class TouchListener implements OnTouchListener{

public boolean onTouch(View v, MotionEvent motionEvent) {
    Tiles currentTile = Tiles.searchTileByView(Play.getAvailableTiles(), (ImageView)v);
    if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
        return true;
    } else if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
        Tiles t = Play.checkCollision(currentTile, currentTile.getPositionX(), currentTile.getPositionY());
        if(t == null){
            if(currentTile.getPositionX() == currentTile.getInitialPositionX() && currentTile.getPositionY() == currentTile.getInitialPositionY()){
                Log.d("Log","This was a click");
            }else{
                currentTile.setPositionX(currentTile.getInitialPositionX());
                currentTile.setPositionY(currentTile.getInitialPositionY());
                currentTile.createImageMargins();
            }
        }else{
            if(t.getId() == currentTile.getId()){
                Play.updateScore(t.getPoints()*t.getSpecialPoints()+currentTile.getPoints()*currentTile.getSpecialPoints());
                t.setActive(false);
                currentTile.setActive(false);
                t.getTileImage().setVisibility(View.INVISIBLE);
                currentTile.getTileImage().setVisibility(View.INVISIBLE);
                Log.d("Log","Tile Removed");
            }
        }
        return true;
    }else if(motionEvent.getAction() == MotionEvent.ACTION_MOVE){
        Log.d("Log:" + this.toString() + ":" + v,"Moved -> X: " + motionEvent.getX() + " Y: " + motionEvent.getY());
        currentTile.setPositionX((int) motionEvent.getX());
        currentTile.setPositionY((int) motionEvent.getY());
        currentTile.updateImageMargins();
        return true;
    }else{
        return false;
    }
}

public void updateImageMargins(){
    MarginLayoutParams marginParams = new MarginLayoutParams(this.tileImage.getLayoutParams());
    marginParams.setMargins(this.positionX, this.positionY, this.positionX  + imageSizeX, this.positionY + this.imageSizeY);
    RelativeLayout.LayoutParams layoutParams2 = new RelativeLayout.LayoutParams(marginParams);
    this.tileImage.setLayoutParams(layoutParams2);
}

I imagine that the problem is that I'm receiving two events in the OnTouchListener.onTouch method. The first is using the coordinates of the RelativeLayout (so it starts in the top left corner of the screen) and other with the coordinates of the ImageView (it start on the top left corner of the ImageView) so when I click and move I receive to events with two different coordinates of the event, like this:

TouchListener@44f3bf80:android.widget.ImageView@44f1b4c8 Moved -> X: 59.0 Y: 24.000015
TouchListener@44f3bf80:android.widget.ImageView@44f1b4c8 Moved -> X: 100.0 Y: 148.00002

In other words, the first line received the coordinates from the position of my click in the imageview (if i click nearer to the any of the borders this value will change) and the second is the position of my click in the relativelayout. So the image start to blink from one point to the other while i move the cursor. Both values change proportionally when I move the cursor towards any direction.

Try using motionEvent.getRawX() and motionEvent.getRawY() instead of getX() and getY() . You may need to make additional adjustments to align it properly within your View .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM