我对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,computeHorizontalScrollRange,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布局会再次以适当的大小对齐。
如果有人有更好的解决方案,我将很乐意让步。
还要感谢神秘的恩人,这使我的问题:)