为了账号安全,请及时绑定邮箱和手机立即绑定

Android-使用展开/捏放大/缩小RelativeLayout

Android-使用展开/捏放大/缩小RelativeLayout

江户川乱折腾 2019-10-29 11:05:41
我有一个包含RelativeLayout和的私有类的活动,该活动扩展了SimpleOnScaleGestureListener。在onScale听众的方法中,我想通过用户展开/捏手指来放大/缩小整个布局(用户看到的一切)。我想改变的布局不被永久的,即当病毒/捏合手势是在我想的布局回去这是什么在首位(任何复位可能在做onScaleEnd的方法SimpleOnScaleGestureListener例如)。我试图通过调用setScaleX和setScaleY在上RelativeLayout以及还使用来实现它ScaleAnimation。两者均不会导致平滑缩放(或任何可能被称为缩放的东西)。甚至可以放大/缩小RelativeLayout?我剩下的唯一想法是从缓存中读取屏幕截图,并将其作为ImageView整个布局的顶部,并通过放大/缩小此图像setImageMatrix。但是,我不知道如何实现这一点。May布局还包含一个片段的容器,在应该进行缩放时该片段为空。通过该onScaleEnd手势,将片段放入其容器中(已经实现并且可以正常工作)。这是我的布局:<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/layout_pinch"android:layout_width="match_parent"android:layout_height="match_parent"android:background="#ffffff" >   <!-- Layout containing the thumbnail ImageViews --><LinearLayout    android:id="@+id/thumbnail_group_pui"    android:layout_width="match_parent"    android:layout_height="wrap_content"    android:layout_centerVertical="true"    android:orientation="horizontal" >    <ImageView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:background="@drawable/tn_c1"/>    <ImageView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:background="@drawable/tn_c2"/>    <ImageView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:background="@drawable/tn_c3"/>    <ImageView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:background="@drawable/tn_c4"/>    <ImageView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:background="@drawable/tn_c5"/>    <ImageView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:background="@drawable/tn_c6"/></LinearLayout>我没有实。我必须在扩展类中包括哪些其他方法来实际缩放布局或重置布局?
查看完整描述

3 回答

?
慕侠2389804

TA贡献1719条经验 获得超6个赞

因此,我创建了RelativeLayout上述主题中所述的的子类。看起来像这样:


public class ZoomableRelativeLayout extends RelativeLayout {

float mScaleFactor = 1;

float mPivotX;

float mPivotY;


public ZoomableRelativeLayout(Context context) {

    super(context);

    // TODO Auto-generated constructor stub

}


public ZoomableRelativeLayout(Context context, AttributeSet attrs) {

    super(context, attrs);

    // TODO Auto-generated constructor stub

}


public ZoomableRelativeLayout(Context context, AttributeSet attrs,

        int defStyle) {

    super(context, attrs, defStyle);

    // TODO Auto-generated constructor stub

}


protected void dispatchDraw(Canvas canvas) {

    canvas.save(Canvas.MATRIX_SAVE_FLAG);

    canvas.scale(mScaleFactor, mScaleFactor, mPivotX, mPivotY);

    super.dispatchDraw(canvas);

    canvas.restore();

}


public void scale(float scaleFactor, float pivotX, float pivotY) {

    mScaleFactor = scaleFactor;

    mPivotX = pivotX;

    mPivotY = pivotY;

    this.invalidate();

}


public void restore() {

    mScaleFactor = 1;

    this.invalidate();

}


}

我对SimpleOnScaleGestureListener外观的实现如下所示:


private class OnPinchListener extends SimpleOnScaleGestureListener {


    float startingSpan; 

    float endSpan;

    float startFocusX;

    float startFocusY;



    public boolean onScaleBegin(ScaleGestureDetector detector) {

        startingSpan = detector.getCurrentSpan();

        startFocusX = detector.getFocusX();

        startFocusY = detector.getFocusY();

        return true;

    }



    public boolean onScale(ScaleGestureDetector detector) {

        mZoomableRelativeLayout.scale(detector.getCurrentSpan()/startingSpan, startFocusX, startFocusY);

        return true;

    }


