我在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;
- }
- }