我对TwoDScrollView布局有问题。缩放其子级后,TwoDScrollView的垂直和水平滚动范围保持不变。

这是XML代码:

<com.fine.example.TwoDScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/scrolling"
    android:drawingCacheQuality="low"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <RelativeLayout
        android:id="@+id/board"
        android:clipChildren="false"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:drawingCacheQuality="low"
        android:layout_marginTop="?android:attr/actionBarSize"
        android:layout_marginBottom="?android:attr/actionBarSize"
        android:paddingTop="@dimen/padmargsmedium"
        android:paddingBottom="?android:attr/actionBarSize"
        android:paddingLeft="@dimen/padmarg"
        android:paddingRight="@dimen/padmarg" >

        <RelativeLayout
            android:id="@+id/boardf"
            android:drawingCacheQuality="low"
            android:layout_width="match_parent"
            android:layout_height="match_parent" >

        </RelativeLayout>

    </RelativeLayout>

</com.fine.example.TwoDScrollView>


这就是我缩放childView的方式:

scale -= 0.25f;      // or scale += 0.25f;
board.setPivotX(0.5f/scale);
board.setPivotY(0.5f/scale);
board.setScaleX(1f/scale);
board.setScaleY(1f/scale);


实际上,通过执行以下操作,我设法解决了“放大”问题:

TwoDScrollView.LayoutParams params = (TwoDScrollView.LayoutParams) board.getLayoutParams();
params.width = (int) (xwidth/scale);
params.height = (int) (yheight/scale);
board.setLayoutParams(params);


但是对于“缩小”,相同的代码不起作用。子项的大小发生变化,但是ScrollView不会更新其容器大小,滚动的方式超出了所需的大小,同时在scrollview及其缩放的子项之间显示了一个空白空间。

您可以在此处找到TwoDScrollView源(由Matt Clark):

https://web.archive.org/web/20121125032032/http://blog.gorges.us/2010/06/android-two-dimensional-scrollview/comment-page-1/#comments

我尝试过的事情:


将TwoDScrollView替换为ScrollView并设置fillViewPort =“ true”,但是会发生同样的情况。
在两种布局以及每种可能的组合中,将layout_width和layout_height更改为WRAP_CONTENT或MATCH_PARENT。
与invalidate()和requestLayout()相同。
将“可见性”设置为“消失”,然后再设置为“可见”,如此处所述:ScrollView does not resize directly after child changes
我什至尝试在这些TwoDScrollView方法中强制缩放:computeVerticalScrollRange,computeHorizo​​ntalScrollRange,measureChild,measureChildWithMargins和computeScroll,但没有结果。
搜索stackoverflow:有一些像我的问题,但是当有答案时,可惜它对我不起作用。


我怎样才能解决这个问题?任何帮助将非常感激!

最佳答案

最终,我发现缩小部分的解决方案肮脏。不是最优的,但是,它有效。

在TwoDScrollView.java中,更改以下三种方法:

@Override
protected float getBottomFadingEdgeStrength() {
    if (getChildCount() == 0) {
        return 0.0f;
    }
    final int length = getVerticalFadingEdgeLength();
    final int bottomEdge = getHeight() - getPaddingBottom();
    final int span = (int) (getChildAt(0).getBottom()/scale) - getScrollY() - bottomEdge;
    if (span < length) {
        return span / (float) length;
    }
    return 1.0f;
}

@Override
protected float getRightFadingEdgeStrength() {
    if (getChildCount() == 0) {
        return 0.0f;
    }
    final int length = getHorizontalFadingEdgeLength();
    final int rightEdge = getWidth() - getPaddingRight();
    final int span = (int) (getChildAt(0).getRight()/scale) - getScrollX() - rightEdge;
    if (span < length) {
        return span / (float) length;
    }
    return 1.0f;
}

@Override
public void computeScroll() {
    if (mScroller.computeScrollOffset()) {
        int oldX = getScrollX();
        int oldY = getScrollY();
        int x = mScroller.getCurrX();
        int y = mScroller.getCurrY();
        if (getChildCount() > 0) {
            View child = getChildAt(0);
            scrollTo(clamp(x, getWidth() - getPaddingRight() - getPaddingLeft(), (int) (child.getWidth() / scale)),
                    clamp(y, getHeight() + getPaddingBottom() - getPaddingTop(), (int) ((child.getHeight() + child.getPaddingBottom()) / scale)));
        } else {
            scrollTo(x, y);
        }
        if (oldX != getScrollX() || oldY != getScrollY()) {
            onScrollChanged(getScrollX(), getScrollY(), oldX, oldY);
        }
        postInvalidate();
    }
}


另外,值得注意的是,我正在使用James McMurray在Gorges.blog上建议的measureChildWithMargins(),如果有帮助的话。

@Override
protected void measureChildWithMargins(View child, int parentWidthMeasureSpec, int widthUsed, int parentHeightMeasureSpec, int heightUsed) {
    final MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();

    int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(lp.leftMargin + lp.rightMargin, MeasureSpec.UNSPECIFIED);
    int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(lp.topMargin + lp.bottomMargin, MeasureSpec.UNSPECIFIED);

    child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
}


因此,现在scrollview父级将其范围限制为按比例缩小子级。可以将其拉出限制,但在发布时,scrollview布局会再次以适当的大小对齐。

如果有人有更好的解决方案,我将很乐意让步。

还要感谢神秘的恩人,这使我的问题:)

09-11 17:20