简体   繁体   中英

Why is the onClickListener for my custom ImageView not registering?

I have a panning zooming relative layout within which I add 25 imageviews that represent systems on a starmap. This takes up 2/3 of the screen. The other 1/3 displays information on whichever corresponding system imageview is clicked. However, my onClickListener method is not triggering. I used debug mode with a breakpoint near the start of the onClick method to be sure it wasn't triggering and not just displaying improperly. Here is the relevant code.

public class StarMapActivity extends AppCompatActivity implements View.OnClickListener {
InteractiveView starMap;
TextView systemNameView;
TextView systemFactionView;
TextView systemCoordinatesView;
TextView systemPlanetsNumberView;
 protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_star_map);

    starMap = (InteractiveView) findViewById(R.id.myStarMapInteractiveView);
    systemNameView = (TextView) findViewById(R.id.systemNameView);
    systemFactionView = (TextView) findViewById(R.id.systemFactionView);
    systemCoordinatesView = (TextView) findViewById(R.id.systemCoordinatesView);
    systemPlanetsNumberView = (TextView) findViewById(R.id.systemPlanetsNumberView);

 for (int i = 0; i < 25; i++) {          plotSystem(PlayerCharacterInfo.currentPlayerCharacter.occupiedSector.starSystems[i], i);
    }
}
void plotSystem(StarSystem systemToDraw, int systemArrayId){ //draws the white circle images that represent the systems on the map
    StarSystemView viewToDraw = new StarSystemView(this, getResources().getString(systemToDraw.nameId), systemArrayId);

    RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);


    ShapeDrawable myShape = new ShapeDrawable(new OvalShape());

    myShape.setIntrinsicHeight(10);
    myShape.setIntrinsicWidth(10);
    myShape.getPaint().setColor(-1);

    layoutParams.leftMargin = (systemToDraw.coordinates.x - 50) * 4;
    layoutParams.topMargin = (systemToDraw.coordinates.y - 50) * 4;

    viewToDraw.setImageDrawable(myShape);

    viewToDraw.setOnClickListener(this);
    viewToDraw.setFocusable(true);
    viewToDraw.setClickable(true);

    starMap.addView(viewToDraw, layoutParams);
    viewToDraw.bringToFront();
}
 public void onClick(View view){
StarSystemView clickedView = (StarSystemView) view;
    StarSystem systemToView = PlayerCharacterInfo.currentPlayerCharacter.occupiedSector.starSystems[clickedView.systemArrayId];

    systemNameView.setText(getResources().getString(systemToView.nameId));

    switch(systemToView.systemFactionId){
        case 0:
            systemFactionView.setText(getResources().getString(R.string.faction_neutral));
            break;
        case 1:
            systemFactionView.setText(getResources().getString(R.string.faction_imperial));
            break;
        case 2:
            systemFactionView.setText(getResources().getString(R.string.faction_federation));
            break;
        case 3:
            systemFactionView.setText(getResources().getString(R.string.faction_republic));
            break;
    }

    systemCoordinatesView.setText(Integer.toString(systemToView.coordinates.x)+", "+Integer.toString(systemToView.coordinates.y));

    switch(systemToView.numberOfPlanets){
        case 1:
            systemPlanetsNumberView.setText(getResources().getString(R.string.basic_one));
            break;
        case 2:
            systemPlanetsNumberView.setText(getResources().getString(R.string.basic_two));
            break;
        case 3:
            systemPlanetsNumberView.setText(getResources().getString(R.string.basic_three));
            break;
    }
}

