Android ColorPicker显示为黑色而不是彩色

时间:2014-09-18 13:55:12

标签: android android-canvas android-view

我想在我开发的应用程序中的活动上添加colorpicker。我不会用对话框。它将取决于活动的内容。当我触摸颜色选择器圆的表面时,它将返回RGB十六进制值。

无论如何,下面有一些代码可以满足我提到的需求。当我在Android 4.4.2上使用manifest.xml上的android:minSdkVersion =“9”运行应用程序时,我可以清楚地看到圆圈。但是,当我在manifest.xml上运行应用程序 - android:minSdkVersion =“14”时,黑色和白色(大多数是黑色)颜色选择器圆圈显示在活动而不是彩色圆圈上。当我触摸圆圈时,它返回正确的值,如彩色圆圈,这也很奇怪。对于前者当我触摸黑色时,它返回0XFF000000(红色)。

我的错在哪里?我该怎么处理?求你帮帮我。

layout xml;

...
 <com.(package name).ColourPicker
        android:id="@+id/colourPick"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
...

java class;

public class ColourPicker extends View {
    private static final float PI = 3.1415926f;

    private int[] mCoord;
    private float[] mHSV;

    private MainActivity ourContext;

    private static int CENTER_X;
    private static int CENTER_Y;
    private static int HUE_RADIUS;
    private static int INNER_RADIUS;
    private static int PALETTE_RADIUS;

    private static int SAT_RADIUS;

    public boolean colourKnown = false;

    int[] mSpectrumColorsRev = new int[] { 0xFFFF0000, 0xFFFF00FF, 0xFF0000FF,
            0xFF00FFFF, 0xFF00FF00, 0xFFFFFF00, 0xFFFF0000, };

    Paint mOvalHue;
    Paint mOvalHueInner;

    Paint mOvalSat;
    RectF mRectSat;
    Paint mArcSat;
    Paint mPaintSatTextRect;
    Paint mPaintSatText;

    Paint mPosMarker;
    RectF posMarkerRect1;
    RectF posMarkerRect2;

    Shader shaderA;
    Shader shaderB;
    Shader shaderHue;

    Shader shaderSat;

