设置用于平移/拖动Zoomable自定义相对布局的边界限制

时间:2013-10-03 09:47:22

标签: android android-layout

我已经通过以下链接成功地在我的自定义相对布局中实现了缩放和平移/拖动功能。

1)。一个很好的教程 - making-sense-of-multitouch

2)。 (SO链接)Extending RelativeLayout, and overriding dispatchDraw() to create a zoomable ViewGroup

3)。 (SO链接)Scroll/Panning or drag in custom layout

这是我的完整工作代码。

https://gist.github.com/pandeyGitHub/6805840

我的layout.xml如下所示: -     

<com.myzoomproject.views.ZoomableRelativeLayout
    android:id="@+id/root_pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <com.myzoomproject.views.CustomViewPager
        android:id="@+id/pager_test2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</com.myzoomproject.views.ZoomableRelativeLayout>

我的自定义相对布局包含一个viewpager,我的viewpager中的每个页面都包含2-4个图像视图(一个全屏图像视图和一些可点击的较小的图像视图)。缩放&amp;平移页面效果很好。

问题1: 但不知何故,我无法为平移功能设置边界限制。在过度滚动时,页面将从屏幕上移开。

问题2: 此外,似乎图像视图仅在绘图中进行平移/翻译,但实际上并非如此。因为当它们离开屏幕上的原始位置时,它们不再可点击,&amp;可点击坐标仅限于其原始位置。

我在SO link 1link 2link 3上查找了几个类似的问题,但它们都是基于ImageView缩放而不是自定义布局缩放。

与他们不同,我在ZoomableRelativeLayout中没有对我的图像视图的引用。参考Imageviews,阅读位图和&amp;显示它们由其他类(MyPagerActivity和MyPagerFragment类)处理。此外,上述链接中的解决方案依赖于矩阵转换,在我的情况下我可能无法使用。

期待对此有任何帮助。

感谢。

3 个答案:

答案 0 :(得分:0)

您需要在mPosX&amp;上设置最小/最大限制。 mPosY个职位 - 在添加dx&amp;之后执行此操作dy

要确定要应用的限制,您可以使用getWidth()getHeight()获取子视图的大小,并计算当前比例。

答案 1 :(得分:0)

我以某种方式通过一些钩子找到了解决方法,这远非完美的解决方案,因为我不得不对某些值进行硬编码。我在现有代码中添加了以下代码片段,以设置平移边界限制。现在平移工作正常。

记录mClipBound.top,bottom,left,right值我提出了以下硬编码值,这些值可能仅适用于720x1280&amp; 800x1280设备。

case MotionEvent.ACTION_MOVE: {
    ...
    ...

    if (isPortraitMode) {
        if (mClipBound.top < 104 && dy > 0) //104 is a hard-coded value here.
           dy = 0;

        if (mClipBound.bottom > (screenHeight - 77) && dy < 0) // 77 - hardcoded
           dy = 0;
    } else {
        if (mClipBound.top < 0 && dy > 0)
            dy = 0;
        if (mClipBound.bottom > screenHeight && dy < 0)
        dy = 0;

    }

    if (mClipBound.left < 30 && dx > 0) // 30 - hardcoded
        dx = 0;

    if (mClipBound.right > screenWidth && dx < 0)
        dx = 0;

    mPosX += dx;
    mPosY += dy;
        ...
        ...
        ...
 }

 ...
 ...


 @Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int widthSize = MeasureSpec.getSize(widthMeasureSpec);
    int heightSize = MeasureSpec.getSize(heightMeasureSpec);
    screenWidth = widthSize;
    screenHeight = heightSize;
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    setMeasuredDimension((int) (widthSize), (int) (heightSize ));
 }

但我仍然无法解决上述问题中提到的问题2:。对onMeasure(..)&amp;的一些适当调整使用mScaleFactor的onLayout(..)方法可能会解决问题。但我还没有能够使它工作。

答案 2 :(得分:0)

对于问题2,您必须调整所有relativelayout孩子的画布rect的大小。您应该在scalegesturedetector的onScaleEnd方法中执行此操作。

public void resizeChildren() {

    int childCount = this.getChildCount();

    for (int i = 0; i < childCount; i++) {

        MyView child = (MyView)this.getChildAt(i);
        child.setScaleFactor(mScaleFactor);
        child.setCanvasRect(mRect);


    }

}

setScaleFactor()和setCanvasRect()是MyView的方法,它是我用于手指绘画的自定义视图。