    public void onScaleEnd(ScaleGestureDetector detector) {

        mZoomableRelativeLayout.restore();

    }

}

希望这可以帮助!


更新:

您可以整合OnPinchListener你的ZoomableRelativelayout使用ScaleGestureDetector:


ScaleGestureDetector scaleGestureDetector = new ScaleGestureDetector(this, new OnPinchListener());

并且您需要将Zoomable布局的触摸侦听器与ScaleGestureDetector的触摸侦听器绑定:


mZoomableLayout.setOnTouchListener(new OnTouchListener() {


                @Override

                public boolean onTouch(View v, MotionEvent event) {

                    // TODO Auto-generated method stub

                    scaleGestureDetector.onTouchEvent(event);

                    return true;

                }

            });


查看完整回答
反对 回复 2019-10-29
?
波斯汪

TA贡献1811条经验 获得超4个赞

我认为我设法提高了Schnodahipfe的答案。我向ZoomableRelativeLayout类添加了两个方法。


public void relativeScale(float scaleFactor, float pivotX, float pivotY)

{

    mScaleFactor *= scaleFactor;


    if(scaleFactor >= 1)

    {

        mPivotX = mPivotX + (pivotX - mPivotX) * (1 - 1 / scaleFactor);

        mPivotY = mPivotY + (pivotY - mPivotY) * (1 - 1 / scaleFactor);

    }

    else

    {

        pivotX = getWidth()/2;

        pivotY = getHeight()/2;


        mPivotX = mPivotX + (pivotX - mPivotX) * (1 - scaleFactor);

        mPivotY = mPivotY + (pivotY - mPivotY) * (1 - scaleFactor);

    }


    this.invalidate();

}


public void release()

{

    if(mScaleFactor < MIN_SCALE)

    {

        final float startScaleFactor = mScaleFactor;


        Animation a = new Animation()

        {

            @Override

            protected void applyTransformation(float interpolatedTime, Transformation t)

            {

                scale(startScaleFactor + (MIN_SCALE - startScaleFactor)*interpolatedTime,mPivotX,mPivotY);

            }

        };


        a.setDuration(300);

        startAnimation(a);

    }

    else if(mScaleFactor > MAX_SCALE)

    {

        final float startScaleFactor = mScaleFactor;


        Animation a = new Animation()

        {

            @Override

            protected void applyTransformation(float interpolatedTime, Transformation t)

            {

                scale(startScaleFactor + (MAX_SCALE - startScaleFactor)*interpolatedTime,mPivotX,mPivotY);

            }

        };


        a.setDuration(300);

        startAnimation(a);

    }

}

并像这样重写OnPinchListener类


private class OnPinchListener extends ScaleGestureDetector.SimpleOnScaleGestureListener

{

    float currentSpan;

    float startFocusX;

    float startFocusY;


    public boolean onScaleBegin(ScaleGestureDetector detector)

    {

        currentSpan = detector.getCurrentSpan();

        startFocusX = detector.getFocusX();

        startFocusY = detector.getFocusY();

        return true;

    }


    public boolean onScale(ScaleGestureDetector detector)

    {

        ZoomableRelativeLayout zoomableRelativeLayout= (ZoomableRelativeLayout) ImageFullScreenActivity.this.findViewById(R.id.imageWrapper);


        zoomableRelativeLayout.relativeScale(detector.getCurrentSpan() / currentSpan, startFocusX, startFocusY);


        currentSpan = detector.getCurrentSpan();


        return true;

    }


    public void onScaleEnd(ScaleGestureDetector detector)

    {

        ZoomableRelativeLayout zoomableRelativeLayout= (ZoomableRelativeLayout) ImageFullScreenActivity.this.findViewById(R.id.imageWrapper);


        zoomableRelativeLayout.release();

    }

}

每次触摸事件结束时,原始答案都会重置比例,但是像这样,您可以放大和缩小多次。


查看完整回答
反对 回复 2019-10-29
  • 3 回答
  • 0 关注
  • 1090 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信