大家好,我想实现这样的效果:
在一个layout中有4个Button和一个surfaceview,  当按下这个layout中任意地方时,可以在界面上任意移动.
当点击Button时,相应执行动作.
因为要移动一个layout,我就重写了viewgroup,然后在viewgroup中放4个Button,布局好, 在onTouchEvent事件中判断是否移动, 然后updateViewLayout(),现在的问题是:
我每次按下时,就出错, 提示说:05-10 AndroidRuntime(21357): java.lang.IllegalArgumentException: Given view not a child of com.example.testviewgroup.snoViewGroup@41703738
请问下为什么,谢谢了

我的代码是:public class snoViewGroup extends ViewGroup {

///Context mContext;
public static int TOOL_BAR_HIGH = 0;
public static WindowManager.LayoutParams params = new WindowManager.LayoutParams();
private float startX;
private float startY;
private float x;
private float y;

public snoViewGroup(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
      
        int Height=0;
        final int count = getChildCount();
        for (int i = 0; i < count; i++) {
            final View child = getChildAt(i);
         
            if (child.getVisibility() != View.GONE) {
         Log.i("sno","snoviewgroup--!= View.GONE:"+count);
                final int childWidth = child.getMeasuredWidth(); 
                final int childHeight= child.getMeasuredHeight();
                child.layout(0, 2+Height, childWidth,
                 childHeight); 
                Height += childHeight;
            }
        }
    }
   @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        final int count = getChildCount();
        for (int i = 0; i < count; i++) {
            getChildAt(i).measure(widthMeasureSpec, heightMeasureSpec);
        }       
    }
   public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (getChildCount() == 0)
            return false;
        return true;
    }
   @Override
public boolean onTouchEvent(MotionEvent event) {
// 触摸点相对于屏幕左上角坐标
x = event.getRawX();
y = event.getRawY() - TOOL_BAR_HIGH;
Log.d("sno","------X: " + x + "------Y:" + y);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
startX = event.getX();
startY = event.getY();
break;
case MotionEvent.ACTION_MOVE:
updatePosition();
break;
case MotionEvent.ACTION_UP:
updatePosition();
startX = startY = 0;
break;
}
return true;
}
private void updatePosition() {
// View的当前位置
params.x = (int) (x - startX);
params.y = (int) (y - startY);
updateViewLayout(this, params);
}}
 

解决方案 »

  1.   

    看你代码头疼,自己大概写的你功能~你看看是不是你那意思~package com.hahaha.hhaha;import android.os.Bundle;
    import android.app.Activity;
    import android.view.Menu;
    import android.view.MotionEvent;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.view.View.OnTouchListener;
    import android.widget.Button;
    import android.widget.RelativeLayout;
    import android.widget.Toast;public class MainActivity extends Activity {
    RelativeLayout rl;
    int x,y,mx,my;
    Button btn01;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    btn01 = (Button) findViewById(R.id.btn01);
    btn01.setOnClickListener(new OnClickListener() {

    @Override
    public void onClick(View v) {
    // TODO Auto-generated method stub
    Toast.makeText(MainActivity.this, "点死我了", 100).show();
    }
    });
    rl = (RelativeLayout) findViewById(R.id.rl);
    rl.setOnTouchListener(new OnTouchListener() {

    @Override
    public boolean onTouch(View v, MotionEvent e) {
    // TODO Auto-generated method stub
    switch (e.getAction()) {
    case MotionEvent.ACTION_DOWN:
    x = (int) e.getX();
    y = (int) e.getY();
    break; case MotionEvent.ACTION_UP:

    break;

    case MotionEvent.ACTION_MOVE:
    mx = (int) (e.getRawX() - x);
    my =(int) (e.getRawY() - y);
    v.layout(mx, my, mx + v.getWidth(), my + v.getHeight());
    break;
    default:
    break;
    }
    return true;
    }
    });
    }}
      

  2.   

    楼上的可以,直接调用v.layout(mx, my, mx + v.getWidth(), my + v.getHeight());就可以了实现任意控件的移动了,加上刷新。
      

  3.   

    有个问题想不明白,请教一下:这里的x是按下时的相对于窗口的相对坐标.而当移动时,你 又使用getRawX这个相对屏幕的绝对坐标,  这样绝对坐标减去相对坐标 有什么作用呢,一直想不明白. 希望给指点一下,谢谢!:mx = (int) (e.getRawX() - x);
    my =(int) (e.getRawY() - y);
    我的理解是 getX和getY是相对坐标.getRawX和getRawY是绝对坐标,请问是这样的,还是我理解有误.
      

  4.   

    谢谢各位了,sno_guo: 这个问题是因为 你要移动到的是当前view的坐标,不是手指按下去的坐标, getX这样获得当前手指相对于view的偏移量,减去这个偏移量不就是当前view的真正坐标了嘛,然后把view的坐标设置一下,就实现了移动.