我在AbsoluteLayout动态添加了一些ImageView,用来表示批注,这些ImageView在相关事件中用layout改变位置。
但是改变了它们的位置后,再用addview方法添加一个新的ImageView后,所有ImageView都重新出现在原来addview时的位置上,没有移动,就像被重新初始化了。
问题来了:使用addView方法时,如何保持已有动态控件位置不初始化?
因为不知道布局中的addview是怎么实现的,所有没有想出直接解决问题的办法。
后来只好用了一种不是很好的办法:
要addView时,先将原来的ImageView全部删除,再按照新的位置重新添加到布局中。这样再addView新的ImageView时,原来的ImageView位置也是正确的。
不知道还有什么办法可以更好的达到这种效果?
经过一番尝试,终于解决这个问题,简单说就是,不能使用layout()方法,来改变位置。 layout()虽然可以改变控件的位置, 但不会将位置信息保存到layoutparam中。 而调用addView往布局添加新的控件时,是根据layoutparam来重新布局控件位置的。 因此另一种方法就是:先获取控件的layoutparam,改变其中相关的值后,再设置回去。 这样移动过的控件,就不会在addView时回到原来的位置了。
下面是主要代码:
MyViewActivity.java
package com.ckl.myview;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AbsoluteLayout;
import android.widget.AbsoluteLayout.LayoutParams;
import android.widget.Button;
import android.widget.ImageView;
public class MyViewActivity extends Activity {
ImageView myImage;
AbsoluteLayout mLayout;
AbsoluteLayout.LayoutParams mParams;
Button mButton;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mLayout = (AbsoluteLayout)findViewById(R.id.myLayout);
mParams = new AbsoluteLayout.LayoutParams(
AbsoluteLayout.LayoutParams.WRAP_CONTENT,
AbsoluteLayout.LayoutParams.WRAP_CONTENT,
100, 100);
myImage = new ImageView(this);
myImage.setImageResource(R.drawable.a);
myImage.setLayoutParams(mParams);
mLayout.addView(myImage);
mButton = (Button)findViewById(R.id.myButton1);
mButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
ImageView icon = (ImageView)findViewById(1234);
if (icon != null) {
mLayout.removeView(icon);
}
addIcon(1234, 200, 200);
}
});
}
private ImageView addIcon(int id, int x, int y) {
AbsoluteLayout.LayoutParams params = new AbsoluteLayout.LayoutParams(
AbsoluteLayout.LayoutParams.WRAP_CONTENT,
AbsoluteLayout.LayoutParams.WRAP_CONTENT,
x, y);
ImageView icon = new ImageView(this);
icon.setImageResource(R.drawable.b);
icon.setLayoutParams(params);
mLayout.addView(icon);
return icon;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
int mX = (int)event.getX();
int mY = (int)event.getY();
switch (action) {
case MotionEvent.ACTION_DOWN:
//logd("ACTION_DOWN");
break;
case MotionEvent.ACTION_MOVE:
//logd("ACTION_MOVE");
break;
case MotionEvent.ACTION_UP:
logd("ACTION_UP mX = " + mX + ", mY = " + mY);
/**
* 不能使用myImage.layout()方法,来改变位置。
* layout()虽然可以改变控件的位置, 但不会将位置信息保存到layoutparam中。
* 而调用addView往布局添加新的控件时,是根据layoutparam来重新布局控件位置的。
* 这里需要用另一种方法:先获取控件的layoutparam,改变其中相关的值后,再设置回去。
*/
// myImage.layout(mX, mY, mX + myImage.getWidth(), mY + myImage.getHeight());
AbsoluteLayout.LayoutParams params = (LayoutParams) myImage.getLayoutParams();
params.x = mX;
params.y = mY;
myImage.setLayoutParams(params);
break;
default:
break;
}
return true;
}
private static final String TAG = "MyViewActivity";
private static final boolean debugOn = true;
private int logd(String msg) {
int retVal = 0;
if (debugOn) {
retVal = Log.i(TAG, msg);
}
return retVal;
}
}
工程代码:http://download.csdn.net/detail/victoryckl/3679107