Java 如何将收缩缩放应用于包含其所有子项的相对布局';它像android中的图像视图、按钮、文本视图

Java 如何将收缩缩放应用于包含其所有子项的相对布局';它像android中的图像视图、按钮、文本视图,java,android,imageview,android-relativelayout,pinchzoom,Java,Android,Imageview,Android Relativelayout,Pinchzoom,如屏幕截图所示,我已将ImageView添加到相对布局,即主楼层图。动态添加蓝色图标。我想将放大缩小应用于整个相对布局,以便在放大/缩小布局时图标将随主图像一起移动。目前,当我尝试以下代码缩放相对布局,然后放大/缩小时,只应用于主图像,而不应用于图像上添加的图标 public class ZoomRelativeLayout extends RelativeLayout { private static final int INVALID_POINTER_ID = -1; pr

如屏幕截图所示,我已将ImageView添加到相对布局,即主楼层图。动态添加蓝色图标。我想将放大缩小应用于整个相对布局,以便在放大/缩小布局时图标将随主图像一起移动。目前,当我尝试以下代码缩放相对布局,然后放大/缩小时,只应用于主图像,而不应用于图像上添加的图标

public class ZoomRelativeLayout extends RelativeLayout 
{
    private static final int INVALID_POINTER_ID = -1;
    private Drawable mIcon;
    private float mPosX;
    private float mPosY;
    ZoomRelativeLayout temp;
    private float mLastTouchX;
    private float mLastTouchY;
    private int mActivePointerId = INVALID_POINTER_ID;

    private ScaleGestureDetector mScaleDetector;
    private float mScaleFactor = 1.f;

    public ZoomRelativeLayout(Context context) {
        this(context, null, 0);
        temp = this;
    }

