Java Android ViewGroup.setScaleX()导致视图被剪裁
我使用库来缩放自定义布局Java Android ViewGroup.setScaleX()导致视图被剪裁,java,android,zooming,scale,viewgroup,Java,Android,Zooming,Scale,Viewgroup,我使用库来缩放自定义布局 public class MyLayout extends FrameLayout { // LayoutParams.MATCH_PARENT and all. ... @Override public boolean setPositionAndScale(ViewGroup v, PositionAndScale pas, PointInfo pi) { ... mScale = pas.getScale(); ViewHe
public class MyLayout extends FrameLayout {
// LayoutParams.MATCH_PARENT and all.
...
@Override
public boolean setPositionAndScale(ViewGroup v, PositionAndScale pas, PointInfo pi) {
...
mScale = pas.getScale();
ViewHelper.setScaleX(this, mScale);
ViewHelper.setScaleY(this, mScale);
}
}
我试过FrameLayout和AbsoluteLayout。所有这些都有相同的效果。
当mScale<1.0
缩放/缩放工作时但部分版面被剪裁
mScale=1.0:
mScale<1.0:
缩放/缩放有效但布局被剪裁如何解决此问题
编辑:这张照片是在ICS上拍摄的。因此,我认为这不是NineodelDroids的问题。如果我正确理解了您的问题,您正在缩放视图组,并期望包含的视图能够相应地缩放。它不是这样工作的:您缩放视图组,它会更改大小,但其子视图不会
只需缩放所有子视图。即便如此,我也不确定文本和图像是否会自动缩放。你想要的是缩放,而不是缩放。请尝试。自API级别11以来,
视图
类具有setScaleX()
和setScaleY()
方法,这些方法按预期工作,还可以缩放缩放视图的子视图。所以,如果这对你来说是一种方式,放下图书馆去做吧
v.setScaleX(mScale);
v.setScaleY(mScale);
以防有人遇到和我一样的情况。 我最终采用了这种方法:
protected void setScale(float scale, boolean updateView) {
mScale = scale;
if (updateView) {
LayoutParams params = getLayoutParams();
onUpdateScale(scale, params);
setLayoutParams(params);
}
}
protected void onUpdateScale(float scale, LayoutParams params) {
params.leftMargin = (int) (mModel.getX() * scale);
params.topMargin = (int) (mModel.getY() * scale);
params.width = (int) (mModel.getWidth() * scale);
params.height = (int) (mModel.getHeight() * scale);
}
使用ViewGroup.layout。这可能是缩放(移动)视图组的最简单方法。视图的父视图必须禁用属性
android:clipChildren
(从布局文件或使用setClipChildren(false)
)
但是使用这种方法,您不会获得视图剪辑边界之外的触摸事件。您可以通过从活动中发送它们或编写自定义的ViewGroup
parent来解决问题
我使用的是另一种方法,在我的例子中似乎有效,诀窍是维护您自己的转换矩阵。然后,您必须重载大量的ViewGroup
方法才能使其工作。例如:
@Override
protected void dispatchDraw(Canvas canvas) {
Log.d(TAG, "dispatchDraw " + canvas);
canvas.save();
canvas.concat(mMatrix);
super.dispatchDraw(canvas);
canvas.restore();
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
Log.d(TAG, "dispatchTouchEvent " + ev);
ev.transform(getInvMatrix()); //
return super.dispatchTouchEvent(ev);
}
private Matrix getInvMatrix()
{
if(!mTmpMatIsInvMat)
mMatrix.invert(mTmpMat);
mTmpMatIsInvMat = true;
return mTmpMat;
}
您希望输出是什么样子的?类似于MapView。布局(
MyLayout
)填充整个屏幕,而不是像2中那样剪裁。照片。MyLayout的LayoutParam设置为匹配父项。缩放和缩放之间的区别是什么?图2显示了缩放的工作原理(mScale~0.8)。只是视图组被剪裁了。我放弃了我的答案,对不起,太吵了。我以前试过。它具有相同的剪裁效果。实际上,库只是一个代理。在ICS上,Nineodeldroid只调用相同的方法。这种方法快吗?我的意思是,你是在用手势来缩放更新太多,还是一次只缩放一次?我还没有运行基准测试或traceview,但它在Xoom 1和Nexus S上运行得很好。要求是移动和缩放需要持续进行(如谷歌地图),而不是在交互结束后(比如缩放OSMTracker)。所以,没有闪烁?(+1,如果您回答否:-)不幸的是,它有时会闪烁(仅缩放)。如果您解决了这个问题,请在此处添加另一个答案:)您可以从视图中获取矩阵。view.getMatrix()然后将其反转,m.invert(m)并使用它来缩放运动事件。我尝试了一些不同的方法,从假视图复制原始触摸,然后通过视图矩阵进行转换。在我能接触到的所有硬件上,唯一能保持一致工作的就是维护我自己的矩阵,并使用它来转换运动事件、视图和无效矩形。