2

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

1)。一个优秀的教程——多点触控的意义

2)。(SO链接)扩展RelativeLayout,并覆盖dispatchDraw()创建一个可缩放的ViewGroup

3)。(SO 链接)在自定义布局中滚动/平移或拖动

这是我的完整工作代码。

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 个图像视图(一个全屏图像视图和几个可点击的较小图像视图)。缩放和平移页面效果很好。

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

问题 2: 此外,似乎图像视图仅在绘图中平移/翻译,但实际上没有。因为当它们从屏幕上的原始位置移开时,它们不再可点击,并且可点击坐标仅局限于其原始位置。

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

所以与他们不同的是,我在 ZoomableRelativeLayout 中没有对我的图像视图的引用。引用 Imageview、读取位图和显示它们由其他类(MyPagerActivity 和 MyPagerFragment 类)负责。此外,上述链接中的解决方案依赖于矩阵转换,在我的情况下我可能无法使用。

期待在这方面的任何帮助。

谢谢。

4

3 回答 3

0

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

要确定应用哪些限制,您可以使用getWidth()and获取子视图的大小getHeight(),并将当前比例考虑在内。

于 2013-10-05T06:48:28.170 回答
0

对于问题 2,您必须调整所有 relativelayout 子级的画布矩形的大小。您应该在 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 的方法,这是我用于手指绘画的自定义视图。

于 2014-03-10T12:34:54.830 回答
0

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

记录 mClipBound.top、bottom、left、right 值我想出了以下硬编码值,这些值可能仅适用于 720x1280 和 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:在我上面的问题中提到。使用 mScaleFactor 对 onMeasure(..) 和 onLayout(..) 方法进行一些适当的调整可能会解决该问题。但我还不能让它工作。

于 2013-10-11T10:52:41.103 回答