【问题标题】:Drawing over a view and all it's children绘制视图及其所有子项
【发布时间】:2012-11-12 15:33:09
【问题描述】:

我正在尝试将视觉效果应用于视图组。我的想法是获取视图组的位图,将其缩小,将其展开,然后将其绘制在视图组上,使其具有块状、低质量的效果。

我已经使用此代码完成了大部分工作:

public class Blocker {

    private static final float RESAMPLE_QUALITY = 0.66f; // less than 1, lower = worse quality


    public static void block(Canvas canvas, Bitmap bitmap_old) {
        block(canvas, bitmap_old, RESAMPLE_QUALITY);
    }


    public static void block(Canvas canvas, Bitmap bitmap_old, float quality) {
        Bitmap bitmap_new = Bitmap.createScaledBitmap(bitmap_old, Math.round(bitmap_old.getWidth() * RESAMPLE_QUALITY), Math.round(bitmap_old.getHeight() * RESAMPLE_QUALITY), true);
        Rect from = new Rect(0, 0, bitmap_new.getWidth(), bitmap_new.getHeight());
        RectF to = new RectF(0, 0, bitmap_old.getWidth(), bitmap_old.getHeight());
        canvas.drawBitmap(bitmap_new, from, to, null);
    }
}

我只是传入要在画布上绘制的位图和需要按比例缩小+放大的位图,效果很好。

public class BlockedLinearLayout extends LinearLayout {

    private static final String TAG = BlockedLinearLayout.class.getSimpleName();


    public BlockedLinearLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        applyCustomAttributes(context, attrs);
        setup();
    }


    public BlockedLinearLayout(Context context) {
        super(context);
        setup();
    }


    private void setup() {
        this.setDrawingCacheEnabled(true);
    }


    @Override
    public void draw(Canvas canvas) {
        super.draw(canvas);
        // block(canvas); If I call this here, it works but no updates
    }


    @Override
    public void onDraw(Canvas canvas) {
        // block(canvas); If I call this here, draws behind children, still no updates
    }

    private void block(Canvas canvas) {
        Blocker.block(canvas, this.getDrawingCache());
    }
}

我遇到的问题是在我的视图组中。如果我在视图组的绘图中运行 block 方法,它会绘制所有内容,但不会在子视图更改时更新。我用 Log 跟踪了函数调用,draw 方法似乎正在运行,但没有任何变化。

我也尝试在 onDraw 中实现这一点。这会在所有子视图后面绘制位图,并且它们没有更新。

谁能解释我将如何解决这个问题?

【问题讨论】:

    标签: android android-canvas android-view


    【解决方案1】:

    试试这个:

    @Override
    protected void dispatchDraw(Canvas canvas) {
        // call block() here if you want to draw behind children
        super.dispatchDraw(canvas);
        // call block() here if you want to draw over children
    }
    

    每次更改孩子时调用 destroyDrawingCache() 然后 buildDrawingCache()。

    【讨论】:

    • 感谢您的建议。不幸的是,这适用于在所有孩子之上绘制,但如果孩子在初始绘制后更新,则视图不会更新。例如,我有一个线性布局,它有一个从 1 开始并每秒递增的单个 textview。我可以看到数字计数,但线性布局只是用 1 绘制,然后没有改变。
    • 尝试调用destroyDrawingCache(),然后在每次更改孩子时调用buildDrawingCache()。
    • 谢谢!这似乎工作得很好。我打算玩一下,但是您知道是否有任何方法可以从父视图中检测到子更改?我希望能够让父级自动处理所有子级的变化,而不是每次我做某事时明确告诉父级视图组重新缓存。
    • 嗯...我觉得你必须覆盖你孩子的 invalidate() 并通知 viewGroup 重新创建它的缓存。
    【解决方案2】:

    Draw() 方法很适合你。

    我现在正在尝试制作一个圆形的计数时间视图,当时间流逝时,视图会减小他的角度。用于覆盖头像(圆形照片)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-09-04
      • 1970-01-01
      • 2012-05-17
      • 1970-01-01
      • 2013-01-19
      • 1970-01-01
      • 2011-03-18
      相关资源
      最近更新 更多