【问题标题】:Swap Android ViewGroup Child Colors in dispatchDraw在 dispatchDraw 中交换 Android ViewGroup 子颜色
【发布时间】:2015-10-19 19:40:30
【问题描述】:

我有一个 ViewGroup(特别是 FrameLayout),它应该有一个流体填充效果,我用一个路径设置了动画,可以很好地显示下面的子视图。

问题是在液体填充线上方,我需要向孩子展示两种颜色的视图反转。 (黑色白色)如果不简单地遍历位图,我看不到实现此目的的方法,这提供了一个非常糟糕的副本,有很多锯齿,并且渲染速度太慢。

这是我在 dispatchDraw 中当前功能的简化版本:

@Override
protected void dispatchDraw(Canvas canvas)
{
    filter.setXfermode(null);
    if (subBitmap == null || mLastWidth != mWidth) {
        subBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
        subCanvas = new Canvas(subBitmap);
    }
    super.dispatchDraw(subCanvas);
    if (mLiquidPaint == null || mLiquidPath == null || waveOval.size() == 0 || bitmapPixels == null || !mLiquidAnimator.isRunning()) {
        canvas.drawBitmap(subBitmap, 0, 0, filter);
        return;
    }

    if (revealBitmap == null || mLastWidth != mWidth) {
        revealBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
        revealCanvas = new Canvas(revealBitmap);
    }
    if (mLastWidth != mWidth) {
        calculateLiquid();
        mLastWidth = mWidth;
    }
    int yOffset = mFillOffset;
    int xOffset = ellipseWidth * -1;
    PointF firstPoint = new PointF();
    PointF lastPoint = new PointF();
    PointF nextPoint = new PointF();
    Pair<Integer, Float> nextWavePoint = wavePoints.get(0);
    PointF ovalPoint = waveOval.get((nextWavePoint.first + mWaveOffset) % waveOval.size());
    lastPoint.set(xOffset + nextWavePoint.second + ovalPoint.x, yOffset + ovalPoint.y);
    mLiquidPath.moveTo(lastPoint.x, lastPoint.y);
    firstPoint.set(lastPoint);
    for (int i = 1; i < wavePoints.size(); i++) {
        nextWavePoint = wavePoints.get(i);
        ovalPoint = waveOval.get((nextWavePoint.first + mWaveOffset) % waveOval.size());
        nextPoint.set(xOffset + nextWavePoint.second + ovalPoint.x, ovalPoint.y + yOffset);
        mLiquidPath.lineTo(nextPoint.x, nextPoint.y);
        lastPoint.set(nextPoint);
    }
    mLiquidPath.lineTo(getWidth(), lastPoint.y);
    mLiquidPath.lineTo(getWidth(), getHeight());
    mLiquidPath.lineTo(0, getHeight());
    mLiquidPath.lineTo(firstPoint.x, firstPoint.y);

    //This definitely draws a nice liquid path that fills from the bottom up.
    revealCanvas.drawPath(mLiquidPath, mLiquidPaint);
    //The next two lines successfully reveal the views underneath
    filter.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP));
    revealCanvas.drawBitmap(subBitmap, 0, 0, filter);

    filter.setXfermode(null);
    filter.setColorFilter(null);
    canvas.drawBitmap(revealBitmap, 0, 0, filter);
}

我尝试了无数种不同的 ColorFilters 和 Transfer Modes 都无济于事。而且孩子们不能让背景透明让我做更简单的颜色替换。

【问题讨论】:

    标签: android animation porter-duff colorfilter


    【解决方案1】:

    最终使用ColorMatrixColorFilter 弄清楚了,如下所述:

    对于color1color2 两种颜色,您可以将它们替换为以下ColorMatrix

    float[] colorSwapMatrix = new float[] {
        -1, 0, 0, 0, Color.red(color1) + Color.red(color2),    //Red
        0, -1, 0, 0, Color.green(color1) + Color.green(color2),//Green
        0, 0, -1, 0, Color.blue(color1) + Color.blue(color2),  //Blue
        0, 0, 0, 1f, 0                                         //Alpha
    }
    

    这是在绘制上面的波路径后应用的,如下所示:

        //Draw the swapped image above the wave
        filter.setColorFilter(new ColorMatrixColorFilter(colorSwapMatrix));
        filter.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT));
        revealCanvas.drawBitmap(subBitmap, 0, 0, filter);
    
        //Draw the regular image below the wave
        filter.setColorFilter(null);
        filter.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_ATOP));
        revealCanvas.drawBitmap(subBitmap, 0, 0, filter);
    
        //Draw the combined image onto the canvas
        filter.setXfermode(null);
        filter.setColorFilter(null);
        canvas.drawBitmap(revealBitmap, 0, 0, filter);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-09-17
      • 2015-09-12
      • 2011-09-16
      • 1970-01-01
      • 2021-12-28
      • 1970-01-01
      • 2013-08-01
      • 1970-01-01
      相关资源
      最近更新 更多