1

我的观点有一些问题。我创建了自己的视图(正方形),我想移动我放在屏幕上的任何正方形。使用菜单,我可以将其他方块放在屏幕上。问题是,当程序启动时,我在屏幕上有一个正方形,我可以移动它。但是当我放其他方块时,我可以移动最后一个。我怎样才能解决这个问题?

public class Square extends View {
private float x, y, width, height;
private int screenW, screenH;
public boolean isInside = false;
public int id=0;

public Square(Context context, int aid, int asw, int ash, float aw, float ah) {
    super(context);
    id = aid;
    screenH = ash;
    screenW = asw;
    x = asw/2;
    y = ash/2;
    width = aw;
    height = ah;
}
protected void onDraw(Canvas canvas){       
        Paint paint = new Paint();
        paint.setColor(Color.BLACK);
        canvas.drawLine(x, y, x+width, y, paint);
        canvas.drawLine(x, y, x, y+height, paint);
        canvas.drawLine(x+width, y+height, x+width, y, paint);
        canvas.drawLine(x+width, y+height, x, y+height, paint);
}
public void setPosition(float x, float y){      
    this.x = x-width/2;
    this.y = y-height/2;
    //invalidate();
}
public int contains(float ax, float ay){
    if(ax==x || (ax<(x+width) && ax > x) || ax==(x+width))
        if(ay==y || (ay<(y+height) && ay > y) || ay==(y+height))
            return id;
    return -1;      
}

}

public class SquareBuilder extends Activity {

private int width, height;
//private RelativeLayout layout;
private FrameLayout layout;
private int id=0;
private ArrayList<Square> squareList;
Square squareTouched;
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_square_builder);
    Display display = null;
    display = getWindowManager().getDefaultDisplay();
    DisplayMetrics outMetrics = new DisplayMetrics();
    display.getMetrics(outMetrics);     
    width = outMetrics.widthPixels;
    height = outMetrics.heightPixels;
    Log.i("Display size", "Width: "+width+" Height: "+height);
    Log.i("Display size", "Width: "+width/2+" Height: "+height/2);
    //layout = new RelativeLayout(this);
    layout = new FrameLayout(this);
    squareList = new ArrayList<Square>();
    Square sqr = new Square(this, id++, (int) width, (int)height,50,50);
    sqr.setOnTouchListener(new View.OnTouchListener() {
        public boolean onTouch(View v, MotionEvent event) {
            // TODO Auto-generated method stub
            Square sqr = (Square) v;
            switch(event.getAction()){
            case MotionEvent.ACTION_DOWN:
                if(sqr.contains(event.getX(),event.getY())>=0)
                    sqr.isInside = true;
                break;
            case MotionEvent.ACTION_MOVE:
                if(sqr.isInside)
                    sqr.setPosition(event.getX(),event.getY());
                break;
            case MotionEvent.ACTION_UP:
                sqr.isInside = false;
                break;
            }
            sqr.invalidate();
            //return super.onTouchEvent(event);     
            return true;
            //return false;
        }
    });
    squareTouched = null;
    squareList.add(sqr);
    layout.addView(sqr);
    setContentView(layout);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.activity_square_builder, menu);
    return true;
}
public boolean onOptionsItemSelected(MenuItem item){
    switch(item.getItemId()){
        case R.id.menu_other:
            Square sqr = new Square(this, id++, (int) width, (int) height,50,50);
            sqr.setOnTouchListener(new View.OnTouchListener() {
                public boolean onTouch(View v, MotionEvent event) {
                    // TODO Auto-generated method stub
                    Square sqr = (Square) v;
                    switch(event.getAction()){
                    case MotionEvent.ACTION_DOWN:
                        if(sqr.contains(event.getX(),event.getY())>=0)
                            sqr.isInside = true;
                        break;
                    case MotionEvent.ACTION_MOVE:
                        if(sqr.isInside)
                            sqr.setPosition(event.getX(),event.getY());
                        break;
                    case MotionEvent.ACTION_UP:
                        sqr.isInside = false;
                        break;
                    }
                    sqr.invalidate();
                    //return super.onTouchEvent(event);     
                    return true;
                    //return false;
                }
            });
            squareList.add(sqr);
            layout.addView(sqr);
            setContentView(layout);
            break;
    }
    return super.onOptionsItemSelected(item);   
}

}

4

1 回答 1

0

首先,让创建新方块成为 SquareBuilder 中的一个方法:

private Square newSquare() { ...

然后用对这个新方法的调用替换用于创建正方形的重复代码。这将使您的问题更容易解决,因为您将只有该代码的一份副本。

然后可能会在每个 case 语句中添加一些日志记录,以查看哪些事件真正在哪里触发。

这也可能有帮助:多个视图 OnTouch 事件 当触摸事件不在广场上时,您需要从事件中返回 false,以便可以将事件传播到其他侦听器。返回 true 会消耗事件。

于 2012-09-14T22:52:54.217 回答