本文介绍了Android - 用展开/捏合放大/缩小RelativeLayout的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有 RelativeLayout 和一个私有类的活动,它扩展了 SimpleOnScaleGestureListener.在侦听器的 onScale 方法中,我想放大/缩小整个布局(用户看到的一切),用户张开/捏住他的手指.

I have an activity with a RelativeLayout and a private class in it, which extends the SimpleOnScaleGestureListener. In the onScale method of the listener I'd like to zoom in/out of the whole layout (everything the user sees) with the user spreading/pinching his fingers.

我希望布局的更改不是永久性的,即当展开/捏合手势结束时,我希望布局恢复到原来的状态(任何重置都可以在以SimpleOnScaleGestureListeneronScaleEnd 方法为例).

I'd like the changes to the layout NOT to be permanent, i.e. when the spread/pinch gesture is over I'd like the layout to go back to what it was in first place (any resetting could be done in the onScaleEnd method of the SimpleOnScaleGestureListener for example).

我尝试通过在 RelativeLayout 上调用 setScaleXsetScaleY 以及使用 ScaleAnimation 来实现它代码>.两者都没有导致平滑缩放(或任何可以称为缩放的东西).甚至可以放大/缩小 RelativeLayout 吗?

I've tried to implement it via calling setScaleX and setScaleY on the RelativeLayout and also by using a ScaleAnimation. Neither resulted in smooth zooming (or anything that could at all be called zooming). Is it even possible to zoom in/out a RelativeLayout?

我剩下的唯一想法是从缓存中读取屏幕截图并将其作为 ImageView 放在整个布局的顶部,并通过 setImageMatrix 放大/缩小该图像.但是,我不知道如何实现这一点.

The only idea I have left would be reading a screenshot from the cache and putting it as an ImageView on top of the whole layout and the zoom in/out of this image via setImageMatrix. I have no clue, however, how to implement this.

May 布局还包含一个片段容器,在应该可以进行缩放时该容器是空的.在 onScaleEnd 手势中,片段被放入它的容器(已经实现并且工作正常).这是我的布局:

May layout also contains a container for a fragment, which is empty at the time the zooming is supposed to be possible. In the onScaleEnd gesture, the fragment is put into it's container (already implemented and working fine). Here is my layout:

<?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"/>

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/tn_c7"/>

</LinearLayout>


<!-- Layout containing the dashed boxes -->
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="152dp"
    android:layout_centerVertical="true"
    android:orientation="horizontal" >

    <ImageView
        android:layout_width="177dp"
        android:layout_height="match_parent"
        android:layout_marginLeft="3dp"
        android:layout_marginRight="3dp"
        android:background="@drawable/dashed_box"/>

   <ImageView
        android:layout_width="177dp"
        android:layout_height="match_parent"
        android:layout_marginLeft="3dp"
        android:layout_marginRight="3dp"
        android:background="@drawable/dashed_box"/>

   <ImageView
        android:layout_width="177dp"
        android:layout_height="match_parent"
        android:layout_marginLeft="3dp"
        android:layout_marginRight="3dp"
        android:background="@drawable/dashed_box"/>

   <ImageView
        android:layout_width="177dp"
        android:layout_height="match_parent"
        android:layout_marginLeft="3dp"
        android:layout_marginRight="3dp"
        android:background="@drawable/dashed_box"/>

   <ImageView
        android:layout_width="177dp"
        android:layout_height="match_parent"
        android:layout_marginLeft="3dp"
        android:layout_marginRight="3dp"
        android:background="@drawable/dashed_box"/>

   <ImageView
        android:layout_width="177dp"
        android:layout_height="match_parent"
        android:layout_marginLeft="3dp"
        android:layout_marginRight="3dp"
        android:background="@drawable/dashed_box"/>

   <ImageView
        android:layout_width="177dp"
        android:layout_height="match_parent"
        android:layout_marginLeft="3dp"
        android:layout_marginRight="3dp"
        android:background="@drawable/dashed_box"/>

</LinearLayout>


<!-- Container for the fragments -->
<FrameLayout
    android:id="@+id/fragment_container_pui"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />


</RelativeLayout>

编辑我找到了这两个相关主题:
扩展RelativeLayout,并覆盖dispatchDraw()来创建可缩放视图组
在相对布局中缩放内容

EDITI found these two related topics:
Extending RelativeLayout, and overriding dispatchDraw() to create a zoomable ViewGroup
Zoom Content in a RelativeLayout

然而,我没有得到实现.我必须在扩展类中包含哪些其他方法才能实际缩放布局或重置布局?

I did not get the implementation, however. What other methods do I have to include in the extended class to actually scale the layout or reset it?

推荐答案

所以我创建了一个 RelativeLayout 的子类,如上述主题所述.它看起来像这样:

So I created a subclass of RelativeLayout as described in the above mentioned topics. It looks like this:

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 的实现如下所示:

My implementation of the SimpleOnScaleGestureListener looks like this:

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();
    }
}

希望这有帮助!

您可以使用 ScaleGestureDetector 为您的 ZoomableRelativelayout 集成 OnPinchListener:

You can integrate OnPinchListener for your ZoomableRelativelayout by using ScaleGestureDetector:

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

并且你需要绑定缩放布局的触摸监听器和ScaleGestureDetector的触摸监听器:

And you are required to bind touch listener of Zoomable layout with the touch listener of ScaleGestureDetector:

mZoomableLayout.setOnTouchListener(new OnTouchListener() {

                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    // TODO Auto-generated method stub
                    scaleGestureDetector.onTouchEvent(event);
                    return true;
                }
            });

这篇关于Android - 用展开/捏合放大/缩小RelativeLayout的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-21 10:04