    public ZoomRelativeLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
        temp = this;
    }

    public ZoomRelativeLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        mIcon = context.getResources().getDrawable(R.drawable.shheildlogo);
        mIcon.setBounds(0, 0, mIcon.getIntrinsicWidth(), mIcon.getIntrinsicHeight());
        temp = this;
        mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        // Let the ScaleGestureDetector inspect all events.

        mScaleDetector.onTouchEvent(ev);



        final int action = ev.getAction();
        switch (action & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN: {
                final float x = ev.getX();
                final float y = ev.getY();

                mLastTouchX = x;
                mLastTouchY = y;
                mActivePointerId = ev.getPointerId(0);
                break;
            }

            case MotionEvent.ACTION_MOVE: {
                final int pointerIndex = ev.findPointerIndex(mActivePointerId);
                final float x = ev.getX(pointerIndex);
                final float y = ev.getY(pointerIndex);

                // Only move if the ScaleGestureDetector isn't processing a gesture.
                if (!mScaleDetector.isInProgress()) {
                    final float dx = x - mLastTouchX;
                    final float dy = y - mLastTouchY;

                    mPosX += dx;
                    mPosY += dy;

                    invalidate();
                }

                mLastTouchX = x;
                mLastTouchY = y;

                break;
            }

            case MotionEvent.ACTION_UP: {
                mActivePointerId = INVALID_POINTER_ID;

                break;
            }

            case MotionEvent.ACTION_CANCEL: {
                mActivePointerId = INVALID_POINTER_ID;
                break;
            }

            case MotionEvent.ACTION_POINTER_UP: {
                final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK)
                        >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
                final int pointerId = ev.getPointerId(pointerIndex);
                if (pointerId == mActivePointerId) {
                    // This was our active pointer going up. Choose a new
                    // active pointer and adjust accordingly.
                    final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
                    mLastTouchX = ev.getX(newPointerIndex);
                    mLastTouchY = ev.getY(newPointerIndex);
                    mActivePointerId = ev.getPointerId(newPointerIndex);
                }


                break;
            }
        }
        return true;
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b)
    {
        int count = getChildCount();
        Log.d("onLayout", ""+count);
        for(int i=0;i<count;i++){
            View child = getChildAt(i);
            if(child.getVisibility()!=GONE ){
                RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams)child.getLayoutParams();
                child.layout(
                        (int)(params.leftMargin * mScaleFactor),
                        (int)(params.topMargin * mScaleFactor),
                        (int)((params.leftMargin + child.getMeasuredWidth()) * mScaleFactor),
                        (int)((params.topMargin + child.getMeasuredHeight()) * mScaleFactor)
                );


                child.setLayoutParams(params);
            }
        }
    }




    @Override
    public void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        canvas.save();
        canvas.translate(mPosX, mPosY);
        canvas.scale(mScaleFactor, mScaleFactor);
        Log.d("onDraw", ""+mScaleFactor);
        int count = getChildCount();
        for(int i=0;i<count;i++){
            View child = getChildAt(i);
            if(child.getVisibility()!=GONE){
                child.draw(canvas);
                Log.d("onDraw", ""+mScaleFactor);
            }
        }

        canvas.restore();
    }
    @Override
    protected void dispatchDraw(Canvas canvas) {
        canvas.save();

        canvas.translate(mPosX, mPosY);
        canvas.scale(mScaleFactor, mScaleFactor);

        super.dispatchDraw(canvas);
        canvas.restore();
    }

    private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
        @Override
        public boolean onScale(ScaleGestureDetector detector) {
            mScaleFactor *= detector.getScaleFactor();

            mScaleFactor = Math.max(1.0f, Math.min(mScaleFactor, 5.0f));
            temp.invalidate();
            invalidate();
            return true;
        }
    }
}
公共类ZoomRelativeLayout扩展了RelativeLayout
{
私有静态final int无效\u指针\u ID=-1;
私人可牵引话筒;
私人浮动mPosX;
私家车;
ZoomRelativeLayout温度;
私有浮动mLastTouchX;
私密的浮躁和敏感;
private int mActivePointerId=无效的\u指针\u ID;
专用scalegestruedetector mScaleDetector;
私人浮动mScaleFactor=1.f;
公共ZoomRelativeLayout(上下文){
这个(上下文,null,0);
温度=这个;
}
公共ZoomRelativeLayout(上下文、属性集属性){
这(上下文,属性,0);
温度=这个;
}
公共ZoomRelativeLayout(上下文上下文、属性集属性、int-defStyle){
超级(上下文、属性、定义样式);
mIcon=context.getResources().getDrawable(R.drawable.shheildlogo);
setBounds(0,0,mIcon.getIntrinsicWidth(),mIcon.getIntrinsicHeight());
温度=这个;
mScaleDetector=新的scalegestruedetector(上下文,新的ScaleListener());
}
@凌驾
公共事件(MotionEvent ev){
//让scalegestruedetector检查所有事件。
mScaleDetector.onTouchEvent(ev);
final int action=ev.getAction();
开关(动作和动作事件.动作屏蔽){
case MotionEvent.ACTION\u DOWN:{
最终浮点数x=ev.getX();
最终浮动y=ev.getY();
mLastTouchX=x;
mLastTouchY=y;
MacTivePointId=ev.getPointerId(0);
打破
}
case MotionEvent.ACTION\u移动:{
final int pointerIndex=ev.findPointerIndex(mactivePointId);
最终浮动x=ev.getX(指针索引);
最终浮动y=ev.getY(指针索引);
//仅在ScaleGetureDetector未处理手势时移动。
如果(!mScaleDetector.isInProgress()){
最终浮点数dx=x-mLastTouchX;
最终浮子dy=y—最大浮子厚度;
mPosX+=dx;
mPosY+=dy;
使无效();
}
mLastTouchX=x;
mLastTouchY=y;
打破
}
case MotionEvent.ACTION\u UP:{
MacTivePointId=无效的\u指针\u ID;
打破
}
case MotionEvent.ACTION\u取消:{
MacTivePointId=无效的\u指针\u ID;
打破
}
case MotionEvent.ACTION\u指针\u向上:{
final int pointerIndex=(ev.getAction()&MotionEvent.ACTION\u指针\u索引\u掩码)
>>MotionEvent.ACTION\u指针\u索引\u移位;
final int pointerId=ev.getPointerId(pointerIndex);
if(pointerId==MacTivePointId){
//这是我们的活动指针上升。请选择一个新指针
//激活指针并进行相应调整。
final int newPointerIndex=pointerIndex==0?1:0;
mLastTouchX=ev.getX(newPointerIndex);
mLastTouchY=ev.getY(新指针索引);
MacTivePointId=ev.getPointerId(newPointerIndex);
}
打破
}
}
返回true;
}
@凌驾
仅受保护的void布局(布尔值已更改、int l、int t、int r、int b)
{
int count=getChildCount();
Log.d(“onLayout”,即“+”计数);

对于(int i=0;如果您没有添加代码,这意味着您还没有尝试过任何东西,请尝试和。