    public ColourPicker(Context context, AttributeSet attr) {
        super(context, attr);

        ourContext = (MainActivity) context;

        DisplayMetrics metrics = new DisplayMetrics();
        WindowManager wm = (WindowManager) context
                .getSystemService(Context.WINDOW_SERVICE);
        wm.getDefaultDisplay().getMetrics(metrics);

        double scalefactor;

        if (metrics.widthPixels < metrics.heightPixels) {
            scalefactor = 2.5;
        } else {
            scalefactor = 5.5;
        }

        CENTER_X = (int) (1 * (metrics.widthPixels / scalefactor));// (metrics.heightPixels
                                                                    // / 2);
        CENTER_Y = (int) (1 * (metrics.widthPixels / scalefactor));// (metrics.heightPixels
                                                                    // / 2);
        HUE_RADIUS = (int) (1 * (metrics.widthPixels / scalefactor));// (metrics.heightPixels
                                                                        // / 6)
                                                                        // -
                                                                        // (metrics.heightPixels
                                                                        // /
                                                                        // 45);
                                                                        // //110;
        INNER_RADIUS = (int) (0.63 * (metrics.widthPixels / scalefactor));// (metrics.heightPixels
                                                                            // /
                                                                            // 10.5);
                                                                            // //70;
        PALETTE_RADIUS = (int) (1 * (metrics.widthPixels / scalefactor));// (metrics.heightPixels
                                                                            // /
                                                                            // 6)
                                                                            // -
                                                                            // (metrics.heightPixels
                                                                            // /
                                                                            // 45);
                                                                            // //110;;
        SAT_RADIUS = (int) (0.60 * (metrics.widthPixels / scalefactor));// (metrics.heightPixels
                                                                        // /
                                                                        // 10.5)
                                                                        // -5;
                                                                        // //65;*/

        mOvalHue = new Paint(Paint.ANTI_ALIAS_FLAG);
        mOvalHueInner = new Paint(Paint.ANTI_ALIAS_FLAG);

        mOvalSat = new Paint(Paint.ANTI_ALIAS_FLAG);
        mRectSat = new RectF(-SAT_RADIUS, -SAT_RADIUS, SAT_RADIUS, SAT_RADIUS);
        mArcSat = new Paint();

        mPosMarker = new Paint(Paint.ANTI_ALIAS_FLAG);

        shaderA = new SweepGradient(0, 0, mSpectrumColorsRev, null);
        shaderB = new RadialGradient(CENTER_X, CENTER_Y, HUE_RADIUS,
                0xFFFFFFFF, 0xFF000000, Shader.TileMode.CLAMP);
        shaderHue = new ComposeShader(shaderA, shaderB, PorterDuff.Mode.SCREEN);

        shaderSat = new RadialGradient(CENTER_X, CENTER_Y, SAT_RADIUS,
                0xFF888888, 0xFFFFFFFF, Shader.TileMode.CLAMP);

        // InitialisePaints Paints
        mOvalHue.setShader(shaderHue);
        mOvalHue.setStyle(Paint.Style.FILL);
        mOvalHue.setDither(true);

        mOvalSat.setShader(shaderSat);
        mOvalSat.setStyle(Paint.Style.FILL);
        mOvalSat.setDither(true);
        mOvalSat.setColor(0xFFFFFFFF);

        mArcSat.setAntiAlias(true);
        mArcSat.setStyle(Paint.Style.FILL);
        mArcSat.setColor(0xFFFFFFFF);

        mPosMarker.setStyle(Paint.Style.STROKE);
        mPosMarker.setStrokeWidth(2);

        mPaintSatTextRect = new Paint();
        mPaintSatTextRect.setAntiAlias(true);
        mPaintSatTextRect.setStyle(Paint.Style.FILL);
        mPaintSatTextRect.setColor(0XFF000000);

        mPaintSatText = new Paint();
        mPaintSatText.setAntiAlias(true);
        mPaintSatText.setStyle(Paint.Style.FILL);
        mPaintSatText.setColor(0xFFFFFFFF);
        mPaintSatText.setTextSize(25);

        mCoord = new int[2];
        mHSV = new float[3];
        mHSV[1] = 1;

        posMarkerRect1 = new RectF(mCoord[0] - 5, mCoord[1] - 5, mCoord[0] + 5,
                mCoord[1] + 5);
        posMarkerRect2 = new RectF(mCoord[0] - 3, mCoord[1] - 3, mCoord[0] + 3,
                mCoord[1] + 3);
    }

    @Override
    protected void onDraw(Canvas canvas) {

        canvas.translate(CENTER_X, CENTER_Y);

        canvas.drawCircle(0, 0, HUE_RADIUS, mOvalHue);
        canvas.drawCircle(0, 0, INNER_RADIUS, mOvalHueInner);

        // Sat up
        canvas.drawArc(mRectSat, (float) 182, (float) 176, true, mOvalSat);
        canvas.drawArc(mRectSat, (float) 182, (float) 176, true, mArcSat);

        // Sat down
        canvas.drawArc(mRectSat, (float) 2, (float) 176, true, mOvalSat);
        canvas.drawArc(mRectSat, (float) 2, (float) 176, true, mArcSat);

        canvas.drawRect(-(SAT_RADIUS - 10), 15, (SAT_RADIUS - 10), -15,
                mPaintSatTextRect);

        mPaintSatText.setColor(0xFFFFFFFF);
        mPaintSatText.setTextSize(25);
        String satStr = "Saturation";
        canvas.drawText(satStr, -60, 8, mPaintSatText);

        mPaintSatText.setTextSize(35);
        mPaintSatText.setColor(0xFF000000);
        satStr = "+";
        canvas.drawText(satStr, -8, -30, mPaintSatText);
        satStr = "-";
        canvas.drawText(satStr, -8, 50, mPaintSatText);

        if (colourKnown) {
            posMarkerRect1.set(mCoord[0] - 5, mCoord[1] - 5, mCoord[0] + 5,
                    mCoord[1] + 5);
            posMarkerRect2.set(mCoord[0] - 3, mCoord[1] - 3, mCoord[0] + 3,
                    mCoord[1] + 3);

            mPosMarker.setColor(Color.BLACK);
            canvas.drawOval(posMarkerRect1, mPosMarker);
            mPosMarker.setColor(Color.WHITE);
            canvas.drawOval(posMarkerRect2, mPosMarker);
        }
    }

