1

我似乎对 java 对象的引用有问题,这可能是由于多年使用 C 语言编程的结果。下面的代码应该使我能够在画布周围移动“WordPart”的对象。当我选择第一个对象时,它会按预期移动。当我释放第一个对象并选择第二个时,第一个和第二个对象的位置变得相同。(我已经删除了编译所需的代码,但与问题无关。)据我所知,activeImage 引用似乎同时指向 wordPartList 中的两个对象。请帮我找出我的误解。

...
public class ONG2Activity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(new SurfaceView2(this));
}

public class SurfaceView2 extends SurfaceView implements SurfaceHolder.Callback {    

ArrayList<WordParts> wordPartList;
WordParts activeImage;
Point activePosition;
String TAG = "SurfaceView2";
public SurfaceView2(Context context) {
super(context);        
wordPartList = NewPartList(context);
this.getHolder().addCallback(this);
setFocusable(true);
activeImage = null;
activePosition = new Point();
}
/**
 * 
 * @return list of word parts
 */
private ArrayList<WordParts> NewPartList(Context context) {
ArrayList<WordParts> newParts = new ArrayList<WordParts>();
newParts.add(new WordParts(context, new Point(400, 100), "foo"));
newParts.add(new WordParts(context, new Point(200, 100), "bar");
return newParts;
}
@Override
protected void onDraw(Canvas canvas) {
Log.d(TAG, "inside onDraw");
canvas.drawColor(Color.BLACK);
if (activeImage != null) {
activeImage.NewPosition(activePosition);
}
draw(canvas, BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher), new Point(100, 300));
draw(canvas, BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher), new Point(200, 300));
draw(canvas, BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher), new Point(300, 300));
for (WordParts wp : wordPartList) {
Point center = wp.getCenter();
Log.d(TAG, String.format("Word part %s at x=%d, y=%d", wp.mWordPartString, center.x, center.y));
draw(canvas, wp.getBitMap(), center);
}

}     
@Override    
public boolean onTouchEvent(MotionEvent event) {
Log.d(TAG, String.format("inside on touch, event is %s", event.toString()));
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
// if within wordPart, set as active
for (WordParts wp : wordPartList) {
if (wp.isInside(event)) {
activeImage = wp;
Log.d(TAG, String.format("Touch down inside word part %s", wp.mWordPartString));
break; // end iteration
}
}

break;
case MotionEvent.ACTION_UP:
for (WordParts wp : wordPartList) {
if (activeImage == wp){
wp.endTouch();
Log.d(TAG, String.format("Released word part %s", wp.mWordPartString));
}
}
activeImage = null;
break;

default:
break;
}
activePosition.x = (int) event.getX();
activePosition.y = (int) event.getY();
if (activeImage != null)
this.postInvalidate(); // force call to onDraw
return true;
}

/**
 * Draw the bitmap centered at specified point
 * @param canvas - target of drawing
 * @param bm - bitmap to draw
 * @param centerPt
 */
public void draw(Canvas canvas, Bitmap bm, Point centerPt) {
canvas.drawBitmap( bm, 
   centerPt.x - (bm.getWidth() / 2), 
   centerPt.y - (bm.getHeight() / 2), null); 
Log.d(TAG, String.format("canvas %s, bm %s, point %s", canvas.toString(), bm.toString(), centerPt.toString()));
}
public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) 
{     

}
public void surfaceCreated(SurfaceHolder holder) {
Log.d("surface", "Surface created");        
setWillNotDraw(false);
            }
public void surfaceDestroyed(SurfaceHolder holder) {
Log.d("surface", "Surface destroyed");
}
}
}
4

1 回答 1

3

怀疑这是问题所在:

if (activeImage != null) {
    activeImage.NewPosition(activePosition);
}

Unfortunately we don't have the code for unconventionally-named NewPosition, but presumably it sets the value of a field in a WordParts. If you set the value of two fields within two separate WordParts objects to refer to the same Point, then later when you change the values within that Point like this:

activePosition.x = (int) event.getX();
activePosition.y = (int) event.getY();

then yes, those changes will be visible via both WordParts objects, as they both refer to the same object.

If you're new to Java, I would strongly advise you to learn the basics of the language through simple console apps. Learn about objects, references and primitives, inheritance, the core collections and IO etc, then start working in the trickier environment of UIs and mobile.

于 2012-10-09T13:38:19.783 回答