android.graphics.Shader

Here are the examples of the java api android.graphics.Shader taken from open source projects. By voting up you can indicate which examples are most useful and appropriate.

197 Examples 7

19 Source : BorderDrawable.java
with Apache License 2.0
from weexext

public void setImage(Shader shader) {
    mShader = shader;
    invalidateSelf();
}

19 Source : PCanvas.java
with GNU General Public License v3.0
from victordiaz

/**
 * Shaders
 */
@PhonkMethod(description = "Sets a shader", example = "")
@PhonkMethodParam(params = { "shader" })
public void setShader(Shader shader) {
    mPaintFill.setAntiAlias(true);
    mPaintFill.setShader(shader);
}

19 Source : ShaderDrawable.java
with Apache License 2.0
from saki4510t

public Shader setShader(@Nullable final Shader shader) {
    if (mShader != shader) {
        mShader = shader;
    }
    return shader;
}

19 Source : BrushDrawable.java
with Apache License 2.0
from saki4510t

public void setShader(final Shader shader) {
    getPaint().setShader(shader);
    invalidateSelf();
}

19 Source : SpanUtils.java
with Apache License 2.0
from RookieJay

/**
 * Set the span of shader.
 *
 * @param shader The shader.
 * @return the single {@link SpanUtils} instance
 */
public SpanUtils setShader(@NonNull final Shader shader) {
    this.shader = shader;
    return this;
}

19 Source : ColorPickerView.java
with Apache License 2.0
from relish-wang

/**
 * 创建SV着色器(明度线性着色器 + 饱和度线性着色器)
 *
 * @return 着色器
 */
private ComposeShader generateSVShader() {
    // 明度线性着色器
    if (mValShader == null) {
        mValShader = new LinearGradient(mSatValRect.left, mSatValRect.top, mSatValRect.left, mSatValRect.bottom, 0xffffffff, 0xff000000, TileMode.CLAMP);
    }
    // HSV转化为RGB
    int rgb = Color.HSVToColor(new float[] { mHue, 1f, 1f });
    // 饱和线性着色器
    Shader satShader = new LinearGradient(mSatValRect.left, mSatValRect.top, mSatValRect.right, mSatValRect.top, 0xffffffff, rgb, TileMode.CLAMP);
    // 组合着色器 = 明度线性着色器 + 饱和度线性着色器
    return new ComposeShader(mValShader, satShader, PorterDuff.Mode.MULTIPLY);
}

19 Source : MasterPaintView.java
with Apache License 2.0
from REBOOTERS

public void drawRadialsGradient() {
    Shader radialGradient = new RadialGradient(centerX, centerY, radius, mStartColor, mEndColor, Shader.TileMode.CLAMP);
    reDraw(radialGradient);
}

19 Source : MasterPaintView.java
with Apache License 2.0
from REBOOTERS

public void drawComposeShader(PorterDuff.Mode mode) {
    Shader bitmapShader1 = new BitmapShader(cover, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
    Shader bitmapShader2 = new BitmapShader(source, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
    Shader mShader = new ComposeShader(bitmapShader1, bitmapShader2, mode);
    reDraw(mShader);
}

19 Source : MasterPaintView.java
with Apache License 2.0
from REBOOTERS

public void drawSweepGradient() {
    Shader sweepGradient = new SweepGradient(centerX, centerY, mStartColor, mEndColor);
    reDraw(sweepGradient);
}

19 Source : MasterPaintView.java
with Apache License 2.0
from REBOOTERS

public void drawBitmapShader() {
    Shader bitmapShader = new BitmapShader(cover, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
    reDraw(bitmapShader);
}

19 Source : MasterPaintView.java
with Apache License 2.0
from REBOOTERS

public void drawLinearGradient() {
    Shader linearGradient = new LinearGradient(0, (centerY - radius), viewW, (centerY + radius), mStartColor, mEndColor, Shader.TileMode.CLAMP);
    reDraw(linearGradient);
}

19 Source : AbstractPaintSubject.java
with Apache License 2.0
from pkware

public void hreplacedhader(@Nullable Shader shader) {
    check("getShader()").that(actual.getShader()).isSameInstanceAs(shader);
}

19 Source : ContourView.java
with Apache License 2.0
from OCNYang

public void setShader(Shader... shader) {
    mShader = shader;
    mShaderMode = SHADER_MODE_CUSTOM;
}

19 Source : BIGChart.java
with GNU General Public License v3.0
from NightscoutFoundation

protected void updateRainbow() {
    animationAngle = (animationAngle + 1) % 360;
    // Animation matrix:
    int[] rainbow = { Color.RED, Color.YELLOW, Color.GREEN, Color.BLUE, Color.CYAN };
    Shader shader = new LinearGradient(0, 0, 0, 20, rainbow, null, Shader.TileMode.MIRROR);
    Matrix matrix = new Matrix();
    matrix.setRotate(animationAngle);
    shader.setLocalMatrix(matrix);
    mSgv.getPaint().setShader(shader);
    invalidate();
}

19 Source : AqiView.java
with Apache License 2.0
from li-yu

/**
 * 自定义空气质量环形控件
 * Created by liyu on 2017/8/23.
 */
public clreplaced AqiView extends View {

    private boolean canRefresh = true;

    private Paint paint;

    private Paint textPaint;

    private Paint textPaint2;

    // 圆环底色
    private int roundColor;

    // 进度条颜色
    private int roundProgressColor;

    // 文字颜色
    private int textColor;

    // 文字大小
    private float textSize;

    // 圆环宽度
    private float roundWidth = 28;

    private FakeWeather.FakeAqi aqi;

    private Shader shader;

    private float speed;

    private int[] aqiColors = new int[] { 0xFF62001E, 0xFF6BCD07, 0xFF6BCD07, 0xFFFBD029, 0xFFFE8800, 0xFFFE0000, 0xFF970454, 0xFF62001E };

    int currentAqiColor;

    public AqiView(Context context) {
        this(context, null);
    }

    public AqiView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public AqiView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        textSize = SizeUtils.dp2px(context, 12);
        paint = new Paint();
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(roundWidth);
        paint.setStrokeCap(Paint.Cap.ROUND);
        paint.setAntiAlias(true);
        textPaint = new Paint();
        textPaint.setStrokeWidth(0);
        textPaint.setAntiAlias(true);
        textPaint.setColor(Color.WHITE);
        textPaint.setTextSize(textSize);
        textPaint.setTextAlign(Paint.Align.CENTER);
        textPaint2 = new Paint();
        textPaint2.setAntiAlias(true);
        textPaint2.setStyle(Paint.Style.FILL);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (aqi == null)
            return;
        paint.setShader(null);
        paint.setColor(0xCC888888);
        RectF rectF;
        if (getHeight() >= getWidth()) {
            rectF = new RectF(0 + roundWidth, 0 + roundWidth, getWidth() - roundWidth, getWidth() - roundWidth);
        } else {
            rectF = new RectF(0 + (getWidth() - getHeight()) / 2 + roundWidth, 0 + roundWidth, getWidth() - (getWidth() - getHeight()) / 2 - roundWidth, getHeight() - roundWidth);
        }
        if (shader == null) {
            shader = new SweepGradient(rectF.left + rectF.width() / 2, rectF.top + rectF.height() / 2, aqiColors, new float[] { 0.125f, 0.125f, 0.3f, 0.375f, 0.45f, 0.525f, 0.675f, 0.925f });
            Matrix matrix = new Matrix();
            matrix.postRotate(45, rectF.left + rectF.width() / 2, rectF.top + rectF.height() / 2);
            shader.setLocalMatrix(matrix);
        }
        canvas.drawArc(rectF, 135, 270, false, paint);
        paint.setShader(shader);
        int aqiValue = Integer.parseInt(aqi.getApi());
        canvas.drawArc(rectF, 135, (aqiValue * speed / 500f) * 270.0f, false, paint);
        Paint.FontMetrics fontMetrics = textPaint.getFontMetrics();
        // 为基线到字体上边框的距离,即上图中的top
        float top = fontMetrics.top;
        // 为基线到字体下边框的距离,即上图中的bottom
        float bottom = fontMetrics.bottom;
        // 基线中间点的y轴计算公式
        int baseLineY = (int) (rectF.centerY() - top / 2 - bottom / 2);
        textPaint.setColor(Color.GRAY);
        canvas.drawText(String.valueOf((int) (aqiValue * speed)), rectF.centerX(), baseLineY, textPaint);
        float qltyStringWidth = textPaint.measureText(aqi.getQlty());
        RectF textRectf = new RectF(getWidth() / 2 - qltyStringWidth / 1.5f, rectF.bottom, getWidth() / 2 + qltyStringWidth / 1.5f, rectF.bottom + rectF.width() / 4);
        textPaint2.setColor(currentAqiColor);
        canvas.drawRoundRect(textRectf, 8, 8, textPaint2);
        // 基线中间点的y轴计算公式
        int baseLineY2 = (int) (textRectf.centerY() - top / 2 - bottom / 2);
        textPaint.setColor(Color.WHITE);
        canvas.drawText(aqi.getQlty(), textRectf.centerX(), baseLineY2, textPaint);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int desiredWidth = SizeUtils.dp2px(getContext(), 100);
        int desiredHeight = SizeUtils.dp2px(getContext(), 120);
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        int width;
        int height;
        // Measure Width
        if (widthMode == MeasureSpec.EXACTLY) {
            // Must be this size
            width = widthSize;
        } else if (widthMode == MeasureSpec.AT_MOST) {
            // Can't be bigger than...
            width = Math.min(desiredWidth, widthSize);
        } else {
            // Be whatever you want
            width = desiredWidth;
        }
        // Measure Height
        if (heightMode == MeasureSpec.EXACTLY) {
            // Must be this size
            height = heightSize;
        } else if (heightMode == MeasureSpec.AT_MOST) {
            // Can't be bigger than...
            height = Math.min(desiredHeight, heightSize);
        } else {
            // Be whatever you want
            height = desiredHeight;
        }
        // MUST CALL THIS
        setMeasuredDimension(width, height);
    }

    public void setApi(IFakeWeather weather) {
        if (weather == null || !canRefresh) {
            return;
        }
        this.aqi = weather.getFakeAqi();
        int apiValue = Integer.parseInt(aqi.getApi());
        int targetColor;
        if (apiValue <= 50) {
            targetColor = aqiColors[2];
        } else if (apiValue <= 100) {
            targetColor = aqiColors[3];
        } else if (apiValue <= 150) {
            targetColor = aqiColors[4];
        } else if (apiValue <= 200) {
            targetColor = aqiColors[5];
        } else if (apiValue <= 300) {
            targetColor = aqiColors[6];
        } else {
            targetColor = aqiColors[7];
        }
        ValueAnimator animator = ValueAnimator.ofFloat(0, 1);
        animator.setRepeatCount(0);
        animator.setInterpolator(new DecelerateInterpolator());
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                speed = (float) animation.getAnimatedValue();
                invalidate();
            }
        });
        ValueAnimator animator2 = ValueAnimator.ofObject(new ArgbEvaluator(), aqiColors[2], targetColor);
        animator2.setInterpolator(new LinearInterpolator());
        animator2.setRepeatCount(0);
        animator2.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                currentAqiColor = (int) animation.getAnimatedValue();
            }
        });
        AnimatorSet animSet = new AnimatorSet();
        animSet.play(animator).with(animator2);
        animSet.setDuration(2000);
        animSet.start();
        canRefresh = false;
        this.postDelayed(new Runnable() {

            @Override
            public void run() {
                canRefresh = true;
            }
        }, 2000);
    }
}

19 Source : SpanUtils.java
with Apache License 2.0
from LeviWGG

/**
 * 设置着色器
 *
 * @param shader 着色器
 * @return {@link SpanUtils}
 */
public SpanUtils setShader(@NonNull final Shader shader) {
    this.shader = shader;
    return this;
}

19 Source : USpan.java
with Apache License 2.0
from KosmoSakura

/**
 * @Tip 设置着色器
 */
public USpan setShader(@NonNull final Shader shader) {
    this.shader = shader;
    return this;
}

19 Source : ProgressWheel.java
with MIT License
from JZ-Darkal

public void setRimShader(Shader shader) {
    this.rimPaint.setShader(shader);
}

19 Source : WeekViewEvent.java
with MIT License
from jlurena

/**
 * Created by Raquib-ul-Alam Kanak on 7/21/2014.
 * Website: http://april-shower.com
 */
public clreplaced WeekViewEvent {

    private String mId;

    private DayTime mStartTime;

    private DayTime mEndTime;

    private String mName;

    private String mLocation;

    @ColorInt
    private int mColor;

    private boolean mAllDay;

    private Shader mShader;

    public WeekViewEvent() {
    }

    /**
     * Initializes the event for week view.
     *
     * @param id The id of the event as String.
     * @param name Name of the event.
     * @param startDay Day when the event starts.
     * @param startHour Hour (in 24-hour format) when the event starts.
     * @param startMinute Minute when the event starts.
     * @param endDay Day when the event ends.
     * @param endHour Hour (in 24-hour format) when the event ends.
     * @param endMinute Minute when the event ends.
     */
    public WeekViewEvent(String id, String name, int startDay, int startHour, int startMinute, int endDay, int endHour, int endMinute) {
        this.mId = id;
        this.mStartTime = new DayTime(startDay, startHour, startMinute);
        this.mEndTime = new DayTime(endDay, endHour, endMinute);
        this.mName = name;
    }

    /**
     * Initializes the event for week view.
     *
     * @param id The id of the event as String.
     * @param name Name of the event.
     * @param location The location of the event.
     * @param startTime The time when the event starts.
     * @param endTime The time when the event ends.
     * @param allDay Is the event an all day event.
     * @param shader the Shader of the event rectangle
     */
    public WeekViewEvent(String id, String name, String location, DayTime startTime, DayTime endTime, boolean allDay, Shader shader) {
        this.mId = id;
        this.mName = name;
        this.mLocation = location;
        this.mStartTime = startTime;
        this.mEndTime = endTime;
        this.mAllDay = allDay;
        this.mShader = shader;
    }

    /**
     * Initializes the event for week view.
     *
     * @param id The id of the event.
     * @param name Name of the event.
     * @param location The location of the event.
     * @param startTime The time when the event starts.
     * @param endTime The time when the event ends.
     * @param allDay Is the event an all day event.
     * @param shader the Shader of the event rectangle
     */
    @Deprecated
    public WeekViewEvent(long id, String name, String location, DayTime startTime, DayTime endTime, boolean allDay, Shader shader) {
        this(String.valueOf(id), name, location, startTime, endTime, allDay, shader);
    }

    /**
     * Initializes the event for week view.
     *
     * @param id The id of the event as String.
     * @param name Name of the event.
     * @param location The location of the event.
     * @param startTime The time when the event starts.
     * @param endTime The time when the event ends.
     * @param allDay Is the event an all day event
     */
    public WeekViewEvent(String id, String name, String location, DayTime startTime, DayTime endTime, boolean allDay) {
        this(id, name, location, startTime, endTime, allDay, null);
    }

    /**
     * Initializes the event for week view.
     *
     * @param id The id of the event as String.
     * @param name Name of the event.
     * @param location The location of the event.
     * @param startTime The time when the event starts.
     * @param endTime The time when the event ends.
     */
    public WeekViewEvent(String id, String name, String location, DayTime startTime, DayTime endTime) {
        this(id, name, location, startTime, endTime, false);
    }

    /**
     * Initializes the event for week view.
     *
     * @param id The id of the event specified as String.
     * @param name Name of the event.
     * @param startTime The time when the event starts.
     * @param endTime The time when the event ends.
     */
    public WeekViewEvent(String id, String name, DayTime startTime, DayTime endTime) {
        this(id, name, null, startTime, endTime);
    }

    @ColorInt
    public int getColor() {
        return mColor;
    }

    public void setColor(int color) {
        this.mColor = color;
    }

    public DayTime getEndTime() {
        return mEndTime;
    }

    public void setEndTime(DayTime endTime) {
        this.mEndTime = endTime;
    }

    public String getIdentifier() {
        return mId;
    }

    public void setIdentifier(String id) {
        this.mId = id;
    }

    public String getLocation() {
        return mLocation;
    }

    public void setLocation(String location) {
        this.mLocation = location;
    }

    public String getName() {
        return mName;
    }

    public void setName(String name) {
        this.mName = name;
    }

    public Shader getShader() {
        return mShader;
    }

    public void setShader(Shader shader) {
        mShader = shader;
    }

    public DayTime getStartTime() {
        return mStartTime;
    }

    public void setStartTime(DayTime startTime) {
        this.mStartTime = startTime;
    }

    public boolean isAllDay() {
        return mAllDay;
    }

    public void setAllDay(boolean allDay) {
        this.mAllDay = allDay;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClreplaced() != o.getClreplaced()) {
            return false;
        }
        WeekViewEvent that = (WeekViewEvent) o;
        return mId.equals(that.mId);
    }

    @Override
    public int hashCode() {
        return mId.hashCode();
    }

    public List<WeekViewEvent> splitWeekViewEvents() {
        // This function splits the WeekViewEvent in WeekViewEvents by day
        List<WeekViewEvent> events = new ArrayList<>();
        DayTime endTime = new DayTime(this.mEndTime);
        if (this.mStartTime.getDay() != endTime.getDay()) {
            endTime = new DayTime(this.mStartTime.getDay(), LocalTime.MAX);
            WeekViewEvent event1 = new WeekViewEvent(this.mId, this.mName, this.mLocation, this.mStartTime, endTime, this.mAllDay);
            event1.setColor(this.mColor);
            events.add(event1);
            // Add other days.
            DayTime otherDay = new DayTime(DayOfWeek.of(1), this.mStartTime.getTime());
            while (otherDay.getDay() != this.mEndTime.getDay()) {
                DayTime overDay = new DayTime(otherDay.getDay(), LocalTime.MIN);
                DayTime endOfOverDay = new DayTime(overDay.getDay(), LocalTime.MAX);
                WeekViewEvent eventMore = new WeekViewEvent(this.mId, this.mName, null, overDay, endOfOverDay, this.mAllDay);
                eventMore.setColor(this.getColor());
                events.add(eventMore);
                // Add next day.
                otherDay.addDays(1);
            }
            // Add last day.
            DayTime startTime = new DayTime(this.mEndTime.getDay(), LocalTime.MIN);
            WeekViewEvent event2 = new WeekViewEvent(this.mId, this.mName, this.mLocation, startTime, this.mEndTime, this.mAllDay);
            event2.setColor(this.getColor());
            events.add(event2);
        } else {
            events.add(this);
        }
        return events;
    }

    @Override
    public String toString() {
        return "WeekViewEvent{" + "mId='" + mId + '\'' + ", mStartTime=" + mStartTime + ", mEndTime=" + mEndTime + ", mName='" + mName + '\'' + ", mLocation='" + mLocation + '\'' + '}';
    }
}

19 Source : WeekViewEvent.java
with MIT License
from jlurena

public void setShader(Shader shader) {
    mShader = shader;
}

19 Source : LineDataSet.java
with Apache License 2.0
from JingZhuanDuoYing

public void setShader(Shader shader) {
    this.shader = shader;
}

19 Source : LineDataSet.java
with Apache License 2.0
from JingZhuanDuoYing

public void setShaderBaseValue(float shaderBaseValue, Shader shaderTop, Shader shaderBottom) {
    this.mShaderBaseValue = shaderBaseValue;
    this.mShaderTop = shaderTop;
    this.mShaderBottom = shaderBottom;
}

19 Source : WaveView.java
with MIT License
from jenly1314

/**
 * 设置波纹着色器
 * @param shader
 */
public void setWaveShader(Shader shader) {
    this.mShader = shader;
    updatePaint();
    invalidate();
}

19 Source : ArcSeekBar.java
with MIT License
from jenly1314

/**
 * 设置进度颜色(通过着色器实现渐变色)
 * @param colors
 */
public void setProgressColor(int... colors) {
    if (isMeasureCircle) {
        Shader shader = new SweepGradient(mCircleCenterX, mCircleCenterX, colors, null);
        setShader(shader);
    } else {
        mShaderColors = colors;
        isShader = true;
    }
}

19 Source : ArcSeekBar.java
with MIT License
from jenly1314

/**
 * 设置着色器
 * @param shader
 */
public void setShader(Shader shader) {
    isShader = true;
    this.mShader = shader;
    invalidate();
}

19 Source : BlazingColorVisualizer.java
with Apache License 2.0
from GautamChibde

/**
 * TODO
 *
 * Created by gautam chibde on 29/10/17.
 */