    // Currently Fixed size
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(CENTER_X * 2, CENTER_Y * 2);
    }

    public void drawPortraite() {
        invalidate();
    }

    // Weighted average between points
    private int ave(int s, int d, float p) {
        return s + java.lang.Math.round(p * (d - s));
    }

    // Interpolate colour value between points
    private int interpColor(int colors[], float unit) {
        if (unit <= 0) {
            return colors[0];
        }
        if (unit >= 1) {
            return colors[colors.length - 1];
        }

        float p = unit * (colors.length - 1);
        int i = (int) p;
        p -= i;

        // now p is just the fractional part [0...1] and i is the index
        int c0 = colors[i];
        int c1 = colors[i + 1];
        int a = ave(Color.alpha(c0), Color.alpha(c1), p);
        int r = ave(Color.red(c0), Color.red(c1), p);
        int g = ave(Color.green(c0), Color.green(c1), p);
        int b = ave(Color.blue(c0), Color.blue(c1), p);
        System.out.println("the vaient is" + b);
        return Color.argb(a, r, g, b);
    }

    private int round(double x) {
        return (int) Math.round(x);
    }

    public void upDateColorPreivew(byte hue, byte sat) {
        // update hue preview
        float unit = (float) hue / 255;
        if (unit < 0) {
            unit += 1;
        }

        unit = 1 - unit;

        int c = interpColor(mSpectrumColorsRev, unit);
        mArcSat.setColor(c);

        // update sat preview
        mArcSat.setAlpha(sat);

        colourKnown = true;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        if (!isEnabled())
            return false;

        float x = event.getX() - CENTER_X;
        float y = event.getY() - CENTER_Y;

        float angle = (float) java.lang.Math.atan2(y, x);
        // need to turn angle [-PI ... PI] into unit [0....1]
        float unit = angle / (2 * PI);

        if (unit < 0) {
            unit += 1;
        }

        // Pin the radius
        float radius = (float) java.lang.Math.sqrt(x * x + y * y);
        if (radius > PALETTE_RADIUS)
            radius = PALETTE_RADIUS;

        if (radius < INNER_RADIUS) {
            // User adjusted saturation
            if (angle < 0) {
                // + Sat
                if ((mHSV[1] + 0.10) <= 1) {
                    mHSV[1] += 0.10;
                } else {
                    mHSV[1] = 1;
                }
            } else {
                // - Sat
                if ((mHSV[1] - 0.10) >= 0) {
                    mHSV[1] -= 0.10;
                } else {
                    mHSV[1] = 0;
                }
            }

            byte hue = (byte) ((mHSV[0] / 360) * 255);
            byte sat = (byte) (mHSV[1] * 254);
            ourContext.sendHueSatChange(hue, sat);

            // update preview
            mArcSat.setAlpha((byte) (mHSV[1] * 254));
        } else {
            // User adjusted hue
            mCoord[0] = round(Math.cos(angle)
                    * (HUE_RADIUS - (HUE_RADIUS - INNER_RADIUS) / 2));
            mCoord[1] = round(Math.sin(angle)
                    * (HUE_RADIUS - (HUE_RADIUS - INNER_RADIUS) / 2));

            int c = interpColor(mSpectrumColorsRev, unit);
            float[] hsv = new float[3];
            Color.colorToHSV(c, hsv);
            mHSV[0] = hsv[0];

            colourKnown = true;

            // Update color
            byte hue = (byte) ((mHSV[0] / 360) * 255);
            byte sat = (byte) (mHSV[1] * 254);
            ourContext.sendHueSatChange(hue, sat);


            // update preview
            mArcSat.setColor(c);
            mArcSat.setAlpha((int) (mHSV[1] * 255));
        }

        invalidate();

        return true;
    }
}

1 个答案:

答案 0 :(得分:2)

我刚刚通过添加到manifest.xml的应用程序标记解决了下面的问题;

android:hardwareAccelerated="false"

链接中的相关句子 - http://developer.android.com/guide/topics/graphics/hardware-accel.html#controlling;

&#34; ...如果您的应用程序仅使用标准视图和Drawables,则全局启用它不会导致任何不利的绘图效果。但是,由于所有2D绘图操作都不支持硬件加速,因此打开它可能会影响某些自定义视图或绘图调用。&#34;