Also for reference, the interactive view class:

    import android.util.AttributeSet;
    import android.widget.RelativeLayout;
    import android.content.Context;
    import android.graphics.Canvas;
    import java.lang.Math;
    import android.view.MotionEvent;
    import android.view.View;
    import android.widget.TextView;



    public class InteractiveView extends RelativeLayout {

    private float mPositionX = 0;
    private float mPositionY = 0;
    float mScale = 1.0f;

    public InteractiveView(Context context) {
        super(context);
        this.setWillNotDraw(false);
        this.setOnTouchListener(mTouchListener);
    }

    public InteractiveView(Context context, AttributeSet attrs){
        super(context, attrs);
        this.setWillNotDraw(false);
        this.setOnTouchListener(mTouchListener);
    }


    public void setMovingPosition(float lPositionX, float lPositionY){
        mPositionX += lPositionX;
        mPositionY += lPositionY;
    }


    @Override
    protected void dispatchDraw(Canvas canvas) {
        if (mScale < 0.5){
            mScale = 0.5f;
        } else if (mScale > 5){
            mScale = 5f;
        }

        canvas.save();
        canvas.translate(getWidth() / 2, getHeight() / 2);
        canvas.translate(mPositionX*mScale, mPositionY*mScale);
        canvas.scale(mScale, mScale);
        super.dispatchDraw(canvas);
        canvas.restore();


    }

    // touch events
    private final int NONE = 0;
    private final int DRAG = 1;
    private final int ZOOM = 2;
    private final int CLICK = 3;

    // pinch to zoom
    private float mOldDist;
    private float mNewDist;
    private float mScaleFactor = 0.01f;

    // position
    private float mPreviousX;
    private float mPreviousY;

    int mode = NONE;

    public OnTouchListener mTouchListener = new  OnTouchListener(){
        public boolean onTouch(View v, MotionEvent e) {
            float x = e.getX();
            float y = e.getY();
            switch (e.getAction()) {
                case MotionEvent.ACTION_DOWN: // one touch: drag
                    mode = CLICK;
                    break;
                case MotionEvent.ACTION_POINTER_2_DOWN: // two touches: zoom
                    mOldDist = spacing(e);
                    mode = ZOOM; // zoom
                    break;
                case MotionEvent.ACTION_UP: // no mode
                    mode = NONE;
                    break;
                case MotionEvent.ACTION_POINTER_2_UP: // no mode
                    mode = NONE;
                    break;
                case MotionEvent.ACTION_MOVE: // rotation
                    if (e.getPointerCount() > 1 && mode == ZOOM) {
                        mNewDist = spacing(e) - mOldDist;

                        mScale += mNewDist*mScaleFactor;
                        invalidate();

                        mOldDist = spacing(e);

                    } else if (mode == CLICK || mode == DRAG) {
                        float dx = (x - mPreviousX)/mScale;
                        float dy = (y - mPreviousY)/mScale;

                        setMovingPosition(dx, dy);
                        invalidate();
                        mode = DRAG;
                    }
                    break;
            }
            mPreviousX = x;
            mPreviousY = y;
            return true;
        }
    };

    // finds spacing
    private float spacing(MotionEvent event) {
        float x = event.getX(0) - event.getX(1);
        float y = event.getY(0) - event.getY(1);
        return (float) Math.sqrt(x * x + y * y);
    }
}

Also for reference the imageview class

public class StarSystemView extends ImageView {

String systemName;
int systemArrayId;

public StarSystemView(Context context, String systemNameToSet, int arrayIdToSet){
    super(context);
    systemName = systemNameToSet;
    systemArrayId = arrayIdToSet;
}
}

I have tried using setOnClickListener(StarMapActivity.this) I've also tried setting the layout parameters for the StarSystemViews to 12 and 12 instead of wrapping content. I also put the interactive view to focusable as I read that somewhere. I've also doublechecked the Android Developer website to see if I can't figure out if I've made any typos or coding errors.

Starting to wonder if imageviews inside a zoomable layout are simply unclickable.
Thanks in advance for any help.

Update: You are scaling the layout only in the draw of the canvas, not by moving and scaling the actual views in it. Therefore the moment they are scaled, you won't be able to click, as the view is not in the location that it's being drawn at. You will have to do the scaling differently, and you should probably post a new question for advice on how.

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