clreplaced BlazingColorVisualizer extends BaseVisualizer {

    private Shader shader;

    public BlazingColorVisualizer(Context context) {
        super(context);
    }

    public BlazingColorVisualizer(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public BlazingColorVisualizer(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void init() {
        shader = new LinearGradient(0, 0, 0, getHeight(), Color.BLUE, Color.GREEN, Shader.TileMode.MIRROR);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        if (bytes != null) {
            paint.setShader(shader);
            for (int i = 0, k = 0; i < (bytes.length - 1) && k < bytes.length; i++, k++) {
                int top = getHeight() + ((byte) (Math.abs(bytes[k]) + 128)) * getHeight() / 128;
                canvas.drawLine(i, getHeight(), i, top, paint);
            }
            super.onDraw(canvas);
        }
    }
}

19 Source : ShimmerSpan.java
with Apache License 2.0
from Fueled

/**
 * Imparts shimmer effect to the text.
 *
 * source: @link{https://www.youtube.com/watch?v=G55mJvel7iI}
 */
public clreplaced ShimmerSpan extends CharacterStyle implements UpdateAppearance {

    private final int[] colors;

    private Shader shader = null;

    private Matrix matrix = new Matrix();

    private float translateXPercentage = 0;

    public ShimmerSpan() {
        colors = new int[3];
        colors[0] = Color.WHITE;
        colors[1] = Color.LTGRAY;
        colors[2] = Color.DKGRAY;
    }

    public void setTranslateXPercentage(float percentage) {
        translateXPercentage = percentage;
    }

    public float getTranslateXPercentage() {
        return translateXPercentage;
    }

    @Override
    public void updateDrawState(TextPaint paint) {
        paint.setStyle(Paint.Style.FILL);
        float width = paint.getTextSize() * colors.length;
        if (shader == null) {
            shader = new LinearGradient(0, 0, 0, width, colors, null, Shader.TileMode.MIRROR);
        }
        matrix.reset();
        matrix.setRotate(90);
        matrix.postTranslate(width * translateXPercentage, 0);
        shader.setLocalMatrix(matrix);
        paint.setShader(shader);
    }
}

19 Source : FadingShadow.java
with Apache License 2.0
from derry

/**
 * This clreplaced draws a variable-sized shadow at the top or bottom edge of a view. This is just like
 * a fading edge, except that the shadow color can have an alpha component, whereas a fading edge
 * color must be opaque.
 */
public clreplaced FadingShadow {

    public static final int POSITION_TOP = 0;

    public static final int POSITION_BOTTOM = 1;

    private static final int SMOOTH_ALGORITHM_INTERPOLATION_POINTS_NUM = 8;

    private Paint mShadowPaint = new Paint();

    private Matrix mShadowMatrix = new Matrix();

    private Shader mShadowShader;

    /**
     * @param shadowColor The color of the shadow, e.g. 0x11000000.
     */
    public FadingShadow(int shadowColor) {
        final int n = SMOOTH_ALGORITHM_INTERPOLATION_POINTS_NUM;
        float[] positions = new float[n];
        int[] colors = new int[n];
        int transparentShadowColor = shadowColor & 0x00FFFFFF;
        int shadowAlpha = Color.alpha(shadowColor);
        // Piece-wise linear interpolation of the smooth cubic function below.
        for (int i = 0; i < n; ++i) {
            float x = (float) i / (n - 1);
            // Polynomial computation by Estrin's scheme.
            float value = (1.0f - 2.2f * x) + (1.8f - 0.6f * x) * (x * x);
            positions[i] = x;
            colors[i] = (Math.round(shadowAlpha * value) << 24) | transparentShadowColor;
        }
        mShadowShader = new LinearGradient(0, 0, 0, 1, colors, positions, Shader.TileMode.CLAMP);
    }

    /**
     * Draws a shadow at the top or bottom of a view. This should be called from dispatchDraw() so
     * the shadow is drawn on top of the view's children.
     *
     * @param view The View in which to draw the shadow.
     * @param canvas The canvas on which to draw.
     * @param position Where to draw the shadow: either POSITION_TOP or POSITION_BOTTOM.
     * @param shadowHeight The maximum height of the shadow, in pixels.
     * @param shadowStrength A value between 0 and 1 indicating the relative size of the shadow. 0
     *                       means no shadow at all. 1 means a full height shadow.
     */
    public void drawShadow(View view, Canvas canvas, int position, float shadowHeight, float shadowStrength) {
        float scaledShadowHeight = Math.max(0.0f, Math.min(1.0f, shadowStrength)) * shadowHeight;
        if (scaledShadowHeight < 1.0f)
            return;
        int left = view.getScrollX();
        int right = left + view.getRight();
        if (position == POSITION_BOTTOM) {
            int bottom = view.getScrollY() + view.getBottom() - view.getTop();
            mShadowMatrix.setScale(1, scaledShadowHeight);
            mShadowMatrix.postRotate(180);
            mShadowMatrix.postTranslate(left, bottom);
            mShadowShader.setLocalMatrix(mShadowMatrix);
            mShadowPaint.setShader(mShadowShader);
            canvas.drawRect(left, bottom - scaledShadowHeight, right, bottom, mShadowPaint);
        } else if (position == POSITION_TOP) {
            int top = view.getScrollY();
            mShadowMatrix.setScale(1, scaledShadowHeight);
            mShadowMatrix.postTranslate(left, top);
            mShadowShader.setLocalMatrix(mShadowMatrix);
            mShadowPaint.setShader(mShadowShader);
            canvas.drawRect(left, top, right, top + scaledShadowHeight, mShadowPaint);
        }
    }
}

19 Source : GradientTextView.java
with GNU General Public License v3.0
from deepshooter

private void applyLinearGradient() {
    Shader shader = null;
    if (mGradientOrientation == LG_HORIZONTAL) {
        shader = new LinearGradient(0, getHeight(), getWidth(), 0, mStartColor, mEndColor, Shader.TileMode.CLAMP);
    } else {
        shader = new LinearGradient(0, 0, 0, getHeight(), mStartColor, mEndColor, Shader.TileMode.CLAMP);
    }
    getPaint().setShader(shader);
}

19 Source : ComplexColorCompat.java
with Apache License 2.0
from covidsafewatch

static ComplexColorCompat from(Shader shader) {
    return new ComplexColorCompat(shader, (ColorStateList) null, 0);
}

19 Source : ComplexColorCompat.java
with Apache License 2.0
from androidx

static ComplexColorCompat from(@NonNull Shader shader) {
    return new ComplexColorCompat(shader, null, TRANSPARENT);
}

18 Source : ColorValueView.java
with Apache License 2.0
from yuchuangu85

private void updatePaint() {
    float[] hsv = new float[] { mHSVO[0], mHSVO[1], 0f };
    int color1 = Color.HSVToColor(hsv);
    hsv[2] = 1;
    int color2 = Color.HSVToColor(hsv);
    Shader sg = new LinearGradient(mBorder, mBorder, mBorder, mHeight - mBorder, color1, color2, Shader.TileMode.CLAMP);
    mBarPaint1.setShader(sg);
}

18 Source : ColorSaturationView.java
with Apache License 2.0
from yuchuangu85

private void updatePaint() {
    float[] hsvo = Arrays.copyOf(mHSVO, 4);
    hsvo[3] = 1;
    hsvo[2] = 1;
    hsvo[1] = 1;
    int color2 = Color.HSVToColor(hsvo);
    hsvo[1] = 0;
    int color1 = Color.HSVToColor(hsvo);
    Shader sg = new LinearGradient(mBorder, mBorder, mWidth - mBorder, mBorder, color1, color2, Shader.TileMode.CLAMP);
    mBarPaint1.setShader(sg);
}

18 Source : ColorOpacityView.java
with Apache License 2.0
from yuchuangu85

private void updatePaint() {
    int color2 = Color.HSVToColor(mHSVO);
    int color1 = color2 & 0xFFFFFF;
    Shader sg = new LinearGradient(mBorder, mBorder, mWidth - mBorder, mBorder, color1, color2, Shader.TileMode.CLAMP);
    mBarPaint1.setShader(sg);
}

18 Source : ColorBrightnessView.java
with Apache License 2.0
from yuchuangu85

private void updatePaint() {
    float[] hsvo = Arrays.copyOf(mHSVO, 4);
    hsvo[2] = 1;
    hsvo[1] = 1;
    hsvo[3] = 1;
    int color2 = Color.HSVToColor(hsvo);
    hsvo[2] = 0;
    int color1 = Color.HSVToColor(hsvo);
    Shader sg = new LinearGradient(mBorder, mBorder, mWidth - mBorder, mBorder, color1, color2, Shader.TileMode.CLAMP);
    mBarPaint1.setShader(sg);
}

18 Source : ColorPickerView.java
with Apache License 2.0
from WrBug

/**
 * Displays a color picker to the user and allow them
 * to select a color. A slider for the alpha channel is
 * also available. Enable it by setting
 * setAlphaSliderVisible(boolean) to true.
 * @author Daniel Nilsson
 */
public clreplaced ColorPickerView extends View {

    private final static int PANEL_SAT_VAL = 0;

    private final static int PANEL_HUE = 1;

    private final static int PANEL_ALPHA = 2;

    /**
     * The width in pixels of the border
     * surrounding all color panels.
     */
    private final static float BORDER_WIDTH_PX = 1;

    /**
     * The width in dp of the hue panel.
     */
    private float HUE_PANEL_WIDTH = 30f;

    /**
     * The height in dp of the alpha panel
     */
    private float ALPHA_PANEL_HEIGHT = 20f;

    /**
     * The distance in dp between the different
     * color panels.
     */
    private float PANEL_SPACING = 10f;

    /**
     * The radius in dp of the color palette tracker circle.
     */
    private float PALETTE_CIRCLE_TRACKER_RADIUS = 5f;

    /**
     * The dp which the tracker of the hue or alpha panel
     * will extend outside of its bounds.
     */
    private float RECTANGLE_TRACKER_OFFSET = 2f;

    private float mDensity = 1f;

    private OnColorChangedListener mListener;

    private Paint mSatValPaint;

    private Paint mSatValTrackerPaint;

    private Paint mHuePaint;

    private Paint mHueTrackerPaint;

    private Paint mAlphaPaint;

    private Paint mAlphaTextPaint;

    private Paint mBorderPaint;

    private Shader mValShader;

    private Shader mSatShader;

    private Shader mHueShader;

    private Shader mAlphaShader;

    private int mAlpha = 0xff;

    private float mHue = 360f;

    private float mSat = 0f;

    private float mVal = 0f;

    private String mAlphaSliderText = "";

    private int mSliderTrackerColor = 0xff1c1c1c;

    private int mBorderColor = 0xff6E6E6E;

    private boolean mShowAlphaPanel = false;

    /*
	 * To remember which panel that has the "focus" when
	 * processing hardware button data.
	 */
    private int mLastTouchedPanel = PANEL_SAT_VAL;

    /**
     * Offset from the edge we must have or else
     * the finger tracker will get clipped when
     * it is drawn outside of the view.
     */
    private float mDrawingOffset;

    /*
	 * Distance form the edges of the view
	 * of where we are allowed to draw.
	 */
    private RectF mDrawingRect;

    private RectF mSatValRect;

    private RectF mHueRect;

    private RectF mAlphaRect;

    private AlphaPatternDrawable mAlphaPattern;

    private Point mStartTouchPoint = null;

    public interface OnColorChangedListener {

        public void onColorChanged(int color);
    }

    public ColorPickerView(Context context) {
        this(context, null);
    }

    public ColorPickerView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ColorPickerView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    private void init() {
        mDensity = getContext().getResources().getDisplayMetrics().density;
        PALETTE_CIRCLE_TRACKER_RADIUS *= mDensity;
        RECTANGLE_TRACKER_OFFSET *= mDensity;
        HUE_PANEL_WIDTH *= mDensity;
        ALPHA_PANEL_HEIGHT *= mDensity;
        PANEL_SPACING = PANEL_SPACING * mDensity;
        mDrawingOffset = calculateRequiredOffset();
        initPaintTools();
        // Needed for receiving trackball motion events.
        setFocusable(true);
        setFocusableInTouchMode(true);
    }

    private void initPaintTools() {
        mSatValPaint = new Paint();
        mSatValTrackerPaint = new Paint();
        mHuePaint = new Paint();
        mHueTrackerPaint = new Paint();
        mAlphaPaint = new Paint();
        mAlphaTextPaint = new Paint();
        mBorderPaint = new Paint();
        mSatValTrackerPaint.setStyle(Style.STROKE);
        mSatValTrackerPaint.setStrokeWidth(2f * mDensity);
        mSatValTrackerPaint.setAntiAlias(true);
        mHueTrackerPaint.setColor(mSliderTrackerColor);
        mHueTrackerPaint.setStyle(Style.STROKE);
        mHueTrackerPaint.setStrokeWidth(2f * mDensity);
        mHueTrackerPaint.setAntiAlias(true);
        mAlphaTextPaint.setColor(0xff1c1c1c);
        mAlphaTextPaint.setTextSize(14f * mDensity);
        mAlphaTextPaint.setAntiAlias(true);
        mAlphaTextPaint.setTextAlign(Align.CENTER);
        mAlphaTextPaint.setFakeBoldText(true);
    }

    private float calculateRequiredOffset() {
        float offset = Math.max(PALETTE_CIRCLE_TRACKER_RADIUS, RECTANGLE_TRACKER_OFFSET);
        offset = Math.max(offset, BORDER_WIDTH_PX * mDensity);
        return offset * 1.5f;
    }

    private int[] buildHueColorArray() {
        int[] hue = new int[361];
        int count = 0;
        for (int i = hue.length - 1; i >= 0; i--, count++) {
            hue[count] = Color.HSVToColor(new float[] { i, 1f, 1f });
        }
        return hue;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        if (mDrawingRect.width() <= 0 || mDrawingRect.height() <= 0)
            return;
        drawSatValPanel(canvas);
        drawHuePanel(canvas);
        drawAlphaPanel(canvas);
    }

    private void drawSatValPanel(Canvas canvas) {
        final RectF rect = mSatValRect;
        if (BORDER_WIDTH_PX > 0) {
            mBorderPaint.setColor(mBorderColor);
            canvas.drawRect(mDrawingRect.left, mDrawingRect.top, rect.right + BORDER_WIDTH_PX, rect.bottom + BORDER_WIDTH_PX, mBorderPaint);
        }
        if (mValShader == null) {
            mValShader = new LinearGradient(rect.left, rect.top, rect.left, rect.bottom, 0xffffffff, 0xff000000, TileMode.CLAMP);
        }
        int rgb = Color.HSVToColor(new float[] { mHue, 1f, 1f });
        mSatShader = new LinearGradient(rect.left, rect.top, rect.right, rect.top, 0xffffffff, rgb, TileMode.CLAMP);
        ComposeShader mShader = new ComposeShader(mValShader, mSatShader, PorterDuff.Mode.MULTIPLY);
        mSatValPaint.setShader(mShader);
        canvas.drawRect(rect, mSatValPaint);
        Point p = satValToPoint(mSat, mVal);
        mSatValTrackerPaint.setColor(0xff000000);
        canvas.drawCircle(p.x, p.y, PALETTE_CIRCLE_TRACKER_RADIUS - 1f * mDensity, mSatValTrackerPaint);
        mSatValTrackerPaint.setColor(0xffdddddd);
        canvas.drawCircle(p.x, p.y, PALETTE_CIRCLE_TRACKER_RADIUS, mSatValTrackerPaint);
    }

    private void drawHuePanel(Canvas canvas) {
        final RectF rect = mHueRect;
        if (BORDER_WIDTH_PX > 0) {
            mBorderPaint.setColor(mBorderColor);
            canvas.drawRect(rect.left - BORDER_WIDTH_PX, rect.top - BORDER_WIDTH_PX, rect.right + BORDER_WIDTH_PX, rect.bottom + BORDER_WIDTH_PX, mBorderPaint);
        }
        if (mHueShader == null) {
            mHueShader = new LinearGradient(rect.left, rect.top, rect.left, rect.bottom, buildHueColorArray(), null, TileMode.CLAMP);
            mHuePaint.setShader(mHueShader);
        }
        canvas.drawRect(rect, mHuePaint);
        float rectHeight = 4 * mDensity / 2;
        Point p = hueToPoint(mHue);
        RectF r = new RectF();
        r.left = rect.left - RECTANGLE_TRACKER_OFFSET;
        r.right = rect.right + RECTANGLE_TRACKER_OFFSET;
        r.top = p.y - rectHeight;
        r.bottom = p.y + rectHeight;
        canvas.drawRoundRect(r, 2, 2, mHueTrackerPaint);
    }

    private void drawAlphaPanel(Canvas canvas) {
        if (!mShowAlphaPanel || mAlphaRect == null || mAlphaPattern == null)
            return;
        final RectF rect = mAlphaRect;
        if (BORDER_WIDTH_PX > 0) {
            mBorderPaint.setColor(mBorderColor);
            canvas.drawRect(rect.left - BORDER_WIDTH_PX, rect.top - BORDER_WIDTH_PX, rect.right + BORDER_WIDTH_PX, rect.bottom + BORDER_WIDTH_PX, mBorderPaint);
        }
        mAlphaPattern.draw(canvas);
        float[] hsv = new float[] { mHue, mSat, mVal };
        int color = Color.HSVToColor(hsv);
        int acolor = Color.HSVToColor(0, hsv);
        mAlphaShader = new LinearGradient(rect.left, rect.top, rect.right, rect.top, color, acolor, TileMode.CLAMP);
        mAlphaPaint.setShader(mAlphaShader);
        canvas.drawRect(rect, mAlphaPaint);
        if (mAlphaSliderText != null && mAlphaSliderText != "") {
            canvas.drawText(mAlphaSliderText, rect.centerX(), rect.centerY() + 4 * mDensity, mAlphaTextPaint);
        }
        float rectWidth = 4 * mDensity / 2;
        Point p = alphaToPoint(mAlpha);
        RectF r = new RectF();
        r.left = p.x - rectWidth;
        r.right = p.x + rectWidth;
        r.top = rect.top - RECTANGLE_TRACKER_OFFSET;
        r.bottom = rect.bottom + RECTANGLE_TRACKER_OFFSET;
        canvas.drawRoundRect(r, 2, 2, mHueTrackerPaint);
    }

    private Point hueToPoint(float hue) {
        final RectF rect = mHueRect;
        final float height = rect.height();
        Point p = new Point();
        p.y = (int) (height - (hue * height / 360f) + rect.top);
        p.x = (int) rect.left;
        return p;
    }

    private Point satValToPoint(float sat, float val) {
        final RectF rect = mSatValRect;
        final float height = rect.height();
        final float width = rect.width();
        Point p = new Point();
        p.x = (int) (sat * width + rect.left);
        p.y = (int) ((1f - val) * height + rect.top);
        return p;
    }

    private Point alphaToPoint(int alpha) {
        final RectF rect = mAlphaRect;
        final float width = rect.width();
        Point p = new Point();
        p.x = (int) (width - (alpha * width / 0xff) + rect.left);
        p.y = (int) rect.top;
        return p;
    }

    private float[] pointToSatVal(float x, float y) {
        final RectF rect = mSatValRect;
        float[] result = new float[2];
        float width = rect.width();
        float height = rect.height();
        if (x < rect.left) {
            x = 0f;
        } else if (x > rect.right) {
            x = width;
        } else {
            x = x - rect.left;
        }
        if (y < rect.top) {
            y = 0f;
        } else if (y > rect.bottom) {
            y = height;
        } else {
            y = y - rect.top;
        }
        result[0] = 1.f / width * x;
        result[1] = 1.f - (1.f / height * y);
        return result;
    }

    private float pointToHue(float y) {
        final RectF rect = mHueRect;
        float height = rect.height();
        if (y < rect.top) {
            y = 0f;
        } else if (y > rect.bottom) {
            y = height;
        } else {
            y = y - rect.top;
        }
        return 360f - (y * 360f / height);
    }

    private int pointToAlpha(int x) {
        final RectF rect = mAlphaRect;
        final int width = (int) rect.width();
        if (x < rect.left) {
            x = 0;
        } else if (x > rect.right) {
            x = width;
        } else {
            x = x - (int) rect.left;
        }
        return 0xff - (x * 0xff / width);
    }

    @Override
    public boolean onTrackballEvent(MotionEvent event) {
        float x = event.getX();
        float y = event.getY();
        boolean update = false;
        if (event.getAction() == MotionEvent.ACTION_MOVE) {
            switch(mLastTouchedPanel) {
                case PANEL_SAT_VAL:
                    float sat, val;
                    sat = mSat + x / 50f;
                    val = mVal - y / 50f;
                    if (sat < 0f) {
                        sat = 0f;
                    } else if (sat > 1f) {
                        sat = 1f;
                    }
                    if (val < 0f) {
                        val = 0f;
                    } else if (val > 1f) {
                        val = 1f;
                    }
                    mSat = sat;
                    mVal = val;
                    update = true;
                    break;
                case PANEL_HUE:
                    float hue = mHue - y * 10f;
                    if (hue < 0f) {
                        hue = 0f;
                    } else if (hue > 360f) {
                        hue = 360f;
                    }
                    mHue = hue;
                    update = true;
                    break;
                case PANEL_ALPHA:
                    if (!mShowAlphaPanel || mAlphaRect == null) {
                        update = false;
                    } else {
                        int alpha = (int) (mAlpha - x * 10);
                        if (alpha < 0) {
                            alpha = 0;
                        } else if (alpha > 0xff) {
                            alpha = 0xff;
                        }
                        mAlpha = alpha;
                        update = true;
                    }
                    break;
            }
        }
        if (update) {
            if (mListener != null) {
                mListener.onColorChanged(Color.HSVToColor(mAlpha, new float[] { mHue, mSat, mVal }));
            }
            invalidate();
            return true;
        }
        return super.onTrackballEvent(event);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        boolean update = false;
        switch(event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mStartTouchPoint = new Point((int) event.getX(), (int) event.getY());
                update = moveTrackersIfNeeded(event);
                break;
            case MotionEvent.ACTION_MOVE:
                update = moveTrackersIfNeeded(event);
                break;
            case MotionEvent.ACTION_UP:
                mStartTouchPoint = null;
                update = moveTrackersIfNeeded(event);
                break;
        }
        if (update) {
            if (mListener != null) {
                mListener.onColorChanged(Color.HSVToColor(mAlpha, new float[] { mHue, mSat, mVal }));
            }
            invalidate();
            return true;
        }
        return super.onTouchEvent(event);
    }

    private boolean moveTrackersIfNeeded(MotionEvent event) {
        if (mStartTouchPoint == null)
            return false;
        boolean update = false;
        int startX = mStartTouchPoint.x;
        int startY = mStartTouchPoint.y;
        if (mHueRect.contains(startX, startY)) {
            mLastTouchedPanel = PANEL_HUE;
            mHue = pointToHue(event.getY());
            update = true;
        } else if (mSatValRect.contains(startX, startY)) {
            mLastTouchedPanel = PANEL_SAT_VAL;
            float[] result = pointToSatVal(event.getX(), event.getY());
            mSat = result[0];
            mVal = result[1];
            update = true;
        } else if (mAlphaRect != null && mAlphaRect.contains(startX, startY)) {
            mLastTouchedPanel = PANEL_ALPHA;
            mAlpha = pointToAlpha((int) event.getX());
            update = true;
        }
        return update;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int width = 0;
        int height = 0;
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int widthAllowed = MeasureSpec.getSize(widthMeasureSpec);
        int heightAllowed = MeasureSpec.getSize(heightMeasureSpec);
        widthAllowed = chooseWidth(widthMode, widthAllowed);
        heightAllowed = chooseHeight(heightMode, heightAllowed);
        if (!mShowAlphaPanel) {
            height = (int) (widthAllowed - PANEL_SPACING - HUE_PANEL_WIDTH);
            // If calculated height (based on the width) is more than the allowed height.
            if (height > heightAllowed || getTag().equals("landscape")) {
                height = heightAllowed;
                width = (int) (height + PANEL_SPACING + HUE_PANEL_WIDTH);
            } else {
                width = widthAllowed;
            }
        } else {
            width = (int) (heightAllowed - ALPHA_PANEL_HEIGHT + HUE_PANEL_WIDTH);
            if (width > widthAllowed) {
                width = widthAllowed;
                height = (int) (widthAllowed - HUE_PANEL_WIDTH + ALPHA_PANEL_HEIGHT);
            } else {
                height = heightAllowed;
            }
        }
        setMeasuredDimension(width, height);
    }

    private int chooseWidth(int mode, int size) {
        if (mode == MeasureSpec.AT_MOST || mode == MeasureSpec.EXACTLY) {
            return size;
        } else {
            // (mode == MeasureSpec.UNSPECIFIED)
            return getPrefferedWidth();
        }
    }

    private int chooseHeight(int mode, int size) {
        if (mode == MeasureSpec.AT_MOST || mode == MeasureSpec.EXACTLY) {
            return size;
        } else {
            // (mode == MeasureSpec.UNSPECIFIED)
            return getPrefferedHeight();
        }
    }

    private int getPrefferedWidth() {
        int width = getPrefferedHeight();
        if (mShowAlphaPanel) {
            width -= (PANEL_SPACING + ALPHA_PANEL_HEIGHT);
        }
        return (int) (width + HUE_PANEL_WIDTH + PANEL_SPACING);
    }

    private int getPrefferedHeight() {
        int height = (int) (200 * mDensity);
        if (mShowAlphaPanel) {
            height += PANEL_SPACING + ALPHA_PANEL_HEIGHT;
        }
        return height;
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mDrawingRect = new RectF();
        mDrawingRect.left = mDrawingOffset + getPaddingLeft();
        mDrawingRect.right = w - mDrawingOffset - getPaddingRight();
        mDrawingRect.top = mDrawingOffset + getPaddingTop();
        mDrawingRect.bottom = h - mDrawingOffset - getPaddingBottom();
        setUpSatValRect();
        setUpHueRect();
        setUpAlphaRect();
    }

    private void setUpSatValRect() {
        final RectF dRect = mDrawingRect;
        float panelSide = dRect.height() - BORDER_WIDTH_PX * 2;
        if (mShowAlphaPanel) {
            panelSide -= PANEL_SPACING + ALPHA_PANEL_HEIGHT;
        }
        float left = dRect.left + BORDER_WIDTH_PX;
        float top = dRect.top + BORDER_WIDTH_PX;
        float bottom = top + panelSide;
        float right = left + panelSide;
        mSatValRect = new RectF(left, top, right, bottom);
    }

    private void setUpHueRect() {
        final RectF dRect = mDrawingRect;
        float left = dRect.right - HUE_PANEL_WIDTH + BORDER_WIDTH_PX;
        float top = dRect.top + BORDER_WIDTH_PX;
        float bottom = dRect.bottom - BORDER_WIDTH_PX - (mShowAlphaPanel ? (PANEL_SPACING + ALPHA_PANEL_HEIGHT) : 0);
        float right = dRect.right - BORDER_WIDTH_PX;
        mHueRect = new RectF(left, top, right, bottom);
    }

    private void setUpAlphaRect() {
        if (!mShowAlphaPanel)
            return;
        final RectF dRect = mDrawingRect;
        float left = dRect.left + BORDER_WIDTH_PX;
        float top = dRect.bottom - ALPHA_PANEL_HEIGHT + BORDER_WIDTH_PX;
        float bottom = dRect.bottom - BORDER_WIDTH_PX;
        float right = dRect.right - BORDER_WIDTH_PX;
        mAlphaRect = new RectF(left, top, right, bottom);
        mAlphaPattern = new AlphaPatternDrawable((int) (5 * mDensity));
        mAlphaPattern.setBounds(Math.round(mAlphaRect.left), Math.round(mAlphaRect.top), Math.round(mAlphaRect.right), Math.round(mAlphaRect.bottom));
    }

    /**
     * Set a OnColorChangedListener to get notified when the color
     * selected by the user has changed.
     * @param listener
     */
    public void setOnColorChangedListener(OnColorChangedListener listener) {
        mListener = listener;
    }

    /**
     * Set the color of the border surrounding all panels.
     * @param color
     */
    public void setBorderColor(int color) {
        mBorderColor = color;
        invalidate();
    }

    /**
     * Get the color of the border surrounding all panels.
     */
    public int getBorderColor() {
        return mBorderColor;
    }

    /**
     * Get the current color this view is showing.
     * @return the current color.
     */
    public int getColor() {
        return Color.HSVToColor(mAlpha, new float[] { mHue, mSat, mVal });
    }

    /**
     * Set the color the view should show.
     * @param color The color that should be selected.
     */
    public void setColor(int color) {
        setColor(color, false);
    }

    /**
     * Set the color this view should show.
     * @param color The color that should be selected.
     * @param callback If you want to get a callback to
     * your OnColorChangedListener.
     */
    public void setColor(int color, boolean callback) {
        int alpha = Color.alpha(color);
        int red = Color.red(color);
        int blue = Color.blue(color);
        int green = Color.green(color);
        float[] hsv = new float[3];
        Color.RGBToHSV(red, green, blue, hsv);
        mAlpha = alpha;
        mHue = hsv[0];
        mSat = hsv[1];
        mVal = hsv[2];
        if (callback && mListener != null) {
            mListener.onColorChanged(Color.HSVToColor(mAlpha, new float[] { mHue, mSat, mVal }));
        }
        invalidate();
    }

    /**
     * Get the drawing offset of the color picker view.
     * The drawing offset is the distance from the side of
     * a panel to the side of the view minus the padding.
     * Useful if you want to have your own panel below showing
     * the currently selected color and want to align it perfectly.
     * @return The offset in pixels.
     */
    public float getDrawingOffset() {
        return mDrawingOffset;
    }

    /**
     * Set if the user is allowed to adjust the alpha panel. Default is false.
     * If it is set to false no alpha will be set.
     * @param visible
     */
    public void setAlphaSliderVisible(boolean visible) {
        if (mShowAlphaPanel != visible) {
            mShowAlphaPanel = visible;
            /*
			 * Reset all shader to force a recreation.
			 * Otherwise they will not look right after
			 * the size of the view has changed.
			 */
            mValShader = null;
            mSatShader = null;
            mHueShader = null;
            mAlphaShader = null;
            ;
            requestLayout();
        }
    }

    public boolean getAlphaSliderVisible() {
        return mShowAlphaPanel;
    }

    public void setSliderTrackerColor(int color) {
        mSliderTrackerColor = color;
        mHueTrackerPaint.setColor(mSliderTrackerColor);
        invalidate();
    }

    public int getSliderTrackerColor() {
        return mSliderTrackerColor;
    }

    /**
     * Set the text that should be shown in the
     * alpha slider. Set to null to disable text.
     * @param res string resource id.
     */
    public void setAlphaSliderText(int res) {
        String text = getContext().getString(res);
        setAlphaSliderText(text);
    }

    /**
     * Set the text that should be shown in the
     * alpha slider. Set to null to disable text.
     * @param text Text that should be shown.
     */
    public void setAlphaSliderText(String text) {
        mAlphaSliderText = text;
        invalidate();
    }

    /**
     * Get the current value of the text
     * that will be shown in the alpha
     * slider.
     * @return
     */
    public String getAlphaSliderText() {
        return mAlphaSliderText;
    }
}

18 Source : WXResourceUtilsTest.java
with Apache License 2.0
from weexext

@Test
public void testGetShader() throws Exception {
    Shader shader = WXResourceUtils.getShader("linear-gradient(to bottom,#a80077,blue)", 100, 100);
    replacedertNotNull(shader);
    shader = WXResourceUtils.getShader("linear-gradient(to bottom,#a80077,rgb(255,255,0))", 100, 100);
    replacedertNotNull(shader);
    shader = WXResourceUtils.getShader("linear-gradient(to bottom,#a80077,rgba(255,255,0,0.5))", 100, 100);
    replacedertNotNull(shader);
    shader = WXResourceUtils.getShader("gradient", 100, 100);
    replacedertNull(shader);
}

18 Source : WXResourceUtils.java
with Apache License 2.0
from weexext

/**
 * replacedembly gradients
 * @param image gradient values contains direction、colors
 * @param width component width
 * @param height component height
 * @return gradient shader
 */
public static Shader getShader(String image, float width, float height) {
    List<String> valueList = parseGradientValues(image);
    if (valueList != null && valueList.size() == 3) {
        float[] points = parseGradientDirection(valueList.get(0), width, height);
        Shader shader = new LinearGradient(points[0], points[1], points[2], points[3], getColor(valueList.get(1), Color.WHITE), getColor(valueList.get(2), Color.WHITE), Shader.TileMode.REPEAT);
        return shader;
    }
    return null;
}

18 Source : WXComponent.java
with Apache License 2.0
from weexext

public void setBackgroundImage(@NonNull String bgImage) {
    if ("".equals(bgImage.trim())) {
        getOrCreateBorder().setImage(null);
    } else {
        Shader shader = WXResourceUtils.getShader(bgImage, mDomObj.getLayoutWidth(), mDomObj.getLayoutHeight());
        getOrCreateBorder().setImage(shader);
    }
}

18 Source : PCanvas.java
with GNU General Public License v3.0
from victordiaz

@PhonkMethod(description = "Create a linear shader", example = "")
@PhonkMethodParam(params = { "x1", "y1", "x2", "y2", "colorHex1", "colorHex2", "tileMode" })
public Shader linearShader(float x1, float y1, float x2, float y2, String c1, String c2) {
    Shader.TileMode mode = Shader.TileMode.REPEAT;
    Shader shader = new LinearGradient(x1, y1, x2, y2, Color.parseColor(c1), Color.parseColor(c2), mode);
    return shader;
}

18 Source : ColorPickerView.java
with Apache License 2.0
from vanhung1710

/**
 * Displays a color picker to the user and allow them to select a color. A
 * slider for the alpha channel is also available. Enable it by setting
 * setAlphaSliderVisible(boolean) to true.
 */
public clreplaced ColorPickerView extends View {

    private final static int PANEL_SAT_VAL = 0;

    private final static int PANEL_HUE = 1;

    private final static int PANEL_ALPHA = 2;

    /**
     * The width in pixels of the border surrounding all color panels.
     */
    private final static float BORDER_WIDTH_PX = 1;

    /**
     * The width in dp of the hue panel.
     */
    private float HUE_PANEL_WIDTH = 30f;

    /**
     * The height in dp of the alpha panel
     */
    private float ALPHA_PANEL_HEIGHT = 20f;

    /**
     * The distance in dp between the different color panels.
     */
    private float PANEL_SPACING = 10f;

    /**
     * The radius in dp of the color palette tracker circle.
     */
    private float PALETTE_CIRCLE_TRACKER_RADIUS = 5f;

    /**
     * The dp which the tracker of the hue or alpha panel will extend outside of
     * its bounds.
     */
    private float RECTANGLE_TRACKER_OFFSET = 2f;

    private float mDensity = 1f;

    private OnColorChangedListener mListener;

    private Paint mSatValPaint;

    private Paint mSatValTrackerPaint;

    private Paint mHuePaint;

    private Paint mHueTrackerPaint;

    private Paint mAlphaPaint;

    private Paint mAlphaTextPaint;

    private Paint mBorderPaint;

    private Shader mValShader;

    private Shader mSatShader;

    private Shader mHueShader;

    private Shader mAlphaShader;

    private int mAlpha = 0xff;

    private float mHue = 360f;

    private float mSat = 0f;

    private float mVal = 0f;

    private String mAlphaSliderText = "";

    private int mSliderTrackerColor = 0xff1c1c1c;

    private int mBorderColor = 0xff6E6E6E;

    private boolean mShowAlphaPanel = false;

    /*
	 * To remember which panel that has the "focus" when processing hardware
	 * button data.
	 */
    private int mLastTouchedPanel = PANEL_SAT_VAL;

    /**
     * Offset from the edge we must have or else the finger tracker will get
     * clipped when it is drawn outside of the view.
     */
    private float mDrawingOffset;

    /*
	 * Distance form the edges of the view of where we are allowed to draw.
	 */
    private RectF mDrawingRect;

    private RectF mSatValRect;

    private RectF mHueRect;

    private RectF mAlphaRect;

    private AlphaPatternDrawable mAlphaPattern;

    private Point mStartTouchPoint = null;

    public interface OnColorChangedListener {

        public void onColorChanged(int color);
    }

    public ColorPickerView(Context context) {
        this(context, null);
    }

    public ColorPickerView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ColorPickerView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    private void init() {
        mDensity = getContext().getResources().getDisplayMetrics().density;
        PALETTE_CIRCLE_TRACKER_RADIUS *= mDensity;
        RECTANGLE_TRACKER_OFFSET *= mDensity;
        HUE_PANEL_WIDTH *= mDensity;
        ALPHA_PANEL_HEIGHT *= mDensity;
        PANEL_SPACING = PANEL_SPACING * mDensity;
        mDrawingOffset = calculateRequiredOffset();
        initPaintTools();
        // Needed for receiving trackball motion events.
        setFocusable(true);
        setFocusableInTouchMode(true);
    }

    private void initPaintTools() {
        mSatValPaint = new Paint();
        mSatValTrackerPaint = new Paint();
        mHuePaint = new Paint();
        mHueTrackerPaint = new Paint();
        mAlphaPaint = new Paint();
        mAlphaTextPaint = new Paint();
        mBorderPaint = new Paint();
        mSatValTrackerPaint.setStyle(Style.STROKE);
        mSatValTrackerPaint.setStrokeWidth(2f * mDensity);
        mSatValTrackerPaint.setAntiAlias(true);
        mHueTrackerPaint.setColor(mSliderTrackerColor);
        mHueTrackerPaint.setStyle(Style.STROKE);
        mHueTrackerPaint.setStrokeWidth(2f * mDensity);
        mHueTrackerPaint.setAntiAlias(true);
        mAlphaTextPaint.setColor(0xff1c1c1c);
        mAlphaTextPaint.setTextSize(14f * mDensity);
        mAlphaTextPaint.setAntiAlias(true);
        mAlphaTextPaint.setTextAlign(Align.CENTER);
        mAlphaTextPaint.setFakeBoldText(true);
    }

    private float calculateRequiredOffset() {
        float offset = Math.max(PALETTE_CIRCLE_TRACKER_RADIUS, RECTANGLE_TRACKER_OFFSET);
        offset = Math.max(offset, BORDER_WIDTH_PX * mDensity);
        return offset * 1.5f;
    }

    private int[] buildHueColorArray() {
        int[] hue = new int[361];
        int count = 0;
        for (int i = hue.length - 1; i >= 0; i--, count++) {
            hue[count] = Color.HSVToColor(new float[] { i, 1f, 1f });
        }
        return hue;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        if (mDrawingRect.width() <= 0 || mDrawingRect.height() <= 0)
            return;
        drawSatValPanel(canvas);
        drawHuePanel(canvas);
        drawAlphaPanel(canvas);
    }

    private void drawSatValPanel(Canvas canvas) {
        final RectF rect = mSatValRect;
        if (BORDER_WIDTH_PX > 0) {
            mBorderPaint.setColor(mBorderColor);
            canvas.drawRect(mDrawingRect.left, mDrawingRect.top, rect.right + BORDER_WIDTH_PX, rect.bottom + BORDER_WIDTH_PX, mBorderPaint);
        }
        if (mValShader == null) {
            mValShader = new LinearGradient(rect.left, rect.top, rect.left, rect.bottom, 0xffffffff, 0xff000000, TileMode.CLAMP);
        }
        int rgb = Color.HSVToColor(new float[] { mHue, 1f, 1f });
        mSatShader = new LinearGradient(rect.left, rect.top, rect.right, rect.top, 0xffffffff, rgb, TileMode.CLAMP);
        ComposeShader mShader = new ComposeShader(mValShader, mSatShader, PorterDuff.Mode.MULTIPLY);
        mSatValPaint.setShader(mShader);
        canvas.drawRect(rect, mSatValPaint);
        Point p = satValToPoint(mSat, mVal);
        mSatValTrackerPaint.setColor(0xff000000);
        canvas.drawCircle(p.x, p.y, PALETTE_CIRCLE_TRACKER_RADIUS - 1f * mDensity, mSatValTrackerPaint);
        mSatValTrackerPaint.setColor(0xffdddddd);
        canvas.drawCircle(p.x, p.y, PALETTE_CIRCLE_TRACKER_RADIUS, mSatValTrackerPaint);
    }

    private void drawHuePanel(Canvas canvas) {
        final RectF rect = mHueRect;
        if (BORDER_WIDTH_PX > 0) {
            mBorderPaint.setColor(mBorderColor);
            canvas.drawRect(rect.left - BORDER_WIDTH_PX, rect.top - BORDER_WIDTH_PX, rect.right + BORDER_WIDTH_PX, rect.bottom + BORDER_WIDTH_PX, mBorderPaint);
        }
        if (mHueShader == null) {
            mHueShader = new LinearGradient(rect.left, rect.top, rect.left, rect.bottom, buildHueColorArray(), null, TileMode.CLAMP);
            mHuePaint.setShader(mHueShader);
        }
        canvas.drawRect(rect, mHuePaint);
        float rectHeight = 4 * mDensity / 2;
        Point p = hueToPoint(mHue);
        RectF r = new RectF();
        r.left = rect.left - RECTANGLE_TRACKER_OFFSET;
        r.right = rect.right + RECTANGLE_TRACKER_OFFSET;
        r.top = p.y - rectHeight;
        r.bottom = p.y + rectHeight;
        canvas.drawRoundRect(r, 2, 2, mHueTrackerPaint);
    }

    private void drawAlphaPanel(Canvas canvas) {
        if (!mShowAlphaPanel || mAlphaRect == null || mAlphaPattern == null)
            return;
        final RectF rect = mAlphaRect;
        if (BORDER_WIDTH_PX > 0) {
            mBorderPaint.setColor(mBorderColor);
            canvas.drawRect(rect.left - BORDER_WIDTH_PX, rect.top - BORDER_WIDTH_PX, rect.right + BORDER_WIDTH_PX, rect.bottom + BORDER_WIDTH_PX, mBorderPaint);
        }
        mAlphaPattern.draw(canvas);
        float[] hsv = new float[] { mHue, mSat, mVal };
        int color = Color.HSVToColor(hsv);
        int acolor = Color.HSVToColor(0, hsv);
        mAlphaShader = new LinearGradient(rect.left, rect.top, rect.right, rect.top, color, acolor, TileMode.CLAMP);
        mAlphaPaint.setShader(mAlphaShader);
        canvas.drawRect(rect, mAlphaPaint);
        if (mAlphaSliderText != null && mAlphaSliderText != "") {
            canvas.drawText(mAlphaSliderText, rect.centerX(), rect.centerY() + 4 * mDensity, mAlphaTextPaint);
        }
        float rectWidth = 4 * mDensity / 2;
        Point p = alphaToPoint(mAlpha);
        RectF r = new RectF();
        r.left = p.x - rectWidth;
        r.right = p.x + rectWidth;
        r.top = rect.top - RECTANGLE_TRACKER_OFFSET;
        r.bottom = rect.bottom + RECTANGLE_TRACKER_OFFSET;
        canvas.drawRoundRect(r, 2, 2, mHueTrackerPaint);
    }

    private Point hueToPoint(float hue) {
        final RectF rect = mHueRect;
        final float height = rect.height();
        Point p = new Point();
        p.y = (int) (height - (hue * height / 360f) + rect.top);
        p.x = (int) rect.left;
        return p;
    }

    private Point satValToPoint(float sat, float val) {
        final RectF rect = mSatValRect;
        final float height = rect.height();
        final float width = rect.width();
        Point p = new Point();
        p.x = (int) (sat * width + rect.left);
        p.y = (int) ((1f - val) * height + rect.top);
        return p;
    }

    private Point alphaToPoint(int alpha) {
        final RectF rect = mAlphaRect;
        final float width = rect.width();
        Point p = new Point();
        p.x = (int) (width - (alpha * width / 0xff) + rect.left);
        p.y = (int) rect.top;
        return p;
    }

    private float[] pointToSatVal(float x, float y) {
        final RectF rect = mSatValRect;
        float[] result = new float[2];
        float width = rect.width();
        float height = rect.height();
        if (x < rect.left) {
            x = 0f;
        } else if (x > rect.right) {
            x = width;
        } else {
            x = x - rect.left;
        }
        if (y < rect.top) {
            y = 0f;
        } else if (y > rect.bottom) {
            y = height;
        } else {
            y = y - rect.top;
        }
        result[0] = 1.f / width * x;
        result[1] = 1.f - (1.f / height * y);
        return result;
    }

    private float pointToHue(float y) {
        final RectF rect = mHueRect;
        float height = rect.height();
        if (y < rect.top) {
            y = 0f;
        } else if (y > rect.bottom) {
            y = height;
        } else {
            y = y - rect.top;
        }
        return 360f - (y * 360f / height);
    }

    private int pointToAlpha(int x) {
        final RectF rect = mAlphaRect;
        final int width = (int) rect.width();
        if (x < rect.left) {
            x = 0;
        } else if (x > rect.right) {
            x = width;
        } else {
            x = x - (int) rect.left;
        }
        return 0xff - (x * 0xff / width);
    }

    @Override
    public boolean onTrackballEvent(MotionEvent event) {
        float x = event.getX();
        float y = event.getY();
        boolean update = false;
        if (event.getAction() == MotionEvent.ACTION_MOVE) {
            switch(mLastTouchedPanel) {
                case PANEL_SAT_VAL:
                    float sat, val;
                    sat = mSat + x / 50f;
                    val = mVal - y / 50f;
                    if (sat < 0f) {
                        sat = 0f;
                    } else if (sat > 1f) {
                        sat = 1f;
                    }
                    if (val < 0f) {
                        val = 0f;
                    } else if (val > 1f) {
                        val = 1f;
                    }
                    mSat = sat;
                    mVal = val;
                    update = true;
                    break;
                case PANEL_HUE:
                    float hue = mHue - y * 10f;
                    if (hue < 0f) {
                        hue = 0f;
                    } else if (hue > 360f) {
                        hue = 360f;
                    }
                    mHue = hue;
                    update = true;
                    break;
                case PANEL_ALPHA:
                    if (!mShowAlphaPanel || mAlphaRect == null) {
                        update = false;
                    } else {
                        int alpha = (int) (mAlpha - x * 10);
                        if (alpha < 0) {
                            alpha = 0;
                        } else if (alpha > 0xff) {
                            alpha = 0xff;
                        }
                        mAlpha = alpha;
                        update = true;
                    }
                    break;
            }
        }
        if (update) {
            if (mListener != null) {
                mListener.onColorChanged(Color.HSVToColor(mAlpha, new float[] { mHue, mSat, mVal }));
            }
            invalidate();
            return true;
        }
        return super.onTrackballEvent(event);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        boolean update = false;
        switch(event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mStartTouchPoint = new Point((int) event.getX(), (int) event.getY());
                update = moveTrackersIfNeeded(event);
                break;
            case MotionEvent.ACTION_MOVE:
                update = moveTrackersIfNeeded(event);
                break;
            case MotionEvent.ACTION_UP:
                mStartTouchPoint = null;
                update = moveTrackersIfNeeded(event);
                break;
        }
        if (update) {
            if (mListener != null) {
                mListener.onColorChanged(Color.HSVToColor(mAlpha, new float[] { mHue, mSat, mVal }));
            }
            invalidate();
            return true;
        }
        return super.onTouchEvent(event);
    }

    private boolean moveTrackersIfNeeded(MotionEvent event) {
        if (mStartTouchPoint == null)
            return false;
        boolean update = false;
        int startX = mStartTouchPoint.x;
        int startY = mStartTouchPoint.y;
        if (mHueRect.contains(startX, startY)) {
            mLastTouchedPanel = PANEL_HUE;
            mHue = pointToHue(event.getY());
            update = true;
        } else if (mSatValRect.contains(startX, startY)) {
            mLastTouchedPanel = PANEL_SAT_VAL;
            float[] result = pointToSatVal(event.getX(), event.getY());
            mSat = result[0];
            mVal = result[1];
            update = true;
        } else if (mAlphaRect != null && mAlphaRect.contains(startX, startY)) {
            mLastTouchedPanel = PANEL_ALPHA;
            mAlpha = pointToAlpha((int) event.getX());
            update = true;
        }
        return update;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int width = 0;
        int height = 0;
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int widthAllowed = MeasureSpec.getSize(widthMeasureSpec);
        int heightAllowed = MeasureSpec.getSize(heightMeasureSpec);
        widthAllowed = chooseWidth(widthMode, widthAllowed);
        heightAllowed = chooseHeight(heightMode, heightAllowed);
        if (!mShowAlphaPanel) {
            height = (int) (widthAllowed - PANEL_SPACING - HUE_PANEL_WIDTH);
            // If calculated height (based on the width) is more than the
            // allowed height.
            if (height > heightAllowed || getTag().equals("landscape")) {
                height = heightAllowed;
                width = (int) (height + PANEL_SPACING + HUE_PANEL_WIDTH);
            } else {
                width = widthAllowed;
            }
        } else {
            width = (int) (heightAllowed - ALPHA_PANEL_HEIGHT + HUE_PANEL_WIDTH);
            if (width > widthAllowed) {
                width = widthAllowed;
                height = (int) (widthAllowed - HUE_PANEL_WIDTH + ALPHA_PANEL_HEIGHT);
            } else {
                height = heightAllowed;
            }
        }
        setMeasuredDimension(width, height);
    }

    private int chooseWidth(int mode, int size) {
        if (mode == MeasureSpec.AT_MOST || mode == MeasureSpec.EXACTLY) {
            return size;
        } else {
            // (mode == MeasureSpec.UNSPECIFIED)
            return getPrefferedWidth();
        }
    }

    private int chooseHeight(int mode, int size) {
        if (mode == MeasureSpec.AT_MOST || mode == MeasureSpec.EXACTLY) {
            return size;
        } else {
            // (mode == MeasureSpec.UNSPECIFIED)
            return getPrefferedHeight();
        }
    }

    private int getPrefferedWidth() {
        int width = getPrefferedHeight();
        if (mShowAlphaPanel) {
            width -= (PANEL_SPACING + ALPHA_PANEL_HEIGHT);
        }
        return (int) (width + HUE_PANEL_WIDTH + PANEL_SPACING);
    }

    private int getPrefferedHeight() {
        int height = (int) (200 * mDensity);
        if (mShowAlphaPanel) {
            height += PANEL_SPACING + ALPHA_PANEL_HEIGHT;
        }
        return height;
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mDrawingRect = new RectF();
        mDrawingRect.left = mDrawingOffset + getPaddingLeft();
        mDrawingRect.right = w - mDrawingOffset - getPaddingRight();
        mDrawingRect.top = mDrawingOffset + getPaddingTop();
        mDrawingRect.bottom = h - mDrawingOffset - getPaddingBottom();
        setUpSatValRect();
        setUpHueRect();
        setUpAlphaRect();
    }

    private void setUpSatValRect() {
        final RectF dRect = mDrawingRect;
        float panelSide = dRect.height() - BORDER_WIDTH_PX * 2;
        if (mShowAlphaPanel) {
            panelSide -= PANEL_SPACING + ALPHA_PANEL_HEIGHT;
        }
        float left = dRect.left + BORDER_WIDTH_PX;
        float top = dRect.top + BORDER_WIDTH_PX;
        float bottom = top + panelSide;
        float right = left + panelSide;
        mSatValRect = new RectF(left, top, right, bottom);
    }

    private void setUpHueRect() {
        final RectF dRect = mDrawingRect;
        float left = dRect.right - HUE_PANEL_WIDTH + BORDER_WIDTH_PX;
        float top = dRect.top + BORDER_WIDTH_PX;
        float bottom = dRect.bottom - BORDER_WIDTH_PX - (mShowAlphaPanel ? (PANEL_SPACING + ALPHA_PANEL_HEIGHT) : 0);
        float right = dRect.right - BORDER_WIDTH_PX;
        mHueRect = new RectF(left, top, right, bottom);
    }

    private void setUpAlphaRect() {
        if (!mShowAlphaPanel)
            return;
        final RectF dRect = mDrawingRect;
        float left = dRect.left + BORDER_WIDTH_PX;
        float top = dRect.bottom - ALPHA_PANEL_HEIGHT + BORDER_WIDTH_PX;
        float bottom = dRect.bottom - BORDER_WIDTH_PX;
        float right = dRect.right - BORDER_WIDTH_PX;
        mAlphaRect = new RectF(left, top, right, bottom);
        mAlphaPattern = new AlphaPatternDrawable((int) (5 * mDensity));
        mAlphaPattern.setBounds(Math.round(mAlphaRect.left), Math.round(mAlphaRect.top), Math.round(mAlphaRect.right), Math.round(mAlphaRect.bottom));
    }

    /**
     * Set a OnColorChangedListener to get notified when the color selected by
     * the user has changed.
     *
     * @param listener
     */
    public void setOnColorChangedListener(OnColorChangedListener listener) {
        mListener = listener;
    }

    /**
     * Set the color of the border surrounding all panels.
     *
     * @param color
     */
    public void setBorderColor(int color) {
        mBorderColor = color;
        invalidate();
    }

    /**
     * Get the color of the border surrounding all panels.
     */
    public int getBorderColor() {
        return mBorderColor;
    }

    /**
     * Get the current color this view is showing.
     *
     * @return the current color.
     */
    public int getColor() {
        return Color.HSVToColor(mAlpha, new float[] { mHue, mSat, mVal });
    }

    /**
     * Set the color the view should show.
     *
     * @param color
     *            The color that should be selected.
     */
    public void setColor(int color) {
        setColor(color, false);
    }

    /**
     * Set the color this view should show.
     *
     * @param color
     *            The color that should be selected.
     * @param callback
     *            If you want to get a callback to your OnColorChangedListener.
     */
    public void setColor(int color, boolean callback) {
        int alpha = Color.alpha(color);
        float[] hsv = new float[3];
        Color.colorToHSV(color, hsv);
        mAlpha = alpha;
        mHue = hsv[0];
        mSat = hsv[1];
        mVal = hsv[2];
        if (callback && mListener != null) {
            mListener.onColorChanged(Color.HSVToColor(mAlpha, new float[] { mHue, mSat, mVal }));
        }
        invalidate();
    }

    /**
     * Get the drawing offset of the color picker view. The drawing offset is
     * the distance from the side of a panel to the side of the view minus the
     * padding. Useful if you want to have your own panel below showing the
     * currently selected color and want to align it perfectly.
     *
     * @return The offset in pixels.
     */
    public float getDrawingOffset() {
        return mDrawingOffset;
    }

    /**
     * Set if the user is allowed to adjust the alpha panel. Default is false.
     * If it is set to false no alpha will be set.
     *
     * @param visible
     */
    public void setAlphaSliderVisible(boolean visible) {
        if (mShowAlphaPanel != visible) {
            mShowAlphaPanel = visible;
            /*
			 * Reset all shader to force a recreation. Otherwise they will not
			 * look right after the size of the view has changed.
			 */
            mValShader = null;
            mSatShader = null;
            mHueShader = null;
            mAlphaShader = null;
            ;
            requestLayout();
        }
    }

    public boolean getAlphaSliderVisible() {
        return mShowAlphaPanel;
    }

    public void setSliderTrackerColor(int color) {
        mSliderTrackerColor = color;
        mHueTrackerPaint.setColor(mSliderTrackerColor);
        invalidate();
    }

    public int getSliderTrackerColor() {
        return mSliderTrackerColor;
    }

    /**
     * Set the text that should be shown in the alpha slider. Set to null to
     * disable text.
     *
     * @param res
     *            string resource id.
     */
    public void setAlphaSliderText(int res) {
        String text = getContext().getString(res);
        setAlphaSliderText(text);
    }

    /**
     * Set the text that should be shown in the alpha slider. Set to null to
     * disable text.
     *
     * @param text
     *            Text that should be shown.
     */
    public void setAlphaSliderText(String text) {
        mAlphaSliderText = text;
        invalidate();
    }

    /**
     * Get the current value of the text that will be shown in the alpha slider.
     *
     * @return
     */
    public String getAlphaSliderText() {
        return mAlphaSliderText;
    }
}

18 Source : ValueBar.java
with GNU General Public License v3.0
from tianyuan168326

public clreplaced ValueBar extends View {

    /*
	 * Constants used to save/restore the instance state.
	 */
    private static final String STATE_PARENT = "parent";

    private static final String STATE_COLOR = "color";

    private static final String STATE_VALUE = "value";

    private static final String STATE_ORIENTATION = "orientation";

    /**
     * Constants used to identify orientation.
     */
    private static final boolean ORIENTATION_HORIZONTAL = true;

    private static final boolean ORIENTATION_VERTICAL = false;

    /**
     * Default orientation of the bar.
     */
    private static final boolean ORIENTATION_DEFAULT = ORIENTATION_HORIZONTAL;

    /**
     * The thickness of the bar.
     */
    private int mBarThickness;

    /**
     * The length of the bar.
     */
    private int mBarLength;

    private int mPreferredBarLength;

    /**
     * The radius of the pointer.
     */
    private int mBarPointerRadius;

    /**
     * The radius of the halo of the pointer.
     */
    private int mBarPointerHaloRadius;

    /**
     * The position of the pointer on the bar.
     */
    private int mBarPointerPosition;

    /**
     * {@code Paint} instance used to draw the bar.
     */
    private Paint mBarPaint;

    /**
     * {@code Paint} instance used to draw the pointer.
     */
    private Paint mBarPointerPaint;

    /**
     * {@code Paint} instance used to draw the halo of the pointer.
     */
    private Paint mBarPointerHaloPaint;

    /**
     * The rectangle enclosing the bar.
     */
    private RectF mBarRect = new RectF();

    /**
     * {@code Shader} instance used to fill the shader of the paint.
     */
    private Shader shader;

    /**
     * {@code true} if the user clicked on the pointer to start the move mode. <br>
     * {@code false} once the user stops touching the screen.
     *
     * @see #onTouchEvent(android.view.MotionEvent)
     */
    private boolean mIsMovingPointer;

    /**
     * The ARGB value of the currently selected color.
     */
    private int mColor;

    /**
     * An array of floats that can be build into a {@code Color} <br>
     * Where we can extract the color from.
     */
    private float[] mHSVColor = new float[3];

    /**
     * Factor used to calculate the position to the Opacity on the bar.
     */
    private float mPosToSatFactor;

    /**
     * Factor used to calculate the Opacity to the postion on the bar.
     */
    private float mSatToPosFactor;

    /**
     * {@code ColorPicker} instance used to control the ColorPicker.
     */
    private ColorPicker mPicker = null;

    /**
     * Used to toggle orientation between vertical and horizontal.
     */
    private boolean mOrientation;

    /**
     * Interface and listener so that changes in ValueBar are sent
     * to the host activity/fragment
     */
    private OnValueChangedListener onValueChangedListener;

    /**
     * Value of the latest entry of the onValueChangedListener.
     */
    private int oldChangedListenerValue;

    public interface OnValueChangedListener {

        public void onValueChanged(int value);
    }

    public void setOnValueChangedListener(OnValueChangedListener listener) {
        this.onValueChangedListener = listener;
    }

    public OnValueChangedListener getOnValueChangedListener() {
        return this.onValueChangedListener;
    }

    public ValueBar(Context context) {
        super(context);
        init(null, 0);
    }

    public ValueBar(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(attrs, 0);
    }

    public ValueBar(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(attrs, defStyle);
    }

    private void init(AttributeSet attrs, int defStyle) {
        final TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.ColorBars, defStyle, 0);
        final Resources b = getContext().getResources();
        mBarThickness = a.getDimensionPixelSize(R.styleable.ColorBars_bar_thickness, b.getDimensionPixelSize(R.dimen.bar_thickness));
        mBarLength = a.getDimensionPixelSize(R.styleable.ColorBars_bar_length, b.getDimensionPixelSize(R.dimen.bar_length));
        mPreferredBarLength = mBarLength;
        mBarPointerRadius = a.getDimensionPixelSize(R.styleable.ColorBars_bar_pointer_radius, b.getDimensionPixelSize(R.dimen.bar_pointer_radius));
        mBarPointerHaloRadius = a.getDimensionPixelSize(R.styleable.ColorBars_bar_pointer_halo_radius, b.getDimensionPixelSize(R.dimen.bar_pointer_halo_radius));
        mOrientation = a.getBoolean(R.styleable.ColorBars_bar_orientation_horizontal, ORIENTATION_DEFAULT);
        a.recycle();
        mBarPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mBarPaint.setShader(shader);
        mBarPointerPosition = mBarPointerHaloRadius;
        mBarPointerHaloPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mBarPointerHaloPaint.setColor(Color.BLACK);
        mBarPointerHaloPaint.setAlpha(0x50);
        mBarPointerPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mBarPointerPaint.setColor(0xff81ff00);
        mPosToSatFactor = 1 / ((float) mBarLength);
        mSatToPosFactor = ((float) mBarLength) / 1;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        final int intrinsicSize = mPreferredBarLength + (mBarPointerHaloRadius * 2);
        // Variable orientation
        int measureSpec;
        if (mOrientation == ORIENTATION_HORIZONTAL) {
            measureSpec = widthMeasureSpec;
        } else {
            measureSpec = heightMeasureSpec;
        }
        int lengthMode = MeasureSpec.getMode(measureSpec);
        int lengthSize = MeasureSpec.getSize(measureSpec);
        int length;
        if (lengthMode == MeasureSpec.EXACTLY) {
            length = lengthSize;
        } else if (lengthMode == MeasureSpec.AT_MOST) {
            length = Math.min(intrinsicSize, lengthSize);
        } else {
            length = intrinsicSize;
        }
        int barPointerHaloRadiusx2 = mBarPointerHaloRadius * 2;
        mBarLength = length - barPointerHaloRadiusx2;
        if (mOrientation == ORIENTATION_VERTICAL) {
            setMeasuredDimension(barPointerHaloRadiusx2, (mBarLength + barPointerHaloRadiusx2));
        } else {
            setMeasuredDimension((mBarLength + barPointerHaloRadiusx2), barPointerHaloRadiusx2);
        }
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        // Fill the rectangle instance based on orientation
        int x1, y1;
        if (mOrientation == ORIENTATION_HORIZONTAL) {
            x1 = (mBarLength + mBarPointerHaloRadius);
            y1 = mBarThickness;
            mBarLength = w - (mBarPointerHaloRadius * 2);
            mBarRect.set(mBarPointerHaloRadius, (mBarPointerHaloRadius - (mBarThickness / 2)), (mBarLength + (mBarPointerHaloRadius)), (mBarPointerHaloRadius + (mBarThickness / 2)));
        } else {
            x1 = mBarThickness;
            y1 = (mBarLength + mBarPointerHaloRadius);
            mBarLength = h - (mBarPointerHaloRadius * 2);
            mBarRect.set((mBarPointerHaloRadius - (mBarThickness / 2)), mBarPointerHaloRadius, (mBarPointerHaloRadius + (mBarThickness / 2)), (mBarLength + (mBarPointerHaloRadius)));
        }
        // Update variables that depend of mBarLength.
        if (!isInEditMode()) {
            shader = new LinearGradient(mBarPointerHaloRadius, 0, x1, y1, new int[] { Color.HSVToColor(0xFF, mHSVColor), Color.BLACK }, null, Shader.TileMode.CLAMP);
        } else {
            shader = new LinearGradient(mBarPointerHaloRadius, 0, x1, y1, new int[] { 0xff81ff00, Color.BLACK }, null, Shader.TileMode.CLAMP);
            Color.colorToHSV(0xff81ff00, mHSVColor);
        }
        mBarPaint.setShader(shader);
        mPosToSatFactor = 1 / ((float) mBarLength);
        mSatToPosFactor = ((float) mBarLength) / 1;
        float[] hsvColor = new float[3];
        Color.colorToHSV(mColor, hsvColor);
        if (!isInEditMode()) {
            mBarPointerPosition = Math.round((mBarLength - (mSatToPosFactor * hsvColor[2])) + mBarPointerHaloRadius);
        } else {
            mBarPointerPosition = mBarPointerHaloRadius;
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        // Draw the bar.
        canvas.drawRect(mBarRect, mBarPaint);
        // Calculate the center of the pointer.
        int cX, cY;
        if (mOrientation == ORIENTATION_HORIZONTAL) {
            cX = mBarPointerPosition;
            cY = mBarPointerHaloRadius;
        } else {
            cX = mBarPointerHaloRadius;
            cY = mBarPointerPosition;
        }
        // Draw the pointer halo.
        canvas.drawCircle(cX, cY, mBarPointerHaloRadius, mBarPointerHaloPaint);
        // Draw the pointer.
        canvas.drawCircle(cX, cY, mBarPointerRadius, mBarPointerPaint);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        getParent().requestDisallowInterceptTouchEvent(true);
        // Convert coordinates to our internal coordinate system
        float dimen;
        if (mOrientation == ORIENTATION_HORIZONTAL) {
            dimen = event.getX();
        } else {
            dimen = event.getY();
        }
        switch(event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mIsMovingPointer = true;
                // Check whether the user pressed on (or near) the pointer
                if (dimen >= (mBarPointerHaloRadius) && dimen <= (mBarPointerHaloRadius + mBarLength)) {
                    mBarPointerPosition = Math.round(dimen);
                    calculateColor(Math.round(dimen));
                    mBarPointerPaint.setColor(mColor);
                    invalidate();
                }
                break;
            case MotionEvent.ACTION_MOVE:
                if (mIsMovingPointer) {
                    // Move the the pointer on the bar.
                    if (dimen >= mBarPointerHaloRadius && dimen <= (mBarPointerHaloRadius + mBarLength)) {
                        mBarPointerPosition = Math.round(dimen);
                        calculateColor(Math.round(dimen));
                        mBarPointerPaint.setColor(mColor);
                        if (mPicker != null) {
                            mPicker.setNewCenterColor(mColor);
                            mPicker.changeOpacityBarColor(mColor);
                        }
                        invalidate();
                    } else if (dimen < mBarPointerHaloRadius) {
                        mBarPointerPosition = mBarPointerHaloRadius;
                        mColor = Color.HSVToColor(mHSVColor);
                        mBarPointerPaint.setColor(mColor);
                        if (mPicker != null) {
                            mPicker.setNewCenterColor(mColor);
                            mPicker.changeOpacityBarColor(mColor);
                        }
                        invalidate();
                    } else if (dimen > (mBarPointerHaloRadius + mBarLength)) {
                        mBarPointerPosition = mBarPointerHaloRadius + mBarLength;
                        mColor = Color.BLACK;
                        mBarPointerPaint.setColor(mColor);
                        if (mPicker != null) {
                            mPicker.setNewCenterColor(mColor);
                            mPicker.changeOpacityBarColor(mColor);
                        }
                        invalidate();
                    }
                }
                if (onValueChangedListener != null && oldChangedListenerValue != mColor) {
                    onValueChangedListener.onValueChanged(mColor);
                    oldChangedListenerValue = mColor;
                }
                break;
            case MotionEvent.ACTION_UP:
                mIsMovingPointer = false;
                break;
        }
        return true;
    }

    /**
     * Set the bar color. <br>
     * <br>
     * Its discouraged to use this method.
     *
     * @param color
     */
    public void setColor(int color) {
        int x1, y1;
        if (mOrientation == ORIENTATION_HORIZONTAL) {
            x1 = (mBarLength + mBarPointerHaloRadius);
            y1 = mBarThickness;
        } else {
            x1 = mBarThickness;
            y1 = (mBarLength + mBarPointerHaloRadius);
        }
        Color.colorToHSV(color, mHSVColor);
        shader = new LinearGradient(mBarPointerHaloRadius, 0, x1, y1, new int[] { color, Color.BLACK }, null, Shader.TileMode.CLAMP);
        mBarPaint.setShader(shader);
        calculateColor(mBarPointerPosition);
        mBarPointerPaint.setColor(mColor);
        if (mPicker != null) {
            mPicker.setNewCenterColor(mColor);
            if (mPicker.hasOpacityBar())
                mPicker.changeOpacityBarColor(mColor);
        }
        invalidate();
    }

    /**
     * Set the pointer on the bar. With the opacity value.
     *
     * @param value float between 0 and 1
     */
    public void setValue(float value) {
        mBarPointerPosition = Math.round((mBarLength - (mSatToPosFactor * value)) + mBarPointerHaloRadius);
        calculateColor(mBarPointerPosition);
        mBarPointerPaint.setColor(mColor);
        if (mPicker != null) {
            mPicker.setNewCenterColor(mColor);
            mPicker.changeOpacityBarColor(mColor);
        }
        invalidate();
    }

    /**
     * Calculate the color selected by the pointer on the bar.
     *
     * @param coord Coordinate of the pointer.
     */
    private void calculateColor(int coord) {
        coord = coord - mBarPointerHaloRadius;
        if (coord < 0) {
            coord = 0;
        } else if (coord > mBarLength) {
            coord = mBarLength;
        }
        mColor = Color.HSVToColor(new float[] { mHSVColor[0], mHSVColor[1], (float) (1 - (mPosToSatFactor * coord)) });
    }

    /**
     * Get the currently selected color.
     *
     * @return The ARGB value of the currently selected color.
     */
    public int getColor() {
        return mColor;
    }

    /**
     * Adds a {@code ColorPicker} instance to the bar. <br>
     * <br>
     * WARNING: Don't change the color picker. it is done already when the bar
     * is added to the ColorPicker
     *
     * @see com.larswerkman.holocolorpicker.ColorPicker#addSVBar(com.larswerkman.holocolorpicker.SVBar)
     * @param picker
     */
    public void setColorPicker(ColorPicker picker) {
        mPicker = picker;
    }

    @Override
    protected Parcelable onSaveInstanceState() {
        Parcelable superState = super.onSaveInstanceState();
        Bundle state = new Bundle();
        state.putParcelable(STATE_PARENT, superState);
        state.putFloatArray(STATE_COLOR, mHSVColor);
        float[] hsvColor = new float[3];
        Color.colorToHSV(mColor, hsvColor);
        state.putFloat(STATE_VALUE, hsvColor[2]);
        return state;
    }

    @Override
    protected void onRestoreInstanceState(Parcelable state) {
        Bundle savedState = (Bundle) state;
        Parcelable superState = savedState.getParcelable(STATE_PARENT);
        super.onRestoreInstanceState(superState);
        setColor(Color.HSVToColor(savedState.getFloatArray(STATE_COLOR)));
        setValue(savedState.getFloat(STATE_VALUE));
    }
}

18 Source : SVBar.java
with GNU General Public License v3.0
from tianyuan168326

public clreplaced SVBar extends View {

    /*
	 * Constants used to save/restore the instance state.
	 */
    private static final String STATE_PARENT = "parent";

    private static final String STATE_COLOR = "color";

    private static final String STATE_SATURATION = "saturation";

    private static final String STATE_VALUE = "value";

    private static final String STATE_ORIENTATION = "orientation";

    /**
     * Constants used to identify orientation.
     */
    private static final boolean ORIENTATION_HORIZONTAL = true;

    private static final boolean ORIENTATION_VERTICAL = false;

    /**
     * Default orientation of the bar.
     */
    private static final boolean ORIENTATION_DEFAULT = ORIENTATION_HORIZONTAL;

    /**
     * The thickness of the bar.
     */
    private int mBarThickness;

    /**
     * The length of the bar.
     */
    private int mBarLength;

    private int mPreferredBarLength;

    /**
     * The radius of the pointer.
     */
    private int mBarPointerRadius;

    /**
     * The radius of the halo of the pointer.
     */
    private int mBarPointerHaloRadius;

    /**
     * The position of the pointer on the bar.
     */
    private int mBarPointerPosition;

    /**
     * {@code Paint} instance used to draw the bar.
     */
    private Paint mBarPaint;

    /**
     * {@code Paint} instance used to draw the pointer.
     */
    private Paint mBarPointerPaint;

    /**
     * {@code Paint} instance used to draw the halo of the pointer.
     */
    private Paint mBarPointerHaloPaint;

    /**
     * The rectangle enclosing the bar.
     */
    private RectF mBarRect = new RectF();

    /**
     * {@code Shader} instance used to fill the shader of the paint.
     */
    private Shader shader;

    /**
     * {@code true} if the user clicked on the pointer to start the move mode. <br>
     * {@code false} once the user stops touching the screen.
     *
     * @see #onTouchEvent(android.view.MotionEvent)
     */
    private boolean mIsMovingPointer;

    /**
     * The ARGB value of the currently selected color.
     */
    private int mColor;

    /**
     * An array of floats that can be build into a {@code Color} <br>
     * Where we can extract the Saturation and Value from.
     */
    private float[] mHSVColor = new float[3];

    /**
     * Factor used to calculate the position to the Saturation/Value on the bar.
     */
    private float mPosToSVFactor;

    /**
     * Factor used to calculate the Saturation/Value to the postion on the bar.
     */
    private float mSVToPosFactor;

    /**
     * {@code ColorPicker} instance used to control the ColorPicker.
     */
    private ColorPicker mPicker = null;

    /**
     * Used to toggle orientation between vertical and horizontal.
     */
    private boolean mOrientation;

    public SVBar(Context context) {
        super(context);
        init(null, 0);
    }

    public SVBar(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(attrs, 0);
    }

    public SVBar(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(attrs, defStyle);
    }

    private void init(AttributeSet attrs, int defStyle) {
        final TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.ColorBars, defStyle, 0);
        final Resources b = getContext().getResources();
        mBarThickness = a.getDimensionPixelSize(R.styleable.ColorBars_bar_thickness, b.getDimensionPixelSize(R.dimen.bar_thickness));
        mBarLength = a.getDimensionPixelSize(R.styleable.ColorBars_bar_length, b.getDimensionPixelSize(R.dimen.bar_length));
        mPreferredBarLength = mBarLength;
        mBarPointerRadius = a.getDimensionPixelSize(R.styleable.ColorBars_bar_pointer_radius, b.getDimensionPixelSize(R.dimen.bar_pointer_radius));
        mBarPointerHaloRadius = a.getDimensionPixelSize(R.styleable.ColorBars_bar_pointer_halo_radius, b.getDimensionPixelSize(R.dimen.bar_pointer_halo_radius));
        mOrientation = a.getBoolean(R.styleable.ColorBars_bar_orientation_horizontal, ORIENTATION_DEFAULT);
        a.recycle();
        mBarPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mBarPaint.setShader(shader);
        mBarPointerPosition = (mBarLength / 2) + mBarPointerHaloRadius;
        mBarPointerHaloPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mBarPointerHaloPaint.setColor(Color.BLACK);
        mBarPointerHaloPaint.setAlpha(0x50);
        mBarPointerPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mBarPointerPaint.setColor(0xff81ff00);
        mPosToSVFactor = 1 / ((float) mBarLength / 2);
        mSVToPosFactor = ((float) mBarLength / 2) / 1;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        final int intrinsicSize = mPreferredBarLength + (mBarPointerHaloRadius * 2);
        // Variable orientation
        int measureSpec;
        if (mOrientation == ORIENTATION_HORIZONTAL) {
            measureSpec = widthMeasureSpec;
        } else {
            measureSpec = heightMeasureSpec;
        }
        int lengthMode = MeasureSpec.getMode(measureSpec);
        int lengthSize = MeasureSpec.getSize(measureSpec);
        int length;
        if (lengthMode == MeasureSpec.EXACTLY) {
            length = lengthSize;
        } else if (lengthMode == MeasureSpec.AT_MOST) {
            length = Math.min(intrinsicSize, lengthSize);
        } else {
            length = intrinsicSize;
        }
        int barPointerHaloRadiusx2 = mBarPointerHaloRadius * 2;
        mBarLength = length - barPointerHaloRadiusx2;
        if (mOrientation == ORIENTATION_VERTICAL) {
            setMeasuredDimension(barPointerHaloRadiusx2, (mBarLength + barPointerHaloRadiusx2));
        } else {
            setMeasuredDimension((mBarLength + barPointerHaloRadiusx2), barPointerHaloRadiusx2);
        }
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        // Fill the rectangle instance based on orientation
        int x1, y1;
        if (mOrientation == ORIENTATION_HORIZONTAL) {
            x1 = (mBarLength + mBarPointerHaloRadius);
            y1 = mBarThickness;
            mBarLength = w - (mBarPointerHaloRadius * 2);
            mBarRect.set(mBarPointerHaloRadius, (mBarPointerHaloRadius - (mBarThickness / 2)), (mBarLength + (mBarPointerHaloRadius)), (mBarPointerHaloRadius + (mBarThickness / 2)));
        } else {
            x1 = mBarThickness;
            y1 = (mBarLength + mBarPointerHaloRadius);
            mBarLength = h - (mBarPointerHaloRadius * 2);
            mBarRect.set((mBarPointerHaloRadius - (mBarThickness / 2)), mBarPointerHaloRadius, (mBarPointerHaloRadius + (mBarThickness / 2)), (mBarLength + (mBarPointerHaloRadius)));
        }
        // Update variables that depend of mBarLength.
        if (!isInEditMode()) {
            shader = new LinearGradient(mBarPointerHaloRadius, 0, x1, y1, new int[] { 0xffffffff, Color.HSVToColor(mHSVColor), 0xff000000 }, null, Shader.TileMode.CLAMP);
        } else {
            shader = new LinearGradient(mBarPointerHaloRadius, 0, x1, y1, new int[] { 0xffffffff, 0xff81ff00, 0xff000000 }, null, Shader.TileMode.CLAMP);
            Color.colorToHSV(0xff81ff00, mHSVColor);
        }
        mBarPaint.setShader(shader);
        mPosToSVFactor = 1 / ((float) mBarLength / 2);
        mSVToPosFactor = ((float) mBarLength / 2) / 1;
        float[] hsvColor = new float[3];
        Color.colorToHSV(mColor, hsvColor);
        if (hsvColor[1] < hsvColor[2]) {
            mBarPointerPosition = Math.round((mSVToPosFactor * hsvColor[1]) + mBarPointerHaloRadius);
        } else {
            mBarPointerPosition = Math.round((mSVToPosFactor * (1 - hsvColor[2])) + mBarPointerHaloRadius + (mBarLength / 2));
        }
        if (isInEditMode()) {
            mBarPointerPosition = (mBarLength / 2) + mBarPointerHaloRadius;
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        // Draw the bar.
        canvas.drawRect(mBarRect, mBarPaint);
        // Calculate the center of the pointer.
        int cX, cY;
        if (mOrientation == ORIENTATION_HORIZONTAL) {
            cX = mBarPointerPosition;
            cY = mBarPointerHaloRadius;
        } else {
            cX = mBarPointerHaloRadius;
            cY = mBarPointerPosition;
        }
        // Draw the pointer halo.
        canvas.drawCircle(cX, cY, mBarPointerHaloRadius, mBarPointerHaloPaint);
        // Draw the pointer.
        canvas.drawCircle(cX, cY, mBarPointerRadius, mBarPointerPaint);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        getParent().requestDisallowInterceptTouchEvent(true);
        // Convert coordinates to our internal coordinate system
        float dimen;
        if (mOrientation == ORIENTATION_HORIZONTAL) {
            dimen = event.getX();
        } else {
            dimen = event.getY();
        }
        switch(event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mIsMovingPointer = true;
                // Check whether the user pressed on the pointer
                if (dimen >= (mBarPointerHaloRadius) && dimen <= (mBarPointerHaloRadius + mBarLength)) {
                    mBarPointerPosition = Math.round(dimen);
                    calculateColor(Math.round(dimen));
                    mBarPointerPaint.setColor(mColor);
                    invalidate();
                }
                break;
            case MotionEvent.ACTION_MOVE:
                if (mIsMovingPointer) {
                    // Move the the pointer on the bar.
                    if (dimen >= mBarPointerHaloRadius && dimen <= (mBarPointerHaloRadius + mBarLength)) {
                        mBarPointerPosition = Math.round(dimen);
                        calculateColor(Math.round(dimen));
                        mBarPointerPaint.setColor(mColor);
                        if (mPicker != null) {
                            mPicker.setNewCenterColor(mColor);
                            mPicker.changeOpacityBarColor(mColor);
                        }
                        invalidate();
                    } else if (dimen < mBarPointerHaloRadius) {
                        mBarPointerPosition = mBarPointerHaloRadius;
                        mColor = Color.WHITE;
                        mBarPointerPaint.setColor(mColor);
                        if (mPicker != null) {
                            mPicker.setNewCenterColor(mColor);
                            mPicker.changeOpacityBarColor(mColor);
                        }
                        invalidate();
                    } else if (dimen > (mBarPointerHaloRadius + mBarLength)) {
                        mBarPointerPosition = mBarPointerHaloRadius + mBarLength;
                        mColor = Color.BLACK;
                        mBarPointerPaint.setColor(mColor);
                        if (mPicker != null) {
                            mPicker.setNewCenterColor(mColor);
                            mPicker.changeOpacityBarColor(mColor);
                        }
                        invalidate();
                    }
                }
                break;
            case MotionEvent.ACTION_UP:
                mIsMovingPointer = false;
                break;
        }
        return true;
    }

    /**
     * Set the pointer on the bar. With the saturation value.
     *
     * @param saturation float between 0 and 1
     */
    public void setSaturation(float saturation) {
        mBarPointerPosition = Math.round((mSVToPosFactor * saturation) + mBarPointerHaloRadius);
        calculateColor(mBarPointerPosition);
        mBarPointerPaint.setColor(mColor);
        // Check whether the Saturation/Value bar is added to the ColorPicker
        // wheel
        if (mPicker != null) {
            mPicker.setNewCenterColor(mColor);
            mPicker.changeOpacityBarColor(mColor);
        }
        invalidate();
    }

    /**
     * Set the pointer on the bar. With the Value value.
     *
     * @param value float between 0 and 1
     */
    public void setValue(float value) {
        mBarPointerPosition = Math.round((mSVToPosFactor * (1 - value)) + mBarPointerHaloRadius + (mBarLength / 2));
        calculateColor(mBarPointerPosition);
        mBarPointerPaint.setColor(mColor);
        // Check whether the Saturation/Value bar is added to the ColorPicker
        // wheel
        if (mPicker != null) {
            mPicker.setNewCenterColor(mColor);
            mPicker.changeOpacityBarColor(mColor);
        }
        invalidate();
    }

    /**
     * Set the bar color. <br>
     * <br>
     * Its discouraged to use this method.
     *
     * @param color
     */
    public void setColor(int color) {
        int x1, y1;
        if (mOrientation) {
            x1 = (mBarLength + mBarPointerHaloRadius);
            y1 = mBarThickness;
        } else {
            x1 = mBarThickness;
            y1 = (mBarLength + mBarPointerHaloRadius);
        }
        Color.colorToHSV(color, mHSVColor);
        shader = new LinearGradient(mBarPointerHaloRadius, 0, x1, y1, new int[] { Color.WHITE, color, Color.BLACK }, null, Shader.TileMode.CLAMP);
        mBarPaint.setShader(shader);
        calculateColor(mBarPointerPosition);
        mBarPointerPaint.setColor(mColor);
        if (mPicker != null) {
            mPicker.setNewCenterColor(mColor);
            if (mPicker.hasOpacityBar())
                mPicker.changeOpacityBarColor(mColor);
        }
        invalidate();
    }

    /**
     * Calculate the color selected by the pointer on the bar.
     *
     * @param coord Coordinate of the pointer.
     */
    private void calculateColor(int coord) {
        coord = coord - mBarPointerHaloRadius;
        if (coord > (mBarLength / 2) && (coord < mBarLength)) {
            mColor = Color.HSVToColor(new float[] { mHSVColor[0], 1f, 1 - (mPosToSVFactor * (coord - (mBarLength / 2))) });
        } else if (coord > 0 && coord < mBarLength) {
            mColor = Color.HSVToColor(new float[] { mHSVColor[0], (mPosToSVFactor * coord), 1f });
        } else if (coord == (mBarLength / 2)) {
            mColor = Color.HSVToColor(new float[] { mHSVColor[0], 1f, 1f });
        } else if (coord <= 0) {
            mColor = Color.WHITE;
        } else if (coord >= mBarLength) {
            mColor = Color.BLACK;
        }
    }

    /**
     * Get the currently selected color.
     *
     * @return The ARGB value of the currently selected color.
     */
    public int getColor() {
        return mColor;
    }

    /**
     * Adds a {@code ColorPicker} instance to the bar. <br>
     * <br>
     * WARNING: Don't change the color picker. it is done already when the bar
     * is added to the ColorPicker
     *
     * @see com.larswerkman.holocolorpicker.ColorPicker#addSVBar(SVBar)
     * @param picker
     */
    public void setColorPicker(ColorPicker picker) {
        mPicker = picker;
    }

    @Override
    protected Parcelable onSaveInstanceState() {
        Parcelable superState = super.onSaveInstanceState();
        Bundle state = new Bundle();
        state.putParcelable(STATE_PARENT, superState);
        state.putFloatArray(STATE_COLOR, mHSVColor);
        float[] hsvColor = new float[3];
        Color.colorToHSV(mColor, hsvColor);
        if (hsvColor[1] < hsvColor[2]) {
            state.putFloat(STATE_SATURATION, hsvColor[1]);
        } else {
            state.putFloat(STATE_VALUE, hsvColor[2]);
        }
        return state;
    }

    @Override
    protected void onRestoreInstanceState(Parcelable state) {
        Bundle savedState = (Bundle) state;
        Parcelable superState = savedState.getParcelable(STATE_PARENT);
        super.onRestoreInstanceState(superState);
        setColor(Color.HSVToColor(savedState.getFloatArray(STATE_COLOR)));
        if (savedState.containsKey(STATE_SATURATION)) {
            setSaturation(savedState.getFloat(STATE_SATURATION));
        } else {
            setValue(savedState.getFloat(STATE_VALUE));
        }
    }
}

18 Source : SaturationBar.java
with GNU General Public License v3.0
from tianyuan168326

public clreplaced SaturationBar extends View {

    /*
	 * Constants used to save/restore the instance state.
	 */
    private static final String STATE_PARENT = "parent";

    private static final String STATE_COLOR = "color";

    private static final String STATE_SATURATION = "saturation";

    private static final String STATE_ORIENTATION = "orientation";

    /**
     * Constants used to identify orientation.
     */
    private static final boolean ORIENTATION_HORIZONTAL = true;

    private static final boolean ORIENTATION_VERTICAL = false;

    /**
     * Default orientation of the bar.
     */
    private static final boolean ORIENTATION_DEFAULT = ORIENTATION_HORIZONTAL;

    /**
     * The thickness of the bar.
     */
    private int mBarThickness;

    /**
     * The length of the bar.
     */
    private int mBarLength;

    private int mPreferredBarLength;

    /**
     * The radius of the pointer.
     */
    private int mBarPointerRadius;

    /**
     * The radius of the halo of the pointer.
     */
    private int mBarPointerHaloRadius;

    /**
     * The position of the pointer on the bar.
     */
    private int mBarPointerPosition;

    /**
     * {@code Paint} instance used to draw the bar.
     */
    private Paint mBarPaint;

    /**
     * {@code Paint} instance used to draw the pointer.
     */
    private Paint mBarPointerPaint;

    /**
     * {@code Paint} instance used to draw the halo of the pointer.
     */
    private Paint mBarPointerHaloPaint;

    /**
     * The rectangle enclosing the bar.
     */
    private RectF mBarRect = new RectF();

    /**
     * {@code Shader} instance used to fill the shader of the paint.
     */
    private Shader shader;

    /**
     * {@code true} if the user clicked on the pointer to start the move mode. <br>
     * {@code false} once the user stops touching the screen.
     *
     * @see #onTouchEvent(android.view.MotionEvent)
     */
    private boolean mIsMovingPointer;

    /**
     * The ARGB value of the currently selected color.
     */
    private int mColor;

    /**
     * An array of floats that can be build into a {@code Color} <br>
     * Where we can extract the color from.
     */
    private float[] mHSVColor = new float[3];

    /**
     * Factor used to calculate the position to the Opacity on the bar.
     */
    private float mPosToSatFactor;

    /**
     * Factor used to calculate the Opacity to the postion on the bar.
     */
    private float mSatToPosFactor;

    /**
     * {@code ColorPicker} instance used to control the ColorPicker.
     */
    private ColorPicker mPicker = null;

    /**
     * Used to toggle orientation between vertical and horizontal.
     */
    private boolean mOrientation;

    /**
     * Interface and listener so that changes in SaturationBar are sent
     * to the host activity/fragment
     */
    private OnSaturationChangedListener onSaturationChangedListener;

    /**
     * Saturation of the latest entry of the onSaturationChangedListener.
     */
    private int oldChangedListenerSaturation;

    public interface OnSaturationChangedListener {

        public void onSaturationChanged(int saturation);
    }

    public void setOnSaturationChangedListener(OnSaturationChangedListener listener) {
        this.onSaturationChangedListener = listener;
    }

    public OnSaturationChangedListener getOnSaturationChangedListener() {
        return this.onSaturationChangedListener;
    }

    public SaturationBar(Context context) {
        super(context);
        init(null, 0);
    }

    public SaturationBar(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(attrs, 0);
    }

    public SaturationBar(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(attrs, defStyle);
    }

    private void init(AttributeSet attrs, int defStyle) {
        final TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.ColorBars, defStyle, 0);
        final Resources b = getContext().getResources();
        mBarThickness = a.getDimensionPixelSize(R.styleable.ColorBars_bar_thickness, b.getDimensionPixelSize(R.dimen.bar_thickness));
        mBarLength = a.getDimensionPixelSize(R.styleable.ColorBars_bar_length, b.getDimensionPixelSize(R.dimen.bar_length));
        mPreferredBarLength = mBarLength;
        mBarPointerRadius = a.getDimensionPixelSize(R.styleable.ColorBars_bar_pointer_radius, b.getDimensionPixelSize(R.dimen.bar_pointer_radius));
        mBarPointerHaloRadius = a.getDimensionPixelSize(R.styleable.ColorBars_bar_pointer_halo_radius, b.getDimensionPixelSize(R.dimen.bar_pointer_halo_radius));
        mOrientation = a.getBoolean(R.styleable.ColorBars_bar_orientation_horizontal, ORIENTATION_DEFAULT);
        a.recycle();
        mBarPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mBarPaint.setShader(shader);
        mBarPointerPosition = mBarLength + mBarPointerHaloRadius;
        mBarPointerHaloPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mBarPointerHaloPaint.setColor(Color.BLACK);
        mBarPointerHaloPaint.setAlpha(0x50);
        mBarPointerPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mBarPointerPaint.setColor(0xff81ff00);
        mPosToSatFactor = 1 / ((float) mBarLength);
        mSatToPosFactor = ((float) mBarLength) / 1;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        final int intrinsicSize = mPreferredBarLength + (mBarPointerHaloRadius * 2);
        // Variable orientation
        int measureSpec;
        if (mOrientation == ORIENTATION_HORIZONTAL) {
            measureSpec = widthMeasureSpec;
        } else {
            measureSpec = heightMeasureSpec;
        }
        int lengthMode = MeasureSpec.getMode(measureSpec);
        int lengthSize = MeasureSpec.getSize(measureSpec);
        int length;
        if (lengthMode == MeasureSpec.EXACTLY) {
            length = lengthSize;
        } else if (lengthMode == MeasureSpec.AT_MOST) {
            length = Math.min(intrinsicSize, lengthSize);
        } else {
            length = intrinsicSize;
        }
        int barPointerHaloRadiusx2 = mBarPointerHaloRadius * 2;
        mBarLength = length - barPointerHaloRadiusx2;
        if (mOrientation == ORIENTATION_VERTICAL) {
            setMeasuredDimension(barPointerHaloRadiusx2, (mBarLength + barPointerHaloRadiusx2));
        } else {
            setMeasuredDimension((mBarLength + barPointerHaloRadiusx2), barPointerHaloRadiusx2);
        }
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        // Fill the rectangle instance based on orientation
        int x1, y1;
        if (mOrientation == ORIENTATION_HORIZONTAL) {
            x1 = (mBarLength + mBarPointerHaloRadius);
            y1 = mBarThickness;
            mBarLength = w - (mBarPointerHaloRadius * 2);
            mBarRect.set(mBarPointerHaloRadius, (mBarPointerHaloRadius - (mBarThickness / 2)), (mBarLength + (mBarPointerHaloRadius)), (mBarPointerHaloRadius + (mBarThickness / 2)));
        } else {
            x1 = mBarThickness;
            y1 = (mBarLength + mBarPointerHaloRadius);
            mBarLength = h - (mBarPointerHaloRadius * 2);
            mBarRect.set((mBarPointerHaloRadius - (mBarThickness / 2)), mBarPointerHaloRadius, (mBarPointerHaloRadius + (mBarThickness / 2)), (mBarLength + (mBarPointerHaloRadius)));
        }
        // Update variables that depend of mBarLength.
        if (!isInEditMode()) {
            shader = new LinearGradient(mBarPointerHaloRadius, 0, x1, y1, new int[] { Color.WHITE, Color.HSVToColor(0xFF, mHSVColor) }, null, Shader.TileMode.CLAMP);
        } else {
            shader = new LinearGradient(mBarPointerHaloRadius, 0, x1, y1, new int[] { Color.WHITE, 0xff81ff00 }, null, Shader.TileMode.CLAMP);
            Color.colorToHSV(0xff81ff00, mHSVColor);
        }
        mBarPaint.setShader(shader);
        mPosToSatFactor = 1 / ((float) mBarLength);
        mSatToPosFactor = ((float) mBarLength) / 1;
        float[] hsvColor = new float[3];
        Color.colorToHSV(mColor, hsvColor);
        if (!isInEditMode()) {
            mBarPointerPosition = Math.round((mSatToPosFactor * hsvColor[1]) + mBarPointerHaloRadius);
        } else {
            mBarPointerPosition = mBarLength + mBarPointerHaloRadius;
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        // Draw the bar.
        canvas.drawRect(mBarRect, mBarPaint);
        // Calculate the center of the pointer.
        int cX, cY;
        if (mOrientation == ORIENTATION_HORIZONTAL) {
            cX = mBarPointerPosition;
            cY = mBarPointerHaloRadius;
        } else {
            cX = mBarPointerHaloRadius;
            cY = mBarPointerPosition;
        }
        // Draw the pointer halo.
        canvas.drawCircle(cX, cY, mBarPointerHaloRadius, mBarPointerHaloPaint);
        // Draw the pointer.
        canvas.drawCircle(cX, cY, mBarPointerRadius, mBarPointerPaint);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        getParent().requestDisallowInterceptTouchEvent(true);
        // Convert coordinates to our internal coordinate system
        float dimen;
        if (mOrientation == ORIENTATION_HORIZONTAL) {
            dimen = event.getX();
        } else {
            dimen = event.getY();
        }
        switch(event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mIsMovingPointer = true;
                // Check whether the user pressed on (or near) the pointer
                if (dimen >= (mBarPointerHaloRadius) && dimen <= (mBarPointerHaloRadius + mBarLength)) {
                    mBarPointerPosition = Math.round(dimen);
                    calculateColor(Math.round(dimen));
                    mBarPointerPaint.setColor(mColor);
                    invalidate();
                }
                break;
            case MotionEvent.ACTION_MOVE:
                if (mIsMovingPointer) {
                    // Move the the pointer on the bar.
                    if (dimen >= mBarPointerHaloRadius && dimen <= (mBarPointerHaloRadius + mBarLength)) {
                        mBarPointerPosition = Math.round(dimen);
                        calculateColor(Math.round(dimen));
                        mBarPointerPaint.setColor(mColor);
                        if (mPicker != null) {
                            mPicker.setNewCenterColor(mColor);
                            mPicker.changeValueBarColor(mColor);
                            mPicker.changeOpacityBarColor(mColor);
                        }
                        invalidate();
                    } else if (dimen < mBarPointerHaloRadius) {
                        mBarPointerPosition = mBarPointerHaloRadius;
                        mColor = Color.WHITE;
                        mBarPointerPaint.setColor(mColor);
                        if (mPicker != null) {
                            mPicker.setNewCenterColor(mColor);
                            mPicker.changeValueBarColor(mColor);
                            mPicker.changeOpacityBarColor(mColor);
                        }
                        invalidate();
                    } else if (dimen > (mBarPointerHaloRadius + mBarLength)) {
                        mBarPointerPosition = mBarPointerHaloRadius + mBarLength;
                        mColor = Color.HSVToColor(mHSVColor);
                        mBarPointerPaint.setColor(mColor);
                        if (mPicker != null) {
                            mPicker.setNewCenterColor(mColor);
                            mPicker.changeValueBarColor(mColor);
                            mPicker.changeOpacityBarColor(mColor);
                        }
                        invalidate();
                    }
                }
                if (onSaturationChangedListener != null && oldChangedListenerSaturation != mColor) {
                    onSaturationChangedListener.onSaturationChanged(mColor);
                    oldChangedListenerSaturation = mColor;
                }
                break;
            case MotionEvent.ACTION_UP:
                mIsMovingPointer = false;
                break;
        }
        return true;
    }

    /**
     * Set the bar color. <br>
     * <br>
     * Its discouraged to use this method.
     *
     * @param color
     */
    public void setColor(int color) {
        int x1, y1;
        if (mOrientation == ORIENTATION_HORIZONTAL) {
            x1 = (mBarLength + mBarPointerHaloRadius);
            y1 = mBarThickness;
        } else {
            x1 = mBarThickness;
            y1 = (mBarLength + mBarPointerHaloRadius);
        }
        Color.colorToHSV(color, mHSVColor);
        shader = new LinearGradient(mBarPointerHaloRadius, 0, x1, y1, new int[] { Color.WHITE, color }, null, Shader.TileMode.CLAMP);
        mBarPaint.setShader(shader);
        calculateColor(mBarPointerPosition);
        mBarPointerPaint.setColor(mColor);
        if (mPicker != null) {
            mPicker.setNewCenterColor(mColor);
            if (mPicker.hasValueBar())
                mPicker.changeValueBarColor(mColor);
            else if (mPicker.hasOpacityBar())
                mPicker.changeOpacityBarColor(mColor);
        }
        invalidate();
    }

    /**
     * Set the pointer on the bar. With the opacity value.
     *
     * @param saturation float between 0 and 1
     */
    public void setSaturation(float saturation) {
        mBarPointerPosition = Math.round((mSatToPosFactor * saturation)) + mBarPointerHaloRadius;
        calculateColor(mBarPointerPosition);
        mBarPointerPaint.setColor(mColor);
        if (mPicker != null) {
            mPicker.setNewCenterColor(mColor);
            mPicker.changeValueBarColor(mColor);
            mPicker.changeOpacityBarColor(mColor);
        }
        invalidate();
    }

    /**
     * Calculate the color selected by the pointer on the bar.
     *
     * @param coord Coordinate of the pointer.
     */
    private void calculateColor(int coord) {
        coord = coord - mBarPointerHaloRadius;
        if (coord < 0) {
            coord = 0;
        } else if (coord > mBarLength) {
            coord = mBarLength;
        }
        mColor = Color.HSVToColor(new float[] { mHSVColor[0], (mPosToSatFactor * coord), 1f });
    }

    /**
     * Get the currently selected color.
     *
     * @return The ARGB value of the currently selected color.
     */
    public int getColor() {
        return mColor;
    }

    /**
     * Adds a {@code ColorPicker} instance to the bar. <br>
     * <br>
     * WARNING: Don't change the color picker. it is done already when the bar
     * is added to the ColorPicker
     *
     * @see com.larswerkman.holocolorpicker.ColorPicker#addSVBar(SVBar)
     * @param picker
     */
    public void setColorPicker(ColorPicker picker) {
        mPicker = picker;
    }

    @Override
    protected Parcelable onSaveInstanceState() {
        Parcelable superState = super.onSaveInstanceState();
        Bundle state = new Bundle();
        state.putParcelable(STATE_PARENT, superState);
        state.putFloatArray(STATE_COLOR, mHSVColor);
        float[] hsvColor = new float[3];
        Color.colorToHSV(mColor, hsvColor);
        state.putFloat(STATE_SATURATION, hsvColor[1]);
        return state;
    }

    @Override
    protected void onRestoreInstanceState(Parcelable state) {
        Bundle savedState = (Bundle) state;
        Parcelable superState = savedState.getParcelable(STATE_PARENT);
        super.onRestoreInstanceState(superState);
        setColor(Color.HSVToColor(savedState.getFloatArray(STATE_COLOR)));
        setSaturation(savedState.getFloat(STATE_SATURATION));
    }
}

18 Source : OpacityBar.java
with GNU General Public License v3.0
from tianyuan168326

public clreplaced OpacityBar extends View {

    /*
	 * Constants used to save/restore the instance state.
	 */
    private static final String STATE_PARENT = "parent";

    private static final String STATE_COLOR = "color";

    private static final String STATE_OPACITY = "opacity";

    private static final String STATE_ORIENTATION = "orientation";

    /**
     * Constants used to identify orientation.
     */
    private static final boolean ORIENTATION_HORIZONTAL = true;

    private static final boolean ORIENTATION_VERTICAL = false;

    /**
     * Default orientation of the bar.
     */
    private static final boolean ORIENTATION_DEFAULT = ORIENTATION_HORIZONTAL;

    /**
     * The thickness of the bar.
     */
    private int mBarThickness;

    /**
     * The length of the bar.
     */
    private int mBarLength;

    private int mPreferredBarLength;

    /**
     * The radius of the pointer.
     */
    private int mBarPointerRadius;

    /**
     * The radius of the halo of the pointer.
     */
    private int mBarPointerHaloRadius;

    /**
     * The position of the pointer on the bar.
     */
    private int mBarPointerPosition;

    /**
     * {@code Paint} instance used to draw the bar.
     */
    private Paint mBarPaint;

    /**
     * {@code Paint} instance used to draw the pointer.
     */
    private Paint mBarPointerPaint;

    /**
     * {@code Paint} instance used to draw the halo of the pointer.
     */
    private Paint mBarPointerHaloPaint;

    /**
     * The rectangle enclosing the bar.
     */
    private RectF mBarRect = new RectF();

    /**
     * {@code Shader} instance used to fill the shader of the paint.
     */
    private Shader shader;

    /**
     * {@code true} if the user clicked on the pointer to start the move mode. <br>
     * {@code false} once the user stops touching the screen.
     *
     * @see #onTouchEvent(android.view.MotionEvent)
     */
    private boolean mIsMovingPointer;

    /**
     * The ARGB value of the currently selected color.
     */
    private int mColor;

    /**
     * An array of floats that can be build into a {@code Color} <br>
     * Where we can extract the color from.
     */
    private float[] mHSVColor = new float[3];

    /**
     * Factor used to calculate the position to the Opacity on the bar.
     */
    private float mPosToOpacFactor;

    /**
     * Factor used to calculate the Opacity to the postion on the bar.
     */
    private float mOpacToPosFactor;

    /**
     * Interface and listener so that changes in OpacityBar are sent
     * to the host activity/fragment
     */
    private OnOpacityChangedListener onOpacityChangedListener;

    /**
     * Opacity of the latest entry of the onOpacityChangedListener.
     */
    private int oldChangedListenerOpacity;

    public interface OnOpacityChangedListener {

        public void onOpacityChanged(int opacity);
    }

    public void setOnOpacityChangedListener(OnOpacityChangedListener listener) {
        this.onOpacityChangedListener = listener;
    }

    public OnOpacityChangedListener getOnOpacityChangedListener() {
        return this.onOpacityChangedListener;
    }

    /**
     * {@code ColorPicker} instance used to control the ColorPicker.
     */
    private ColorPicker mPicker = null;

    /**
     * Used to toggle orientation between vertical and horizontal.
     */
    private boolean mOrientation;

    public OpacityBar(Context context) {
        super(context);
        init(null, 0);
    }

    public OpacityBar(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(attrs, 0);
    }

    public OpacityBar(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(attrs, defStyle);
    }

    private void init(AttributeSet attrs, int defStyle) {
        final TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.ColorBars, defStyle, 0);
        final Resources b = getContext().getResources();
        mBarThickness = a.getDimensionPixelSize(R.styleable.ColorBars_bar_thickness, b.getDimensionPixelSize(R.dimen.bar_thickness));
        mBarLength = a.getDimensionPixelSize(R.styleable.ColorBars_bar_length, b.getDimensionPixelSize(R.dimen.bar_length));
        mPreferredBarLength = mBarLength;
        mBarPointerRadius = a.getDimensionPixelSize(R.styleable.ColorBars_bar_pointer_radius, b.getDimensionPixelSize(R.dimen.bar_pointer_radius));
        mBarPointerHaloRadius = a.getDimensionPixelSize(R.styleable.ColorBars_bar_pointer_halo_radius, b.getDimensionPixelSize(R.dimen.bar_pointer_halo_radius));
        mOrientation = a.getBoolean(R.styleable.ColorBars_bar_orientation_horizontal, ORIENTATION_DEFAULT);
        a.recycle();
        mBarPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mBarPaint.setShader(shader);
        mBarPointerPosition = mBarLength + mBarPointerHaloRadius;
        mBarPointerHaloPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mBarPointerHaloPaint.setColor(Color.BLACK);
        mBarPointerHaloPaint.setAlpha(0x50);
        mBarPointerPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mBarPointerPaint.setColor(0xff81ff00);
        mPosToOpacFactor = 0xFF / ((float) mBarLength);
        mOpacToPosFactor = ((float) mBarLength) / 0xFF;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        final int intrinsicSize = mPreferredBarLength + (mBarPointerHaloRadius * 2);
        // Variable orientation
        int measureSpec;
        if (mOrientation == ORIENTATION_HORIZONTAL) {
            measureSpec = widthMeasureSpec;
        } else {
            measureSpec = heightMeasureSpec;
        }
        int lengthMode = MeasureSpec.getMode(measureSpec);
        int lengthSize = MeasureSpec.getSize(measureSpec);
        int length;
        if (lengthMode == MeasureSpec.EXACTLY) {
            length = lengthSize;
        } else if (lengthMode == MeasureSpec.AT_MOST) {
            length = Math.min(intrinsicSize, lengthSize);
        } else {
            length = intrinsicSize;
        }
        int barPointerHaloRadiusx2 = mBarPointerHaloRadius * 2;
        mBarLength = length - barPointerHaloRadiusx2;
        if (mOrientation == ORIENTATION_VERTICAL) {
            setMeasuredDimension(barPointerHaloRadiusx2, (mBarLength + barPointerHaloRadiusx2));
        } else {
            setMeasuredDimension((mBarLength + barPointerHaloRadiusx2), barPointerHaloRadiusx2);
        }
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        // Fill the rectangle instance based on orientation
        int x1, y1;
        if (mOrientation == ORIENTATION_HORIZONTAL) {
            x1 = (mBarLength + mBarPointerHaloRadius);
            y1 = mBarThickness;
            mBarLength = w - (mBarPointerHaloRadius * 2);
            mBarRect.set(mBarPointerHaloRadius, (mBarPointerHaloRadius - (mBarThickness / 2)), (mBarLength + (mBarPointerHaloRadius)), (mBarPointerHaloRadius + (mBarThickness / 2)));
        } else {
            x1 = mBarThickness;
            y1 = (mBarLength + mBarPointerHaloRadius);
            mBarLength = h - (mBarPointerHaloRadius * 2);
            mBarRect.set((mBarPointerHaloRadius - (mBarThickness / 2)), mBarPointerHaloRadius, (mBarPointerHaloRadius + (mBarThickness / 2)), (mBarLength + (mBarPointerHaloRadius)));
        }
        // Update variables that depend of mBarLength.
        if (!isInEditMode()) {
            shader = new LinearGradient(mBarPointerHaloRadius, 0, x1, y1, new int[] { Color.HSVToColor(0x00, mHSVColor), Color.HSVToColor(0xFF, mHSVColor) }, null, Shader.TileMode.CLAMP);
        } else {
            shader = new LinearGradient(mBarPointerHaloRadius, 0, x1, y1, new int[] { 0x0081ff00, 0xff81ff00 }, null, Shader.TileMode.CLAMP);
            Color.colorToHSV(0xff81ff00, mHSVColor);
        }
        mBarPaint.setShader(shader);
        mPosToOpacFactor = 0xFF / ((float) mBarLength);
        mOpacToPosFactor = ((float) mBarLength) / 0xFF;
        float[] hsvColor = new float[3];
        Color.colorToHSV(mColor, hsvColor);
        if (!isInEditMode()) {
            mBarPointerPosition = Math.round((mOpacToPosFactor * Color.alpha(mColor)) + mBarPointerHaloRadius);
        } else {
            mBarPointerPosition = mBarLength + mBarPointerHaloRadius;
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        // Draw the bar.
        canvas.drawRect(mBarRect, mBarPaint);
        // Calculate the center of the pointer.
        int cX, cY;
        if (mOrientation == ORIENTATION_HORIZONTAL) {
            cX = mBarPointerPosition;
            cY = mBarPointerHaloRadius;
        } else {
            cX = mBarPointerHaloRadius;
            cY = mBarPointerPosition;
        }
        // Draw the pointer halo.
        canvas.drawCircle(cX, cY, mBarPointerHaloRadius, mBarPointerHaloPaint);
        // Draw the pointer.
        canvas.drawCircle(cX, cY, mBarPointerRadius, mBarPointerPaint);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        getParent().requestDisallowInterceptTouchEvent(true);
        // Convert coordinates to our internal coordinate system
        float dimen;
        if (mOrientation == ORIENTATION_HORIZONTAL) {
            dimen = event.getX();
        } else {
            dimen = event.getY();
        }
        switch(event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mIsMovingPointer = true;
                // Check whether the user pressed on (or near) the pointer
                if (dimen >= (mBarPointerHaloRadius) && dimen <= (mBarPointerHaloRadius + mBarLength)) {
                    mBarPointerPosition = Math.round(dimen);
                    calculateColor(Math.round(dimen));
                    mBarPointerPaint.setColor(mColor);
                    invalidate();
                }
                break;
            case MotionEvent.ACTION_MOVE:
                if (mIsMovingPointer) {
                    // Move the the pointer on the bar.
                    if (dimen >= mBarPointerHaloRadius && dimen <= (mBarPointerHaloRadius + mBarLength)) {
                        mBarPointerPosition = Math.round(dimen);
                        calculateColor(Math.round(dimen));
                        mBarPointerPaint.setColor(mColor);
                        if (mPicker != null) {
                            mPicker.setNewCenterColor(mColor);
                        }
                        invalidate();
                    } else if (dimen < mBarPointerHaloRadius) {
                        mBarPointerPosition = mBarPointerHaloRadius;
                        mColor = Color.TRANSPARENT;
                        mBarPointerPaint.setColor(mColor);
                        if (mPicker != null) {
                            mPicker.setNewCenterColor(mColor);
                        }
                        invalidate();
                    } else if (dimen > (mBarPointerHaloRadius + mBarLength)) {
                        mBarPointerPosition = mBarPointerHaloRadius + mBarLength;
                        mColor = Color.HSVToColor(mHSVColor);
                        mBarPointerPaint.setColor(mColor);
                        if (mPicker != null) {
                            mPicker.setNewCenterColor(mColor);
                        }
                        invalidate();
                    }
                }
                if (onOpacityChangedListener != null && oldChangedListenerOpacity != getOpacity()) {
                    onOpacityChangedListener.onOpacityChanged(getOpacity());
                    oldChangedListenerOpacity = getOpacity();
                }
                break;
            case MotionEvent.ACTION_UP:
                mIsMovingPointer = false;
                break;
        }
        return true;
    }

    /**
     * Set the bar color. <br>
     * <br>
     * Its discouraged to use this method.
     *
     * @param color
     */
    public void setColor(int color) {
        int x1, y1;
        if (mOrientation == ORIENTATION_HORIZONTAL) {
            x1 = (mBarLength + mBarPointerHaloRadius);
            y1 = mBarThickness;
        } else {
            x1 = mBarThickness;
            y1 = (mBarLength + mBarPointerHaloRadius);
        }
        Color.colorToHSV(color, mHSVColor);
        shader = new LinearGradient(mBarPointerHaloRadius, 0, x1, y1, new int[] { Color.HSVToColor(0x00, mHSVColor), color }, null, Shader.TileMode.CLAMP);
        mBarPaint.setShader(shader);
        calculateColor(mBarPointerPosition);
        mBarPointerPaint.setColor(mColor);
        if (mPicker != null) {
            mPicker.setNewCenterColor(mColor);
        }
        invalidate();
    }

    /**
     * Set the pointer on the bar. With the opacity value.
     *
     * @param opacity float between 0 and 255
     */
    public void setOpacity(int opacity) {
        mBarPointerPosition = Math.round((mOpacToPosFactor * opacity)) + mBarPointerHaloRadius;
        calculateColor(mBarPointerPosition);
        mBarPointerPaint.setColor(mColor);
        if (mPicker != null) {
            mPicker.setNewCenterColor(mColor);
        }
        invalidate();
    }

    /**
     * Get the currently selected opacity.
     *
     * @return The int value of the currently selected opacity.
     */
    public int getOpacity() {
        int opacity = Math.round((mPosToOpacFactor * (mBarPointerPosition - mBarPointerHaloRadius)));
        if (opacity < 5) {
            return 0x00;
        } else if (opacity > 250) {
            return 0xFF;
        } else {
            return opacity;
        }
    }

    /**
     * Calculate the color selected by the pointer on the bar.
     *
     * @param coord Coordinate of the pointer.
     */
    private void calculateColor(int coord) {
        coord = coord - mBarPointerHaloRadius;
        if (coord < 0) {
            coord = 0;
        } else if (coord > mBarLength) {
            coord = mBarLength;
        }
        mColor = Color.HSVToColor(Math.round(mPosToOpacFactor * coord), mHSVColor);
        if (Color.alpha(mColor) > 250) {
            mColor = Color.HSVToColor(mHSVColor);
        } else if (Color.alpha(mColor) < 5) {
            mColor = Color.TRANSPARENT;
        }
    }

    /**
     * Get the currently selected color.
     *
     * @return The ARGB value of the currently selected color.
     */
    public int getColor() {
        return mColor;
    }

    /**
     * Adds a {@code ColorPicker} instance to the bar. <br>
     * <br>
     * WARNING: Don't change the color picker. it is done already when the bar
     * is added to the ColorPicker
     *
     * @see com.larswerkman.holocolorpicker.ColorPicker#addSVBar(SVBar)
     * @param picker
     */
    public void setColorPicker(ColorPicker picker) {
        mPicker = picker;
    }

    @Override
    protected Parcelable onSaveInstanceState() {
        Parcelable superState = super.onSaveInstanceState();
        Bundle state = new Bundle();
        state.putParcelable(STATE_PARENT, superState);
        state.putFloatArray(STATE_COLOR, mHSVColor);
        state.putInt(STATE_OPACITY, getOpacity());
        return state;
    }

    @Override
    protected void onRestoreInstanceState(Parcelable state) {
        Bundle savedState = (Bundle) state;
        Parcelable superState = savedState.getParcelable(STATE_PARENT);
        super.onRestoreInstanceState(superState);
        setColor(Color.HSVToColor(savedState.getFloatArray(STATE_COLOR)));
        setOpacity(savedState.getInt(STATE_OPACITY));
    }
}

18 Source : ColorPickerView.java
with Apache License 2.0
from starscryer

/**
 * Displays a color picker to the user and allow them
 * to select a color. A slider for the alpha channel is
 * also available. Enable it by setting
 * setAlphaSliderVisible(boolean) to true.
 *
 * @author Daniel Nilsson
 */
public clreplaced ColorPickerView extends View {

    private final static int PANEL_SAT_VAL = 0;

    private final static int PANEL_HUE = 1;

    private final static int PANEL_ALPHA = 2;

    /**
     * The width in pixels of the border
     * surrounding all color panels.
     */
    private final static float BORDER_WIDTH_PX = 1;

    /**
     * The width in dp of the hue panel.
     */
    private float HUE_PANEL_WIDTH = 30f;

    /**
     * The height in dp of the alpha panel
     */
    private float ALPHA_PANEL_HEIGHT = 20f;

    /**
     * The distance in dp between the different
     * color panels.
     */
    private float PANEL_SPACING = 10f;

    /**
     * The radius in dp of the color palette tracker circle.
     */
    private float PALETTE_CIRCLE_TRACKER_RADIUS = 5f;

    /**
     * The dp which the tracker of the hue or alpha panel
     * will extend outside of its bounds.
     */
    private float RECTANGLE_TRACKER_OFFSET = 2f;

    private float mDensity = 1f;

    private OnColorChangedListener mListener;

    private Paint mSatValPaint;

    private Paint mSatValTrackerPaint;

    private Paint mHuePaint;

    private Paint mHueTrackerPaint;

    private Paint mAlphaPaint;

    private Paint mAlphaTextPaint;

    private Paint mBorderPaint;

    private Shader mValShader;

    private Shader mSatShader;

    private Shader mHueShader;

    private Shader mAlphaShader;

    private int mAlpha = 0xff;

    private float mHue = 360f;

    private float mSat = 0f;

    private float mVal = 0f;

    private String mAlphaSliderText = "";

    private int mSliderTrackerColor = 0xff1c1c1c;

    private int mBorderColor = 0xff6E6E6E;

    private boolean mShowAlphaPanel = false;

    /*
     * To remember which panel that has the "focus" when
     * processing hardware button data.
     */
    private int mLastTouchedPanel = PANEL_SAT_VAL;

    /**
     * Offset from the edge we must have or else
     * the finger tracker will get clipped when
     * it is drawn outside of the view.
     */
    private float mDrawingOffset;

    /*
     * Distance form the edges of the view
     * of where we are allowed to draw.
     */
    private RectF mDrawingRect;

    private RectF mSatValRect;

    private RectF mHueRect;

    private RectF mAlphaRect;

    private AlphaPatternDrawable mAlphaPattern;

    private Point mStartTouchPoint = null;

    public interface OnColorChangedListener {

        public void onColorChanged(int color);
    }

    public ColorPickerView(Context context) {
        this(context, null);
    }

    public ColorPickerView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ColorPickerView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    private void init() {
        mDensity = getContext().getResources().getDisplayMetrics().density;
        PALETTE_CIRCLE_TRACKER_RADIUS *= mDensity;
        RECTANGLE_TRACKER_OFFSET *= mDensity;
        HUE_PANEL_WIDTH *= mDensity;
        ALPHA_PANEL_HEIGHT *= mDensity;
        PANEL_SPACING = PANEL_SPACING * mDensity;
        mDrawingOffset = calculateRequiredOffset();
        initPaintTools();
        // Needed for receiving trackball motion events.
        setFocusable(true);
        setFocusableInTouchMode(true);
    }

    private void initPaintTools() {
        mSatValPaint = new Paint();
        mSatValTrackerPaint = new Paint();
        mHuePaint = new Paint();
        mHueTrackerPaint = new Paint();
        mAlphaPaint = new Paint();
        mAlphaTextPaint = new Paint();
        mBorderPaint = new Paint();
        mSatValTrackerPaint.setStyle(Style.STROKE);
        mSatValTrackerPaint.setStrokeWidth(2f * mDensity);
        mSatValTrackerPaint.setAntiAlias(true);
        mHueTrackerPaint.setColor(mSliderTrackerColor);
        mHueTrackerPaint.setStyle(Style.STROKE);
        mHueTrackerPaint.setStrokeWidth(2f * mDensity);
        mHueTrackerPaint.setAntiAlias(true);
        mAlphaTextPaint.setColor(0xff1c1c1c);
        mAlphaTextPaint.setTextSize(14f * mDensity);
        mAlphaTextPaint.setAntiAlias(true);
        mAlphaTextPaint.setTextAlign(Align.CENTER);
        mAlphaTextPaint.setFakeBoldText(true);
    }

    private float calculateRequiredOffset() {
        float offset = Math.max(PALETTE_CIRCLE_TRACKER_RADIUS, RECTANGLE_TRACKER_OFFSET);
        offset = Math.max(offset, BORDER_WIDTH_PX * mDensity);
        return offset * 1.5f;
    }

    private int[] buildHueColorArray() {
        int[] hue = new int[361];
        int count = 0;
        for (int i = hue.length - 1; i >= 0; i--, count++) {
            hue[count] = Color.HSVToColor(new float[] { i, 1f, 1f });
        }
        return hue;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        if (mDrawingRect.width() <= 0 || mDrawingRect.height() <= 0)
            return;
        drawSatValPanel(canvas);
        drawHuePanel(canvas);
        drawAlphaPanel(canvas);
    }

    private void drawSatValPanel(Canvas canvas) {
        final RectF rect = mSatValRect;
        if (BORDER_WIDTH_PX > 0) {
            mBorderPaint.setColor(mBorderColor);
            canvas.drawRect(mDrawingRect.left, mDrawingRect.top, rect.right + BORDER_WIDTH_PX, rect.bottom + BORDER_WIDTH_PX, mBorderPaint);
        }
        if (mValShader == null) {
            mValShader = new LinearGradient(rect.left, rect.top, rect.left, rect.bottom, 0xffffffff, 0xff000000, TileMode.CLAMP);
        }
        int rgb = Color.HSVToColor(new float[] { mHue, 1f, 1f });
        mSatShader = new LinearGradient(rect.left, rect.top, rect.right, rect.top, 0xffffffff, rgb, TileMode.CLAMP);
        ComposeShader mShader = new ComposeShader(mValShader, mSatShader, PorterDuff.Mode.MULTIPLY);
        mSatValPaint.setShader(mShader);
        canvas.drawRect(rect, mSatValPaint);
        Point p = satValToPoint(mSat, mVal);
        mSatValTrackerPaint.setColor(0xff000000);
        canvas.drawCircle(p.x, p.y, PALETTE_CIRCLE_TRACKER_RADIUS - 1f * mDensity, mSatValTrackerPaint);
        mSatValTrackerPaint.setColor(0xffdddddd);
        canvas.drawCircle(p.x, p.y, PALETTE_CIRCLE_TRACKER_RADIUS, mSatValTrackerPaint);
    }

    private void drawHuePanel(Canvas canvas) {
        final RectF rect = mHueRect;
        if (BORDER_WIDTH_PX > 0) {
            mBorderPaint.setColor(mBorderColor);
            canvas.drawRect(rect.left - BORDER_WIDTH_PX, rect.top - BORDER_WIDTH_PX, rect.right + BORDER_WIDTH_PX, rect.bottom + BORDER_WIDTH_PX, mBorderPaint);
        }
        if (mHueShader == null) {
            mHueShader = new LinearGradient(rect.left, rect.top, rect.left, rect.bottom, buildHueColorArray(), null, TileMode.CLAMP);
            mHuePaint.setShader(mHueShader);
        }
        canvas.drawRect(rect, mHuePaint);
        float rectHeight = 4 * mDensity / 2;
        Point p = hueToPoint(mHue);
        RectF r = new RectF();
        r.left = rect.left - RECTANGLE_TRACKER_OFFSET;
        r.right = rect.right + RECTANGLE_TRACKER_OFFSET;
        r.top = p.y - rectHeight;
        r.bottom = p.y + rectHeight;
        canvas.drawRoundRect(r, 2, 2, mHueTrackerPaint);
    }

    private void drawAlphaPanel(Canvas canvas) {
        if (!mShowAlphaPanel || mAlphaRect == null || mAlphaPattern == null)
            return;
        final RectF rect = mAlphaRect;
        if (BORDER_WIDTH_PX > 0) {
            mBorderPaint.setColor(mBorderColor);
            canvas.drawRect(rect.left - BORDER_WIDTH_PX, rect.top - BORDER_WIDTH_PX, rect.right + BORDER_WIDTH_PX, rect.bottom + BORDER_WIDTH_PX, mBorderPaint);
        }
        mAlphaPattern.draw(canvas);
        float[] hsv = new float[] { mHue, mSat, mVal };
        int color = Color.HSVToColor(hsv);
        int acolor = Color.HSVToColor(0, hsv);
        mAlphaShader = new LinearGradient(rect.left, rect.top, rect.right, rect.top, color, acolor, TileMode.CLAMP);
        mAlphaPaint.setShader(mAlphaShader);
        canvas.drawRect(rect, mAlphaPaint);
        if (mAlphaSliderText != null && mAlphaSliderText != "") {
            canvas.drawText(mAlphaSliderText, rect.centerX(), rect.centerY() + 4 * mDensity, mAlphaTextPaint);
        }
        float rectWidth = 4 * mDensity / 2;
        Point p = alphaToPoint(mAlpha);
        RectF r = new RectF();
        r.left = p.x - rectWidth;
        r.right = p.x + rectWidth;
        r.top = rect.top - RECTANGLE_TRACKER_OFFSET;
        r.bottom = rect.bottom + RECTANGLE_TRACKER_OFFSET;
        canvas.drawRoundRect(r, 2, 2, mHueTrackerPaint);
    }

    private Point hueToPoint(float hue) {
        final RectF rect = mHueRect;
        final float height = rect.height();
        Point p = new Point();
        p.y = (int) (height - (hue * height / 360f) + rect.top);
        p.x = (int) rect.left;
        return p;
    }

    private Point satValToPoint(float sat, float val) {
        final RectF rect = mSatValRect;
        final float height = rect.height();
        final float width = rect.width();
        Point p = new Point();
        p.x = (int) (sat * width + rect.left);
        p.y = (int) ((1f - val) * height + rect.top);
        return p;
    }

    private Point alphaToPoint(int alpha) {
        final RectF rect = mAlphaRect;
        final float width = rect.width();
        Point p = new Point();
        p.x = (int) (width - (alpha * width / 0xff) + rect.left);
        p.y = (int) rect.top;
        return p;
    }

    private float[] pointToSatVal(float x, float y) {
        final RectF rect = mSatValRect;
        float[] result = new float[2];
        float width = rect.width();
        float height = rect.height();
        if (x < rect.left) {
            x = 0f;
        } else if (x > rect.right) {
            x = width;
        } else {
            x = x - rect.left;
        }
        if (y < rect.top) {
            y = 0f;
        } else if (y > rect.bottom) {
            y = height;
        } else {
            y = y - rect.top;
        }
        result[0] = 1.f / width * x;
        result[1] = 1.f - (1.f / height * y);
        return result;
    }

    private float pointToHue(float y) {
        final RectF rect = mHueRect;
        float height = rect.height();
        if (y < rect.top) {
            y = 0f;
        } else if (y > rect.bottom) {
            y = height;
        } else {
            y = y - rect.top;
        }
        return 360f - (y * 360f / height);
    }

    private int pointToAlpha(int x) {
        final RectF rect = mAlphaRect;
        final int width = (int) rect.width();
        if (x < rect.left) {
            x = 0;
        } else if (x > rect.right) {
            x = width;
        } else {
            x = x - (int) rect.left;
        }
        return 0xff - (x * 0xff / width);
    }

    @Override
    public boolean onTrackballEvent(MotionEvent event) {
        float x = event.getX();
        float y = event.getY();
        boolean update = false;
        if (event.getAction() == MotionEvent.ACTION_MOVE) {
            switch(mLastTouchedPanel) {
                case PANEL_SAT_VAL:
                    float sat, val;
                    sat = mSat + x / 50f;
                    val = mVal - y / 50f;
                    if (sat < 0f) {
                        sat = 0f;
                    } else if (sat > 1f) {
                        sat = 1f;
                    }
                    if (val < 0f) {
                        val = 0f;
                    } else if (val > 1f) {
                        val = 1f;
                    }
                    mSat = sat;
                    mVal = val;
                    update = true;
                    break;
                case PANEL_HUE:
                    float hue = mHue - y * 10f;
                    if (hue < 0f) {
                        hue = 0f;
                    } else if (hue > 360f) {
                        hue = 360f;
                    }
                    mHue = hue;
                    update = true;
                    break;
                case PANEL_ALPHA:
                    if (!mShowAlphaPanel || mAlphaRect == null) {
                        update = false;
                    } else {
                        int alpha = (int) (mAlpha - x * 10);
                        if (alpha < 0) {
                            alpha = 0;
                        } else if (alpha > 0xff) {
                            alpha = 0xff;
                        }
                        mAlpha = alpha;
                        update = true;
                    }
                    break;
            }
        }
        if (update) {
            if (mListener != null) {
                mListener.onColorChanged(Color.HSVToColor(mAlpha, new float[] { mHue, mSat, mVal }));
            }
            invalidate();
            return true;
        }
        return super.onTrackballEvent(event);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        boolean update = false;
        switch(event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mStartTouchPoint = new Point((int) event.getX(), (int) event.getY());
                update = moveTrackersIfNeeded(event);
                break;
            case MotionEvent.ACTION_MOVE:
                update = moveTrackersIfNeeded(event);
                break;
            case MotionEvent.ACTION_UP:
                mStartTouchPoint = null;
                update = moveTrackersIfNeeded(event);
                break;
        }
        if (update) {
            if (mListener != null) {
                mListener.onColorChanged(Color.HSVToColor(mAlpha, new float[] { mHue, mSat, mVal }));
            }
            invalidate();
            return true;
        }
        return super.onTouchEvent(event);
    }

    private boolean moveTrackersIfNeeded(MotionEvent event) {
        if (mStartTouchPoint == null)
            return false;
        boolean update = false;
        int startX = mStartTouchPoint.x;
        int startY = mStartTouchPoint.y;
        if (mHueRect.contains(startX, startY)) {
            mLastTouchedPanel = PANEL_HUE;
            mHue = pointToHue(event.getY());
            update = true;
        } else if (mSatValRect.contains(startX, startY)) {
            mLastTouchedPanel = PANEL_SAT_VAL;
            float[] result = pointToSatVal(event.getX(), event.getY());
            mSat = result[0];
            mVal = result[1];
            update = true;
        } else if (mAlphaRect != null && mAlphaRect.contains(startX, startY)) {
            mLastTouchedPanel = PANEL_ALPHA;
            mAlpha = pointToAlpha((int) event.getX());
            update = true;
        }
        return update;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int width = 0;
        int height = 0;
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int widthAllowed = MeasureSpec.getSize(widthMeasureSpec);
        int heightAllowed = MeasureSpec.getSize(heightMeasureSpec);
        widthAllowed = chooseWidth(widthMode, widthAllowed);
        heightAllowed = chooseHeight(heightMode, heightAllowed);
        if (!mShowAlphaPanel) {
            height = (int) (widthAllowed - PANEL_SPACING - HUE_PANEL_WIDTH);
            // If calculated height (based on the width) is more than the allowed height.
            if (height > heightAllowed || getTag().equals("landscape")) {
                height = heightAllowed;
                width = (int) (height + PANEL_SPACING + HUE_PANEL_WIDTH);
            } else {
                width = widthAllowed;
            }
        } else {
            width = (int) (heightAllowed - ALPHA_PANEL_HEIGHT + HUE_PANEL_WIDTH);
            if (width > widthAllowed) {
                width = widthAllowed;
                height = (int) (widthAllowed - HUE_PANEL_WIDTH + ALPHA_PANEL_HEIGHT);
            } else {
                height = heightAllowed;
            }
        }
        setMeasuredDimension(width, height);
    }

    private int chooseWidth(int mode, int size) {
        if (mode == MeasureSpec.AT_MOST || mode == MeasureSpec.EXACTLY) {
            return size;
        } else {
            // (mode == MeasureSpec.UNSPECIFIED)
            return getPrefferedWidth();
        }
    }

    private int chooseHeight(int mode, int size) {
        if (mode == MeasureSpec.AT_MOST || mode == MeasureSpec.EXACTLY) {
            return size;
        } else {
            // (mode == MeasureSpec.UNSPECIFIED)
            return getPrefferedHeight();
        }
    }

    private int getPrefferedWidth() {
        int width = getPrefferedHeight();
        if (mShowAlphaPanel) {
            width -= (PANEL_SPACING + ALPHA_PANEL_HEIGHT);
        }
        return (int) (width + HUE_PANEL_WIDTH + PANEL_SPACING);
    }

    private int getPrefferedHeight() {
        int height = (int) (200 * mDensity);
        if (mShowAlphaPanel) {
            height += PANEL_SPACING + ALPHA_PANEL_HEIGHT;
        }
        return height;
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mDrawingRect = new RectF();
        mDrawingRect.left = mDrawingOffset + getPaddingLeft();
        mDrawingRect.right = w - mDrawingOffset - getPaddingRight();
        mDrawingRect.top = mDrawingOffset + getPaddingTop();
        mDrawingRect.bottom = h - mDrawingOffset - getPaddingBottom();
        setUpSatValRect();
        setUpHueRect();
        setUpAlphaRect();
    }

    private void setUpSatValRect() {
        final RectF dRect = mDrawingRect;
        float panelSide = dRect.height() - BORDER_WIDTH_PX * 2;
        if (mShowAlphaPanel) {
            panelSide -= PANEL_SPACING + ALPHA_PANEL_HEIGHT;
        }
        float left = dRect.left + BORDER_WIDTH_PX;
        float top = dRect.top + BORDER_WIDTH_PX;
        float bottom = top + panelSide;
        float right = left + panelSide;
        mSatValRect = new RectF(left, top, right, bottom);
    }

    private void setUpHueRect() {
        final RectF dRect = mDrawingRect;
        float left = dRect.right - HUE_PANEL_WIDTH + BORDER_WIDTH_PX;
        float top = dRect.top + BORDER_WIDTH_PX;
        float bottom = dRect.bottom - BORDER_WIDTH_PX - (mShowAlphaPanel ? (PANEL_SPACING + ALPHA_PANEL_HEIGHT) : 0);
        float right = dRect.right - BORDER_WIDTH_PX;
        mHueRect = new RectF(left, top, right, bottom);
    }

    private void setUpAlphaRect() {
        if (!mShowAlphaPanel)
            return;
        final RectF dRect = mDrawingRect;
        float left = dRect.left + BORDER_WIDTH_PX;
        float top = dRect.bottom - ALPHA_PANEL_HEIGHT + BORDER_WIDTH_PX;
        float bottom = dRect.bottom - BORDER_WIDTH_PX;
        float right = dRect.right - BORDER_WIDTH_PX;
        mAlphaRect = new RectF(left, top, right, bottom);
        mAlphaPattern = new AlphaPatternDrawable((int) (5 * mDensity));
        mAlphaPattern.setBounds(Math.round(mAlphaRect.left), Math.round(mAlphaRect.top), Math.round(mAlphaRect.right), Math.round(mAlphaRect.bottom));
    }

    /**
     * Set a OnColorChangedListener to get notified when the color
     * selected by the user has changed.
     *
     * @param listener
     */
    public void setOnColorChangedListener(OnColorChangedListener listener) {
        mListener = listener;
    }

    /**
     * Set the color of the border surrounding all panels.
     *
     * @param color
     */
    public void setBorderColor(int color) {
        mBorderColor = color;
        invalidate();
    }

    /**
     * Get the color of the border surrounding all panels.
     */
    public int getBorderColor() {
        return mBorderColor;
    }

    /**
     * Get the current color this view is showing.
     *
     * @return the current color.
     */
    public int getColor() {
        return Color.HSVToColor(mAlpha, new float[] { mHue, mSat, mVal });
    }

    /**
     * Set the color the view should show.
     *
     * @param color The color that should be selected.
     */
    public void setColor(int color) {
        setColor(color, false);
    }

    /**
     * Set the color this view should show.
     *
     * @param color    The color that should be selected.
     * @param callback If you want to get a callback to
     *                 your OnColorChangedListener.
     */
    public void setColor(int color, boolean callback) {
        int alpha = Color.alpha(color);
        float[] hsv = new float[3];
        Color.colorToHSV(color, hsv);
        mAlpha = alpha;
        mHue = hsv[0];
        mSat = hsv[1];
        mVal = hsv[2];
        if (callback && mListener != null) {
            mListener.onColorChanged(Color.HSVToColor(mAlpha, new float[] { mHue, mSat, mVal }));
        }
        invalidate();
    }

    /**
     * Get the drawing offset of the color picker view.
     * The drawing offset is the distance from the side of
     * a panel to the side of the view minus the padding.
     * Useful if you want to have your own panel below showing
     * the currently selected color and want to align it perfectly.
     *
     * @return The offset in pixels.
     */
    public float getDrawingOffset() {
        return mDrawingOffset;
    }

    /**
     * Set if the user is allowed to adjust the alpha panel. Default is false.
     * If it is set to false no alpha will be set.
     *
     * @param visible
     */
    public void setAlphaSliderVisible(boolean visible) {
        if (mShowAlphaPanel != visible) {
            mShowAlphaPanel = visible;
            /*
             * Reset all shader to force a recreation.
			 * Otherwise they will not look right after
			 * the size of the view has changed.
			 */
            mValShader = null;
            mSatShader = null;
            mHueShader = null;
            mAlphaShader = null;
            requestLayout();
        }
    }

    public boolean getAlphaSliderVisible() {
        return mShowAlphaPanel;
    }

    public void setSliderTrackerColor(int color) {
        mSliderTrackerColor = color;
        mHueTrackerPaint.setColor(mSliderTrackerColor);
        invalidate();
    }

    public int getSliderTrackerColor() {
        return mSliderTrackerColor;
    }

    /**
     * Set the text that should be shown in the
     * alpha slider. Set to null to disable text.
     *
     * @param res string resource id.
     */
    public void setAlphaSliderText(int res) {
        String text = getContext().getString(res);
        setAlphaSliderText(text);
    }

    /**
     * Set the text that should be shown in the
     * alpha slider. Set to null to disable text.
     *
     * @param text Text that should be shown.
     */
    public void setAlphaSliderText(String text) {
        mAlphaSliderText = text;
        invalidate();
    }

    /**
     * Get the current value of the text
     * that will be shown in the alpha
     * slider.
     *
     * @return
     */
    public String getAlphaSliderText() {
        return mAlphaSliderText;
    }
}

18 Source : ShaderDrawable.java
with Apache License 2.0
from saki4510t

public clreplaced ShaderDrawable extends Drawable {

    private final Paint mPaint;

    private final DrawFilter mDrawFilter;

    @Nullable
    private Shader mShader;

    public ShaderDrawable() {
        this(0, 0);
    }

    /**
     * clearflagsにはPaint.XXX_FLAGをセット
     * @param clearflags
     */
    public ShaderDrawable(final int clearflags) {
        this(clearflags, 0);
    }

    /**
     * clearflags, setFlagsにはPaint.XXX_FLAGをセット
     * @param clearflags
     * @param setFlags
     */
    public ShaderDrawable(final int clearflags, final int setFlags) {
        mPaint = new Paint();
        mDrawFilter = new PaintFlagsDrawFilter(clearflags, setFlags);
    }

    @Override
    public void draw(@NonNull final Canvas canvas) {
        if (mShader != null) {
            final int count = canvas.save();
            final DrawFilter org = canvas.getDrawFilter();
            canvas.setDrawFilter(mDrawFilter);
            mPaint.setShader(mShader);
            canvas.drawPaint(mPaint);
            canvas.setDrawFilter(org);
            canvas.restoreToCount(count);
        }
    }

    @Override
    public void setAlpha(final int alpha) {
        mPaint.setAlpha(alpha);
    }

    @Override
    public void setColorFilter(final ColorFilter cf) {
        mPaint.setColorFilter(cf);
    }

    @Override
    @SuppressLint("Override")
    public ColorFilter getColorFilter() {
        return mPaint.getColorFilter();
    }

    @Override
    public int getOpacity() {
        return PixelFormat.UNKNOWN;
    }

    public void setBounds(@NonNull final RectF bounds) {
        super.setBounds((int) bounds.left, (int) bounds.top, (int) bounds.right, (int) bounds.bottom);
    }

    public void setBounds(final float left, final float top, final float right, final float bottom) {
        super.setBounds((int) left, (int) top, (int) right, (int) bottom);
    }

    public Shader setShader(@Nullable final Shader shader) {
        if (mShader != shader) {
            mShader = shader;
        }
        return shader;
    }

    @Nullable
    public Shader getShader() {
        return mShader;
    }
}

18 Source : ColorPickerView.java
with MIT License
from ric96

/**
 * Displays a color picker to the user and allow them to select a color. A
 * slider for the alpha channel is also available. Enable it by setting
 * setAlphaSliderVisible(boolean) to true.
 *
 * @author Daniel Nilsson
 */
public clreplaced ColorPickerView extends View {

    public interface OnColorChangedListener {

        public void onColorChanged(int color);
    }

    private final static int PANEL_SAT_VAL = 0;

    private final static int PANEL_HUE = 1;

    private final static int PANEL_ALPHA = 2;

    /**
     * The width in pixels of the border surrounding all color panels.
     */
    private final static float BORDER_WIDTH_PX = 1;

    /**
     * The width in dp of the hue panel.
     */
    private float HUE_PANEL_WIDTH = 30f;

    /**
     * The height in dp of the alpha panel
     */
    private float ALPHA_PANEL_HEIGHT = 20f;

    /**
     * The distance in dp between the different color panels.
     */
    private float PANEL_SPACING = 10f;

    /**
     * The radius in dp of the color palette tracker circle.
     */
    private float PALETTE_CIRCLE_TRACKER_RADIUS = 5f;

    /**
     * The dp which the tracker of the hue or alpha panel will extend outside of
     * its bounds.
     */
    private float RECTANGLE_TRACKER_OFFSET = 2f;

    private static float mDensity = 1f;

    private OnColorChangedListener mListener;

    private Paint mSatValPaint;

    private Paint mSatValTrackerPaint;

    private Paint mHuePaint;

    private Paint mHueTrackerPaint;

    private Paint mAlphaPaint;

    private Paint mAlphaTextPaint;

    private Paint mBorderPaint;

    private Shader mValShader;

    private Shader mSatShader;

    private Shader mHueShader;

    private Shader mAlphaShader;

    private int mAlpha = 0xff;

    private float mHue = 360f;

    private float mSat = 0f;

    private float mVal = 0f;

    private String mAlphaSliderText = "Alpha";

    private int mSliderTrackerColor = 0xff1c1c1c;

    private int mBorderColor = 0xff6E6E6E;

    private boolean mShowAlphaPanel = false;

    /*
     * To remember which panel that has the "focus" when processing hardware
     * button data.
     */
    private int mLastTouchedPanel = PANEL_SAT_VAL;

    /**
     * Offset from the edge we must have or else the finger tracker will get
     * clipped when it is drawn outside of the view.
     */
    private float mDrawingOffset;

    /*
     * Distance form the edges of the view of where we are allowed to draw.
     */
    private RectF mDrawingRect;

    private RectF mSatValRect;

    private RectF mHueRect;

    private RectF mAlphaRect;

    private AlphaPatternDrawable mAlphaPattern;

    private Point mStartTouchPoint = null;

    public ColorPickerView(Context context) {
        this(context, null);
    }

    public ColorPickerView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ColorPickerView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    private void init() {
        mDensity = getContext().getResources().getDisplayMetrics().density;
        PALETTE_CIRCLE_TRACKER_RADIUS *= mDensity;
        RECTANGLE_TRACKER_OFFSET *= mDensity;
        HUE_PANEL_WIDTH *= mDensity;
        ALPHA_PANEL_HEIGHT *= mDensity;
        PANEL_SPACING = PANEL_SPACING * mDensity;
        mDrawingOffset = calculateRequiredOffset();
        initPaintTools();
        // Needed for receiving track ball motion events.
        setFocusableInTouchMode(true);
        setFocusable(true);
        setClickable(true);
    }

    private void initPaintTools() {
        mSatValPaint = new Paint();
        mSatValTrackerPaint = new Paint();
        mHuePaint = new Paint();
        mHueTrackerPaint = new Paint();
        mAlphaPaint = new Paint();
        mAlphaTextPaint = new Paint();
        mBorderPaint = new Paint();
        mSatValTrackerPaint.setStyle(Style.STROKE);
        mSatValTrackerPaint.setStrokeWidth(2f * mDensity);
        mSatValTrackerPaint.setAntiAlias(true);
        mHueTrackerPaint.setColor(mSliderTrackerColor);
        mHueTrackerPaint.setStyle(Style.STROKE);
        mHueTrackerPaint.setStrokeWidth(2f * mDensity);
        mHueTrackerPaint.setAntiAlias(true);
        mAlphaTextPaint.setColor(0xff1c1c1c);
        mAlphaTextPaint.setTextSize(14f * mDensity);
        mAlphaTextPaint.setAntiAlias(true);
        mAlphaTextPaint.setTextAlign(Align.CENTER);
        mAlphaTextPaint.setFakeBoldText(true);
    }

    private float calculateRequiredOffset() {
        float offset = Math.max(PALETTE_CIRCLE_TRACKER_RADIUS, RECTANGLE_TRACKER_OFFSET);
        offset = Math.max(offset, BORDER_WIDTH_PX * mDensity);
        return offset * 1.5f;
    }

    private int[] buildHueColorArray() {
        int[] hue = new int[361];
        int count = 0;
        for (int i = hue.length - 1; i >= 0; i--, count++) {
            hue[count] = Color.HSVToColor(new float[] { i, 1f, 1f });
        }
        return hue;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        if (mDrawingRect.width() <= 0 || mDrawingRect.height() <= 0) {
            return;
        }
        drawSatValPanel(canvas);
        drawHuePanel(canvas);
        drawAlphaPanel(canvas);
    }

    private void drawSatValPanel(Canvas canvas) {
        final RectF rect = mSatValRect;
        int rgb = Color.HSVToColor(new float[] { mHue, 1f, 1f });
        if (BORDER_WIDTH_PX > 0) {
            mBorderPaint.setColor(mBorderColor);
            canvas.drawRect(mDrawingRect.left, mDrawingRect.top, rect.right + BORDER_WIDTH_PX, rect.bottom + BORDER_WIDTH_PX, mBorderPaint);
        }
        // On Honeycomb+ we need to use software rendering to create the shader properly
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            setLayerType(View.LAYER_TYPE_SOFTWARE, null);
        }
        // Get the overlaying gradients ready and create the ComposeShader
        if (mValShader == null) {
            mValShader = new LinearGradient(rect.left, rect.top, rect.left, rect.bottom, 0xffffffff, 0xff000000, TileMode.CLAMP);
        }
        mSatShader = new LinearGradient(rect.left, rect.top, rect.right, rect.top, 0xffffffff, rgb, TileMode.CLAMP);
        ComposeShader mShader = new ComposeShader(mValShader, mSatShader, Mode.MULTIPLY);
        mSatValPaint.setShader(mShader);
        canvas.drawRect(rect, mSatValPaint);
        Point p = satValToPoint(mSat, mVal);
        mSatValTrackerPaint.setColor(0xff000000);
        canvas.drawCircle(p.x, p.y, PALETTE_CIRCLE_TRACKER_RADIUS - 1f * mDensity, mSatValTrackerPaint);
        mSatValTrackerPaint.setColor(0xffdddddd);
        canvas.drawCircle(p.x, p.y, PALETTE_CIRCLE_TRACKER_RADIUS, mSatValTrackerPaint);
    }

    private void drawHuePanel(Canvas canvas) {
        final RectF rect = mHueRect;
        if (BORDER_WIDTH_PX > 0) {
            mBorderPaint.setColor(mBorderColor);
            canvas.drawRect(rect.left - BORDER_WIDTH_PX, rect.top - BORDER_WIDTH_PX, rect.right + BORDER_WIDTH_PX, rect.bottom + BORDER_WIDTH_PX, mBorderPaint);
        }
        if (mHueShader == null) {
            mHueShader = new LinearGradient(rect.left, rect.top, rect.left, rect.bottom, buildHueColorArray(), null, TileMode.CLAMP);
            mHuePaint.setShader(mHueShader);
        }
        canvas.drawRect(rect, mHuePaint);
        float rectHeight = 4 * mDensity / 2;
        Point p = hueToPoint(mHue);
        RectF r = new RectF();
        r.left = rect.left - RECTANGLE_TRACKER_OFFSET;
        r.right = rect.right + RECTANGLE_TRACKER_OFFSET;
        r.top = p.y - rectHeight;
        r.bottom = p.y + rectHeight;
        canvas.drawRoundRect(r, 2, 2, mHueTrackerPaint);
    }

    private void drawAlphaPanel(Canvas canvas) {
        if (!mShowAlphaPanel || mAlphaRect == null || mAlphaPattern == null) {
            return;
        }
        final RectF rect = mAlphaRect;
        if (BORDER_WIDTH_PX > 0) {
            mBorderPaint.setColor(mBorderColor);
            canvas.drawRect(rect.left - BORDER_WIDTH_PX, rect.top - BORDER_WIDTH_PX, rect.right + BORDER_WIDTH_PX, rect.bottom + BORDER_WIDTH_PX, mBorderPaint);
        }
        mAlphaPattern.draw(canvas);
        float[] hsv = new float[] { mHue, mSat, mVal };
        int color = Color.HSVToColor(hsv);
        int acolor = Color.HSVToColor(0, hsv);
        mAlphaShader = new LinearGradient(rect.left, rect.top, rect.right, rect.top, color, acolor, TileMode.CLAMP);
        mAlphaPaint.setShader(mAlphaShader);
        canvas.drawRect(rect, mAlphaPaint);
        if (mAlphaSliderText != null && mAlphaSliderText != "") {
            canvas.drawText(mAlphaSliderText, rect.centerX(), rect.centerY() + 4 * mDensity, mAlphaTextPaint);
        }
        float rectWidth = 4 * mDensity / 2;
        Point p = alphaToPoint(mAlpha);
        RectF r = new RectF();
        r.left = p.x - rectWidth;
        r.right = p.x + rectWidth;
        r.top = rect.top - RECTANGLE_TRACKER_OFFSET;
        r.bottom = rect.bottom + RECTANGLE_TRACKER_OFFSET;
        canvas.drawRoundRect(r, 2, 2, mHueTrackerPaint);
    }

    private Point hueToPoint(float hue) {
        final RectF rect = mHueRect;
        final float height = rect.height();
        Point p = new Point();
        p.y = (int) (height - (hue * height / 360f) + rect.top);
        p.x = (int) rect.left;
        return p;
    }

    private Point satValToPoint(float sat, float val) {
        final RectF rect = mSatValRect;
        final float height = rect.height();
        final float width = rect.width();
        Point p = new Point();
        p.x = (int) (sat * width + rect.left);
        p.y = (int) ((1f - val) * height + rect.top);
        return p;
    }

    private Point alphaToPoint(int alpha) {
        final RectF rect = mAlphaRect;
        final float width = rect.width();
        Point p = new Point();
        p.x = (int) (width - (alpha * width / 0xff) + rect.left);
        p.y = (int) rect.top;
        return p;
    }

    private float[] pointToSatVal(float x, float y) {
        final RectF rect = mSatValRect;
        float[] result = new float[2];
        float width = rect.width();
        float height = rect.height();
        if (x < rect.left) {
            x = 0f;
        } else if (x > rect.right) {
            x = width;
        } else {
            x = x - rect.left;
        }
        if (y < rect.top) {
            y = 0f;
        } else if (y > rect.bottom) {
            y = height;
        } else {
            y = y - rect.top;
        }
        result[0] = 1.f / width * x;
        result[1] = 1.f - (1.f / height * y);
        return result;
    }

    private float pointToHue(float y) {
        final RectF rect = mHueRect;
        float height = rect.height();
        if (y < rect.top) {
            y = 0f;
        } else if (y > rect.bottom) {
            y = height;
        } else {
            y = y - rect.top;
        }
        return 360f - (y * 360f / height);
    }

    private int pointToAlpha(int x) {
        final RectF rect = mAlphaRect;
        final int width = (int) rect.width();
        if (x < rect.left) {
            x = 0;
        } else if (x > rect.right) {
            x = width;
        } else {
            x = x - (int) rect.left;
        }
        return 0xff - (x * 0xff / width);
    }

    @Override
    public boolean onTrackballEvent(MotionEvent event) {
        float x = event.getX();
        float y = event.getY();
        boolean update = false;
        if (event.getAction() == MotionEvent.ACTION_MOVE) {
            switch(mLastTouchedPanel) {
                case PANEL_SAT_VAL:
                    float sat, val;
                    sat = mSat + x / 50f;
                    val = mVal - y / 50f;
                    if (sat < 0f) {
                        sat = 0f;
                    } else if (sat > 1f) {
                        sat = 1f;
                    }
                    if (val < 0f) {
                        val = 0f;
                    } else if (val > 1f) {
                        val = 1f;
                    }
                    mSat = sat;
                    mVal = val;
                    update = true;
                    break;
                case PANEL_HUE:
                    float hue = mHue - y * 10f;
                    if (hue < 0f) {
                        hue = 0f;
                    } else if (hue > 360f) {
                        hue = 360f;
                    }
                    mHue = hue;
                    update = true;
                    break;
                case PANEL_ALPHA:
                    if (!mShowAlphaPanel || mAlphaRect == null) {
                        update = false;
                    } else {
                        int alpha = (int) (mAlpha - x * 10);
                        if (alpha < 0) {
                            alpha = 0;
                        } else if (alpha > 0xff) {
                            alpha = 0xff;
                        }
                        mAlpha = alpha;
                        update = true;
                    }
                    break;
            }
        }
        if (update) {
            if (mListener != null) {
                mListener.onColorChanged(Color.HSVToColor(mAlpha, new float[] { mHue, mSat, mVal }));
            }
            invalidate();
            return true;
        }
        return super.onTrackballEvent(event);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        boolean update = false;
        switch(event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mStartTouchPoint = new Point((int) event.getX(), (int) event.getY());
                update = moveTrackersIfNeeded(event);
                break;
            case MotionEvent.ACTION_MOVE:
                update = moveTrackersIfNeeded(event);
                break;
            case MotionEvent.ACTION_UP:
                mStartTouchPoint = null;
                update = moveTrackersIfNeeded(event);
                break;
        }
        if (update) {
            requestFocus();
            if (mListener != null) {
                mListener.onColorChanged(Color.HSVToColor(mAlpha, new float[] { mHue, mSat, mVal }));
            }
            invalidate();
            return true;
        }
        return super.onTouchEvent(event);
    }

    private boolean moveTrackersIfNeeded(MotionEvent event) {
        if (mStartTouchPoint == null)
            return false;
        boolean update = false;
        int startX = mStartTouchPoint.x;
        int startY = mStartTouchPoint.y;
        if (mHueRect.contains(startX, startY)) {
            mLastTouchedPanel = PANEL_HUE;
            mHue = pointToHue(event.getY());
            update = true;
        } else if (mSatValRect.contains(startX, startY)) {
            mLastTouchedPanel = PANEL_SAT_VAL;
            float[] result = pointToSatVal(event.getX(), event.getY());
            mSat = result[0];
            mVal = result[1];
            update = true;
        } else if (mAlphaRect != null && mAlphaRect.contains(startX, startY)) {
            mLastTouchedPanel = PANEL_ALPHA;
            mAlpha = pointToAlpha((int) event.getX());
            update = true;
        }
        return update;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int width = 0;
        int height = 0;
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int widthAllowed = MeasureSpec.getSize(widthMeasureSpec);
        int heightAllowed = MeasureSpec.getSize(heightMeasureSpec);
        widthAllowed = chooseWidth(widthMode, widthAllowed);
        heightAllowed = chooseHeight(heightMode, heightAllowed);
        if (!mShowAlphaPanel) {
            height = (int) (widthAllowed - PANEL_SPACING - HUE_PANEL_WIDTH);
            // If calculated height (based on the width) is more than the
            // allowed height.
            if (height > heightAllowed && heightMode != MeasureSpec.UNSPECIFIED) {
                height = heightAllowed;
                width = (int) (height + PANEL_SPACING + HUE_PANEL_WIDTH);
            } else {
                width = widthAllowed;
            }
        } else {
            width = (int) (heightAllowed - ALPHA_PANEL_HEIGHT + HUE_PANEL_WIDTH);
            if (width > widthAllowed && widthMode != MeasureSpec.UNSPECIFIED) {
                width = widthAllowed;
                height = (int) (widthAllowed - HUE_PANEL_WIDTH + ALPHA_PANEL_HEIGHT);
            } else {
                height = heightAllowed;
            }
        }
        setMeasuredDimension(width, height);
    }

    private int chooseWidth(int mode, int size) {
        if (mode == MeasureSpec.AT_MOST || mode == MeasureSpec.EXACTLY) {
            return size;
        } else {
            // (mode == MeasureSpec.UNSPECIFIED)
            return getPrefferedWidth();
        }
    }

    private int chooseHeight(int mode, int size) {
        if (mode == MeasureSpec.AT_MOST || mode == MeasureSpec.EXACTLY) {
            return size;
        } else {
            // (mode == MeasureSpec.UNSPECIFIED)
            return getPrefferedHeight();
        }
    }

    private int getPrefferedWidth() {
        int width = getPrefferedHeight();
        if (mShowAlphaPanel) {
            width -= (PANEL_SPACING + ALPHA_PANEL_HEIGHT);
        }
        return (int) (width + HUE_PANEL_WIDTH + PANEL_SPACING);
    }

    private int getPrefferedHeight() {
        int height = (int) (200 * mDensity);
        if (mShowAlphaPanel) {
            height += PANEL_SPACING + ALPHA_PANEL_HEIGHT;
        }
        return height;
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mDrawingRect = new RectF();
        mDrawingRect.left = mDrawingOffset + getPaddingLeft();
        mDrawingRect.right = w - mDrawingOffset - getPaddingRight();
        mDrawingRect.top = mDrawingOffset + getPaddingTop();
        mDrawingRect.bottom = h - mDrawingOffset - getPaddingBottom();
        setUpSatValRect();
        setUpHueRect();
        setUpAlphaRect();
    }

    private void setUpSatValRect() {
        final RectF dRect = mDrawingRect;
        float panelSide = dRect.height() - BORDER_WIDTH_PX * 2;
        if (mShowAlphaPanel) {
            panelSide -= PANEL_SPACING + ALPHA_PANEL_HEIGHT;
        }
        float left = dRect.left + BORDER_WIDTH_PX;
        float top = dRect.top + BORDER_WIDTH_PX;
        float bottom = top + panelSide;
        float right = left + panelSide;
        mSatValRect = new RectF(left, top, right, bottom);
    }

    private void setUpHueRect() {
        final RectF dRect = mDrawingRect;
        float left = dRect.right - HUE_PANEL_WIDTH + BORDER_WIDTH_PX;
        float top = dRect.top + BORDER_WIDTH_PX;
        float bottom = dRect.bottom - BORDER_WIDTH_PX - (mShowAlphaPanel ? (PANEL_SPACING + ALPHA_PANEL_HEIGHT) : 0);
        float right = dRect.right - BORDER_WIDTH_PX;
        mHueRect = new RectF(left, top, right, bottom);
    }

    private void setUpAlphaRect() {
        if (!mShowAlphaPanel) {
            return;
        }
        final RectF dRect = mDrawingRect;
        float left = dRect.left + BORDER_WIDTH_PX;
        float top = dRect.bottom - ALPHA_PANEL_HEIGHT + BORDER_WIDTH_PX;
        float bottom = dRect.bottom - BORDER_WIDTH_PX;
        float right = dRect.right - BORDER_WIDTH_PX;
        mAlphaRect = new RectF(left, top, right, bottom);
        mAlphaPattern = new AlphaPatternDrawable((int) (5 * mDensity));
        mAlphaPattern.setBounds(Math.round(mAlphaRect.left), Math.round(mAlphaRect.top), Math.round(mAlphaRect.right), Math.round(mAlphaRect.bottom));
    }

    /**
     * Set a OnColorChangedListener to get notified when the color selected by
     * the user has changed.
     *
     * @param listener
     */
    public void setOnColorChangedListener(OnColorChangedListener listener) {
        mListener = listener;
    }

    /**
     * Set the color of the border surrounding all panels.
     *
     * @param color
     */
    public void setBorderColor(int color) {
        mBorderColor = color;
        invalidate();
    }

    /**
     * Get the color of the border surrounding all panels.
     */
    public int getBorderColor() {
        return mBorderColor;
    }

    /**
     * Get the current color this view is showing.
     *
     * @return the current color.
     */
    public int getColor() {
        return Color.HSVToColor(mAlpha, new float[] { mHue, mSat, mVal });
    }

    /**
     * Set the color the view should show.
     *
     * @param color The color that should be selected.
     */
    public void setColor(int color) {
        setColor(color, false);
    }

    /**
     * Set the color this view should show.
     *
     * @param color The color that should be selected.
     * @param callback If you want to get a callback to your
     *            OnColorChangedListener.
     */
    public void setColor(int color, boolean callback) {
        int alpha = Color.alpha(color);
        int red = Color.red(color);
        int blue = Color.blue(color);
        int green = Color.green(color);
        float[] hsv = new float[3];
        Color.RGBToHSV(red, green, blue, hsv);
        mAlpha = alpha;
        mHue = hsv[0];
        mSat = hsv[1];
        mVal = hsv[2];
        if (callback && mListener != null) {
            mListener.onColorChanged(Color.HSVToColor(mAlpha, new float[] { mHue, mSat, mVal }));
        }
        invalidate();
    }

    /**
     * Get the drawing offset of the color picker view. The drawing offset is
     * the distance from the side of a panel to the side of the view minus the
     * padding. Useful if you want to have your own panel below showing the
     * currently selected color and want to align it perfectly.
     *
     * @return The offset in pixels.
     */
    public float getDrawingOffset() {
        return mDrawingOffset;
    }

    /**
     * Set if the user is allowed to adjust the alpha panel. Default is false.
     * If it is set to false no alpha will be set.
     *
     * @param visible
     */
    public void setAlphaSliderVisible(boolean visible) {
        if (mShowAlphaPanel != visible) {
            mShowAlphaPanel = visible;
            /*
             * Reset all shader to force a recreation. Otherwise they will not
             * look right after the size of the view has changed.
             */
            mValShader = null;
            mSatShader = null;
            mHueShader = null;
            mAlphaShader = null;
            requestLayout();
        }
    }

    public boolean isAlphaSliderVisible() {
        return mShowAlphaPanel;
    }

    public void setSliderTrackerColor(int color) {
        mSliderTrackerColor = color;
        mHueTrackerPaint.setColor(mSliderTrackerColor);
        invalidate();
    }

    public int getSliderTrackerColor() {
        return mSliderTrackerColor;
    }

    /**
     * Set the text that should be shown in the alpha slider. Set to null to
     * disable text.
     *
     * @param res string resource id.
     */
    public void setAlphaSliderText(int res) {
        String text = getContext().getString(res);
        setAlphaSliderText(text);
    }

    /**
     * Set the text that should be shown in the alpha slider. Set to null to
     * disable text.
     *
     * @param text Text that should be shown.
     */
    public void setAlphaSliderText(String text) {
        mAlphaSliderText = text;
        invalidate();
    }

    /**
     * Get the current value of the text that will be shown in the alpha slider.
     *
     * @return
     */
    public String getAlphaSliderText() {
        return mAlphaSliderText;
    }
}

18 Source : MasterPaintView.java
with Apache License 2.0
from REBOOTERS

private void reDraw(Shader shader) {
    mPaint.setShader(shader);
    invalidate();
}

18 Source : ReflectItemView.java
with Apache License 2.0
from Pluckypan

/**
 * 设置倒影的shader属性.
 */
public void setReflectionShader(Shader shader) {
    if (mRefPaint != null) {
        mRefPaint.setShader(shader);
        invalidate();
    }
}

See More Examples