我见过一些人问过如何一次性缩放整个ViewGroup(例如RelativeLayout).目前,这是我需要实现的目标.对我来说,最明显的方法是将缩放比例因子保持为某个变量; 并且在每个子视图的onDraw()方法中,该比例因子将在绘制图形之前应用于Canvas.
然而,在这之前,我试图聪明(哈 - 通常是一个坏主意)并将RelativeLayout扩展到一个名为ZoomableRelativeLayout的类中.我的想法是,任何比例转换只能在重写的dispatchDraw()函数中应用于Canvas,因此绝对不需要在任何子视图中单独应用缩放.
这是我在ZoomableRelativeLayout中所做的.它只是RelativeLayout的一个简单扩展,其中dispatchDraw()被覆盖:
protected void dispatchDraw(Canvas canvas){
canvas.save(Canvas.MATRIX_SAVE_FLAG);
canvas.scale(mScaleFactor, mScaleFactor);
super.dispatchDraw(canvas);
canvas.restore();
}
Run Code Online (Sandbox Code Playgroud)
mScaleFactor由同一类中的ScaleListener操作.
它确实有效.我可以捏缩放ZoomableRelativeLayout,并将所有视图保持在一起正确重新缩放.
除了有问题.其中一些子视图是动画的,因此我会定期对它们调用invalidate().当比例为1时,可以看到这些子视图定期重绘完全正常.当比例不是1时,这些动画子视图只能在其观看区域的一部分中更新 - 或者根本不会更新 - 具体取决于缩放比例.
我最初的想法是,当一个人子视图的无效()被调用,那么它可能被单独由系统重新绘制,而不是传递从父的RelativeLayout的dispatchDraw()画布,这意味着子视图最终刷新自己没有应用缩放比例.但奇怪的是,在屏幕上重绘的子视图的元素是正确的缩放比例.这几乎就好像系统决定在后备位图中实际更新的区域仍然未缩放 - 如果这有意义的话.换一种方式,如果我有一个动画儿童观和我逐渐成为1的初始规模进一步和进一步放大,如果我们把一个假想的地方发现孩子的看法是该区域时,缩放比例为1 ,然后调用invalidate()只会导致刷新该虚构框中的图形.但是,这被视为更新显卡都正在做正确的规模.如果放大到目前为止,子视图现在已经完全远离它的比例为1,那么它的任何部分都不会被刷新.我将举一个例子:想象我的孩子视图是一个通过在黄色和红色之间切换来动画的球.如果我放大一点使得球向右和向下移动,在某一点你只会看到球的左上角四分之一的颜色.
如果我不断放大和缩小,我会看到孩子正确完整地观看动画.这是因为正在重绘整个ViewGroup.
我希望这是有道理的; 我试图尽我所能解释.使用我的可缩放ViewGroup策略,我有点失败吗?还有另外一种方法吗?
谢谢,
崔佛
android android-layout android-relativelayout android-viewgroup