【问题标题】:Android ViewGroup add child on top of all drawingsAndroid ViewGroup 在所有图纸之上添加子项
【发布时间】:2013-12-11 11:02:19
【问题描述】:

我有一个自定义的ViewGroup,我将覆盖它的dispatchDraw 并绘制一些额外的Paths,看起来像这样:

@Override
public void dispatchDraw(Canvas canvas) {
    super.dispatchDraw(canvas);
    canvas.setMatrix(matrix);
    mRegions.clear();
    canvas.drawPicture(mPicture);
    if (drawShader) {
        canvas.drawBitmap(mShader, 0, 0, mBitmapPaint);
    }
    for (int i = 0; i < mPaths.size(); i++) {
        if (mIndex != -1 && mIndex == i) {
            canvas.save();
            canvas.drawRect(mRect, mPaint);
            drawPaths(canvas, mPaths.get(i));
            canvas.clipPath(mPaths.get(i), Region.Op.INTERSECT);
            canvas.drawColor(mOverlayColor);
            Rect f = mRegions.get(i).getBounds();
            mPaint.setColor(Color.RED);
            mPaint.setStyle(Paint.Style.STROKE);
            canvas.drawCircle(f.centerX() - mRadius, f.centerY() - mRadius, mRadius, mPaint);
            canvas.restore();
        } else {
            drawPaths(canvas, mPaths.get(i));
        }
    }
}

现在我想要添加一个孩子,该孩子将放置在dispatchDraw 上绘制的这些东西之上。现在我正在这样做:

    mBalloon = LayoutInflater.from(getContext()).inflate(R.layout.map_balloon, null);
    LayoutParams params = new LayoutParams(500, 150);
    mBalloon.setLayoutParams(params);
    addView(mBalloon);
    bringChildToFront(getChildAt(0));

在我的ViewGroup 的构造函数中调用的init() 方法中,结果是dispatchDraw 中的绘图被放置在mBalloon 之上。

知道如何将我的View - mBalloon 放在来自dispatchDraw 的东西上方吗?

提前致谢!

【问题讨论】:

  • 您是否尝试在自定义绘图后调用 drawChild?

标签: android android-view viewgroup


【解决方案1】:

要在您的额外Path 之上绘制孩子,您应该在绘制Path 之后调用super.dispatchDraw(canvas)

@Override
public void dispatchDraw(Canvas canvas) {
    canvas.setMatrix(matrix);
    mRegions.clear();
    canvas.drawPicture(mPicture);
    if (drawShader) {
        canvas.drawBitmap(mShader, 0, 0, mBitmapPaint);
    }
    for (int i = 0; i < mPaths.size(); i++) {
        if (mIndex != -1 && mIndex == i) {
            canvas.save();
            canvas.drawRect(mRect, mPaint);
            drawPaths(canvas, mPaths.get(i));
            canvas.clipPath(mPaths.get(i), Region.Op.INTERSECT);
            canvas.drawColor(mOverlayColor);
            Rect f = mRegions.get(i).getBounds();
            mPaint.setColor(Color.RED);
            mPaint.setStyle(Paint.Style.STROKE);
            canvas.drawCircle(f.centerX() - mRadius, f.centerY() - mRadius, mRadius, mPaint);
            canvas.restore();
        } else {
            drawPaths(canvas, mPaths.get(i));
        }
    }
    super.dispatchDraw(canvas);
}

【讨论】:

    【解决方案2】:

    我了解您想要达到的目标的总体思路,我会尝试提出不同的方法。

    来自文档:A ViewGroup is a special view that can contain other views (called children.) The view group is the base class for layouts and views containers.

    所以 ViewGroup 根本不应该在屏幕上绘制东西。有可能做到吗?是的,但这只会让你的 OO 结构做得不太好。

    所以我的建议是使用您喜欢的任何 ViewGroup FrameLayout、RelativeLayout 等。并将路径绘制代码迁移到将在屏幕上绘制所有这些路径的自定义 View,并且在标准 ViewGroup 中您只需定位相应地自定义视图。大概是这样的:

    <RelativeLayout>
    
        <TextView/> // just an example
        <ImageView/> // just an example
    
        <CustomPathView/> // your custom view
    
        <FrameLayout/>  // in this frame you can put views to be on top
    </RelativeLayout>
    

    【讨论】:

    • 我这样做只是因为我需要根据所选路径更新mBalloon的位置,并在我在ViewGroup中移动路径时移动它。
    • 我理解并且您的 CustomChild 总是可以通过接口等方式从 CustomViewGroups(不绘制任何东西)接收回调。其他选项是在 super.dispatchDraw 期间绘制所有子视图,所以你必须检查源代码并自己重新实现。
    • 调用drawChild()super.dispatchDraw(),毕竟所有的图纸几乎都成功了,但不是我想要的。所以将我的ViewGroup 更改为View,将其添加到RelativeLayout 并在Fragment 之间创建连接,通过interface 保存我的View 就可以了,所以谢谢@Budius 的回答!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多