Android - 运行时缩放视图组(布局)

8
我有一堆瓷砖组成了单个图像,按请求渲染(根据屏幕上可见的总图像部分)。合成图像比屏幕大得多。每个瓷砖都紧密地与相邻的瓷砖相邻,以创建单个图像的错觉(如果不使用平铺,则单个图像将太大并且会出现OOM错误)。
这些是FrameLayout中的ImageViews,通过top/leftMargin定位。
目标API 2.2 / SDK 8
我正在尝试响应用户事件(按钮按下,捏等)缩放总图像。
显然,setScale直到API 11才可用。我尝试在setWillNotDraw(false)的FrameLayout的onDraw中使用canvas.scale,并且正在调用onDraw,但没有应用缩放(我认为因为布局本身没有任何图形信息?我原以为它也会呈现其子代,但我想除非我在这里做错了,否则不会)。
我想我可以遍历每个瓷砖并独立缩放它,但每次还需要重新定位每个瓷砖。
我必须想到一种方法来缩放父View(ViewGroup?),以便其所有子项也被缩放(就像其他管理GUI的语言一样)。 我错过了什么?
谢谢
1个回答

10

供参考,上述提到的方法(使用父ViewGroup的onDraw)确实可行。我之前在变换前使用了canvas.save(),并在变换后使用了canvas.restore()(基于一些示例),但这是错误的。

以下是一个通用的FrameLayout子类,它将缩放其子项。

package com.whatever.layouts;

import android.content.Context;
import android.graphics.Canvas;
import android.widget.FrameLayout;

public class ScalingFrameLayout extends FrameLayout {

    private float scale = 1;

    public ScalingFrameLayout(Context context) {
        super(context);
        setWillNotDraw(false);
    }

    public void setScale(float factor){
        scale = factor;
        invalidate();
    }
    public float getScale(){
        return scale;
    }

    @Override
    public void onDraw(Canvas canvas){
        canvas.scale(scale, scale);
        super.onDraw(canvas);
    }

}

哇,这真是大开眼界,谢谢!但我想这很有道理(知道答案后得出结论更容易;)). 我们不想保存和恢复画布到其先前的状态,因为那就是我们想要的变化,直接在同一层上进行。再次感谢 :) - aMiGo
关于canvas.save()和canvas.restore(),我一直在做同样的事情。而且没有它们也可以工作。那么你能告诉我为什么在Android开发页面中他们要放这些代码吗? - AsafK
1
@AsafK 我不知道。 - momo
太棒了!这是自动缩放“View Group”类型的最佳解决方案。 - Huy Tower
@AsafK 只是为了澄清一下:意图是您执行 canvas.save(); 然后 canvas.scale(scale, scale);,然后进行任何所需的绘制操作,最后执行 canvas.restore();。这样,只有您想要受到影响的绘制操作才会受到变换的影响。例如,如果超类或父类打算在画布上进行进一步的绘制,则不会无意中泄漏比例操作。在 save 和 restore 之间进行的绘制会受到比例的影响,调用 restore 不会对此产生反向作用,只会对之后的绘制产生影响。 - Arild

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接