add files
|
@ -7,3 +7,4 @@
|
|||
/build
|
||||
/captures
|
||||
.externalNativeBuild
|
||||
/rc
|
||||
|
|
After Width: | Height: | Size: 96 B |
After Width: | Height: | Size: 257 B |
After Width: | Height: | Size: 216 B |
After Width: | Height: | Size: 276 B |
After Width: | Height: | Size: 294 B |
After Width: | Height: | Size: 350 B |
|
@ -0,0 +1 @@
|
|||
/build
|
|
@ -0,0 +1,25 @@
|
|||
apply plugin: 'com.android.library'
|
||||
|
||||
android {
|
||||
|
||||
compileSdkVersion 26
|
||||
buildToolsVersion '26.0.2'
|
||||
resourcePrefix "cpv_"
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 14
|
||||
targetSdkVersion 26
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
abortOnError false
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile 'com.android.support:appcompat-v7:26.1.0'
|
||||
}
|
||||
|
||||
//apply plugin: 'com.getkeepsafe.dexcount'
|
||||
//apply from: 'https://raw.githubusercontent.com/jaredrummler/android-artifact-push/master/artifactory/publication.gradle'
|
||||
//apply from: 'https://raw.githubusercontent.com/jaredrummler/android-artifact-push/master/maven/gradle-mvn-push.gradle'
|
|
@ -0,0 +1,22 @@
|
|||
VERSION_NAME=2.1.7
|
||||
VERSION_CODE=217
|
||||
GROUP=com.jrummyapps
|
||||
ARTIFACT_ID=colorpicker
|
||||
|
||||
POM_NAME=colorpicker
|
||||
POM_ARTIFACT_ID=colorpicker
|
||||
POM_PACKAGING=aar
|
||||
|
||||
POM_DESCRIPTION=A simple good looking color picker component for Android
|
||||
POM_URL=https://github.com/jrummyapps/colorpicker
|
||||
POM_SCM_URL=https://github.com/jrummyapps/colorpicker
|
||||
POM_SCM_CONNECTION=scm:git@github.com:jrummyapps/colorpicker.git
|
||||
POM_SCM_DEV_CONNECTION=scm:git@github.com:jrummyapps/colorpicker.git
|
||||
POM_LICENCE_NAME=The Apache Software License, Version 2.0
|
||||
POM_LICENCE_URL=http://www.apache.org/licenses/LICENSE-2.0.txt
|
||||
POM_LICENCE_DIST=repo
|
||||
POM_DEVELOPER_ID=jrummyapps
|
||||
POM_DEVELOPER_NAME=JRummy Apps Inc.
|
||||
|
||||
SNAPSHOT_REPOSITORY_URL=https://oss.sonatype.org/content/repositories/snapshots
|
||||
RELEASE_REPOSITORY_URL=https://oss.sonatype.org/service/local/staging/deploy/maven2
|
|
@ -0,0 +1,17 @@
|
|||
# Add project specific ProGuard rules here.
|
||||
# By default, the flags in this file are appended to flags specified
|
||||
# in C:\android-sdk/tools/proguard/proguard-android.txt
|
||||
# You can edit the include path and order by changing the proguardFiles
|
||||
# directive in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# Add any project specific keep options here:
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
|
@ -0,0 +1 @@
|
|||
<manifest package="com.jrummyapps.android.colorpicker"/>
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* Copyright (C) 2017 JRummy Apps Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.jrummyapps.android.colorpicker;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Bitmap.Config;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.ColorFilter;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
/**
|
||||
* This drawable will draw a simple white and gray chessboard pattern.
|
||||
* It's the pattern you will often see as a background behind a partly transparent image in many applications.
|
||||
*/
|
||||
class AlphaPatternDrawable extends Drawable {
|
||||
|
||||
private int rectangleSize = 10;
|
||||
|
||||
private Paint paint = new Paint();
|
||||
private Paint paintWhite = new Paint();
|
||||
private Paint paintGray = new Paint();
|
||||
|
||||
private int numRectanglesHorizontal;
|
||||
private int numRectanglesVertical;
|
||||
|
||||
/**
|
||||
* Bitmap in which the pattern will be cached.
|
||||
* This is so the pattern will not have to be recreated each time draw() gets called.
|
||||
* Because recreating the pattern i rather expensive. I will only be recreated if the size changes.
|
||||
*/
|
||||
private Bitmap bitmap;
|
||||
|
||||
AlphaPatternDrawable(int rectangleSize) {
|
||||
this.rectangleSize = rectangleSize;
|
||||
paintWhite.setColor(0xFFFFFFFF);
|
||||
paintGray.setColor(0xFFCBCBCB);
|
||||
}
|
||||
|
||||
@Override public void draw(Canvas canvas) {
|
||||
if (bitmap != null && !bitmap.isRecycled()) {
|
||||
canvas.drawBitmap(bitmap, null, getBounds(), paint);
|
||||
}
|
||||
}
|
||||
|
||||
@Override public int getOpacity() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override public void setAlpha(int alpha) {
|
||||
throw new UnsupportedOperationException("Alpha is not supported by this drawable.");
|
||||
}
|
||||
|
||||
@Override public void setColorFilter(ColorFilter cf) {
|
||||
throw new UnsupportedOperationException("ColorFilter is not supported by this drawable.");
|
||||
}
|
||||
|
||||
@Override protected void onBoundsChange(Rect bounds) {
|
||||
super.onBoundsChange(bounds);
|
||||
int height = bounds.height();
|
||||
int width = bounds.width();
|
||||
numRectanglesHorizontal = (int) Math.ceil((width / rectangleSize));
|
||||
numRectanglesVertical = (int) Math.ceil(height / rectangleSize);
|
||||
generatePatternBitmap();
|
||||
}
|
||||
|
||||
/**
|
||||
* This will generate a bitmap with the pattern as big as the rectangle we were allow to draw on.
|
||||
* We do this to chache the bitmap so we don't need to recreate it each time draw() is called since it takes a few milliseconds
|
||||
*/
|
||||
private void generatePatternBitmap() {
|
||||
if (getBounds().width() <= 0 || getBounds().height() <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
bitmap = Bitmap.createBitmap(getBounds().width(), getBounds().height(), Config.ARGB_8888);
|
||||
Canvas canvas = new Canvas(bitmap);
|
||||
|
||||
Rect r = new Rect();
|
||||
boolean verticalStartWhite = true;
|
||||
for (int i = 0; i <= numRectanglesVertical; i++) {
|
||||
boolean isWhite = verticalStartWhite;
|
||||
for (int j = 0; j <= numRectanglesHorizontal; j++) {
|
||||
r.top = i * rectangleSize;
|
||||
r.left = j * rectangleSize;
|
||||
r.bottom = r.top + rectangleSize;
|
||||
r.right = r.left + rectangleSize;
|
||||
canvas.drawRect(r, isWhite ? paintWhite : paintGray);
|
||||
isWhite = !isWhite;
|
||||
}
|
||||
verticalStartWhite = !verticalStartWhite;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,147 @@
|
|||
/*
|
||||
* Copyright (C) 2017 JRummy Apps Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.jrummyapps.android.colorpicker;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.support.v4.graphics.ColorUtils;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.ImageView;
|
||||
|
||||
class ColorPaletteAdapter extends BaseAdapter {
|
||||
|
||||
/*package*/ final OnColorSelectedListener listener;
|
||||
/*package*/ final int[] colors;
|
||||
/*package*/ int selectedPosition;
|
||||
/*package*/ int colorShape;
|
||||
|
||||
ColorPaletteAdapter(OnColorSelectedListener listener,
|
||||
int[] colors,
|
||||
int selectedPosition,
|
||||
@ColorShape int colorShape) {
|
||||
this.listener = listener;
|
||||
this.colors = colors;
|
||||
this.selectedPosition = selectedPosition;
|
||||
this.colorShape = colorShape;
|
||||
}
|
||||
|
||||
@Override public int getCount() {
|
||||
return colors.length;
|
||||
}
|
||||
|
||||
@Override public Object getItem(int position) {
|
||||
return colors[position];
|
||||
}
|
||||
|
||||
@Override public long getItemId(int position) {
|
||||
return position;
|
||||
}
|
||||
|
||||
@Override public View getView(int position, View convertView, ViewGroup parent) {
|
||||
final ViewHolder holder;
|
||||
if (convertView == null) {
|
||||
holder = new ViewHolder(parent.getContext());
|
||||
convertView = holder.view;
|
||||
} else {
|
||||
holder = (ViewHolder) convertView.getTag();
|
||||
}
|
||||
holder.setup(position);
|
||||
return convertView;
|
||||
}
|
||||
|
||||
void selectNone() {
|
||||
selectedPosition = -1;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
interface OnColorSelectedListener {
|
||||
|
||||
void onColorSelected(int color);
|
||||
}
|
||||
|
||||
private final class ViewHolder {
|
||||
|
||||
View view;
|
||||
ColorPanelView colorPanelView;
|
||||
ImageView imageView;
|
||||
int originalBorderColor;
|
||||
|
||||
ViewHolder(Context context) {
|
||||
int layoutResId;
|
||||
if (colorShape == ColorShape.SQUARE) {
|
||||
layoutResId = R.layout.cpv_color_item_square;
|
||||
} else {
|
||||
layoutResId = R.layout.cpv_color_item_circle;
|
||||
}
|
||||
view = View.inflate(context, layoutResId, null);
|
||||
colorPanelView = (ColorPanelView) view.findViewById(R.id.cpv_color_panel_view);
|
||||
imageView = (ImageView) view.findViewById(R.id.cpv_color_image_view);
|
||||
originalBorderColor = colorPanelView.getBorderColor();
|
||||
view.setTag(this);
|
||||
}
|
||||
|
||||
void setup(int position) {
|
||||
int color = colors[position];
|
||||
int alpha = Color.alpha(color);
|
||||
colorPanelView.setColor(color);
|
||||
imageView.setImageResource(selectedPosition == position ? R.drawable.cpv_preset_checked : 0);
|
||||
if (alpha != 255) {
|
||||
if (alpha <= ColorPickerDialog.ALPHA_THRESHOLD) {
|
||||
colorPanelView.setBorderColor(color | 0xFF000000);
|
||||
imageView.setColorFilter(/*color | 0xFF000000*/Color.BLACK, PorterDuff.Mode.SRC_IN);
|
||||
} else {
|
||||
colorPanelView.setBorderColor(originalBorderColor);
|
||||
imageView.setColorFilter(Color.WHITE, PorterDuff.Mode.SRC_IN);
|
||||
}
|
||||
} else {
|
||||
setColorFilter(position);
|
||||
}
|
||||
setOnClickListener(position);
|
||||
}
|
||||
|
||||
private void setOnClickListener(final int position) {
|
||||
colorPanelView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override public void onClick(View v) {
|
||||
if (selectedPosition != position) {
|
||||
selectedPosition = position;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
listener.onColorSelected(colors[position]);
|
||||
}
|
||||
});
|
||||
colorPanelView.setOnLongClickListener(new View.OnLongClickListener() {
|
||||
@Override public boolean onLongClick(View v) {
|
||||
colorPanelView.showHint();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setColorFilter(int position) {
|
||||
if (position == selectedPosition && ColorUtils.calculateLuminance(colors[position]) >= 0.65) {
|
||||
imageView.setColorFilter(Color.BLACK, PorterDuff.Mode.SRC_IN);
|
||||
} else {
|
||||
imageView.setColorFilter(null);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,323 @@
|
|||
/*
|
||||
* Copyright (C) 2017 JRummy Apps Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.jrummyapps.android.colorpicker;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapShader;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.Shader;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcelable;
|
||||
import android.support.annotation.ColorInt;
|
||||
import android.support.v4.view.GravityCompat;
|
||||
import android.support.v4.view.ViewCompat;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.TypedValue;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* This class draws a panel which which will be filled with a color which can be set. It can be used to show the
|
||||
* currently selected color which you will get from the {@link ColorPickerView}.
|
||||
*/
|
||||
public class ColorPanelView extends View {
|
||||
|
||||
private final static int DEFAULT_BORDER_COLOR = 0xFF6E6E6E;
|
||||
|
||||
private Drawable alphaPattern;
|
||||
private Paint borderPaint;
|
||||
private Paint colorPaint;
|
||||
private Paint alphaPaint;
|
||||
private Paint originalPaint;
|
||||
private Rect drawingRect;
|
||||
private Rect colorRect;
|
||||
private RectF centerRect = new RectF();
|
||||
private boolean showOldColor;
|
||||
|
||||
/* The width in pixels of the border surrounding the color panel. */
|
||||
private int borderWidthPx;
|
||||
private int borderColor = DEFAULT_BORDER_COLOR;
|
||||
private int color = Color.BLACK;
|
||||
private int shape;
|
||||
|
||||
public ColorPanelView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public ColorPanelView(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public ColorPanelView(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
init(context, attrs);
|
||||
}
|
||||
|
||||
@Override public Parcelable onSaveInstanceState() {
|
||||
Bundle state = new Bundle();
|
||||
state.putParcelable("instanceState", super.onSaveInstanceState());
|
||||
state.putInt("color", color);
|
||||
return state;
|
||||
}
|
||||
|
||||
@Override public void onRestoreInstanceState(Parcelable state) {
|
||||
if (state instanceof Bundle) {
|
||||
Bundle bundle = (Bundle) state;
|
||||
color = bundle.getInt("color");
|
||||
state = bundle.getParcelable("instanceState");
|
||||
}
|
||||
super.onRestoreInstanceState(state);
|
||||
}
|
||||
|
||||
private void init(Context context, AttributeSet attrs) {
|
||||
TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.ColorPanelView);
|
||||
shape = a.getInt(R.styleable.ColorPanelView_cpv_colorShape, ColorShape.CIRCLE);
|
||||
showOldColor = a.getBoolean(R.styleable.ColorPanelView_cpv_showOldColor, false);
|
||||
if (showOldColor && shape != ColorShape.CIRCLE) {
|
||||
throw new IllegalStateException("Color preview is only available in circle mode");
|
||||
}
|
||||
borderColor = a.getColor(R.styleable.ColorPanelView_cpv_borderColor, DEFAULT_BORDER_COLOR);
|
||||
a.recycle();
|
||||
if (borderColor == DEFAULT_BORDER_COLOR) {
|
||||
// If no specific border color has been set we take the default secondary text color as border/slider color.
|
||||
// Thus it will adopt to theme changes automatically.
|
||||
final TypedValue value = new TypedValue();
|
||||
TypedArray typedArray = context.obtainStyledAttributes(value.data, new int[]{android.R.attr.textColorSecondary});
|
||||
borderColor = typedArray.getColor(0, borderColor);
|
||||
typedArray.recycle();
|
||||
}
|
||||
borderWidthPx = DrawingUtils.dpToPx(context, 1);
|
||||
borderPaint = new Paint();
|
||||
borderPaint.setAntiAlias(true);
|
||||
colorPaint = new Paint();
|
||||
colorPaint.setAntiAlias(true);
|
||||
if (showOldColor) {
|
||||
originalPaint = new Paint();
|
||||
}
|
||||
if (shape == ColorShape.CIRCLE) {
|
||||
Bitmap bitmap = ((BitmapDrawable) context.getResources().getDrawable(R.drawable.cpv_alpha)).getBitmap();
|
||||
alphaPaint = new Paint();
|
||||
alphaPaint.setAntiAlias(true);
|
||||
BitmapShader shader = new BitmapShader(bitmap, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
|
||||
alphaPaint.setShader(shader);
|
||||
}
|
||||
}
|
||||
|
||||
@Override protected void onDraw(Canvas canvas) {
|
||||
borderPaint.setColor(borderColor);
|
||||
colorPaint.setColor(color);
|
||||
if (shape == ColorShape.SQUARE) {
|
||||
if (borderWidthPx > 0) {
|
||||
canvas.drawRect(drawingRect, borderPaint);
|
||||
}
|
||||
if (alphaPattern != null) {
|
||||
alphaPattern.draw(canvas);
|
||||
}
|
||||
canvas.drawRect(colorRect, colorPaint);
|
||||
} else if (shape == ColorShape.CIRCLE) {
|
||||
final int outerRadius = getMeasuredWidth() / 2;
|
||||
if (borderWidthPx > 0) {
|
||||
canvas.drawCircle(getMeasuredWidth() / 2,
|
||||
getMeasuredHeight() / 2,
|
||||
outerRadius,
|
||||
borderPaint);
|
||||
}
|
||||
if (Color.alpha(color) < 255) {
|
||||
canvas.drawCircle(getMeasuredWidth() / 2,
|
||||
getMeasuredHeight() / 2,
|
||||
outerRadius - borderWidthPx, alphaPaint);
|
||||
}
|
||||
if (showOldColor) {
|
||||
canvas.drawArc(centerRect, 90, 180, true, originalPaint);
|
||||
canvas.drawArc(centerRect, 270, 180, true, colorPaint);
|
||||
} else {
|
||||
canvas.drawCircle(getMeasuredWidth() / 2,
|
||||
getMeasuredHeight() / 2,
|
||||
outerRadius - borderWidthPx,
|
||||
colorPaint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
if (shape == ColorShape.SQUARE) {
|
||||
int width = MeasureSpec.getSize(widthMeasureSpec);
|
||||
int height = MeasureSpec.getSize(heightMeasureSpec);
|
||||
setMeasuredDimension(width, height);
|
||||
} else if (shape == ColorShape.CIRCLE) {
|
||||
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
|
||||
setMeasuredDimension(getMeasuredWidth(), getMeasuredWidth());
|
||||
} else {
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
}
|
||||
}
|
||||
|
||||
@Override protected void onSizeChanged(int w, int h, int oldw, int oldh) {
|
||||
super.onSizeChanged(w, h, oldw, oldh);
|
||||
if (shape == ColorShape.SQUARE || showOldColor) {
|
||||
drawingRect = new Rect();
|
||||
drawingRect.left = getPaddingLeft();
|
||||
drawingRect.right = w - getPaddingRight();
|
||||
drawingRect.top = getPaddingTop();
|
||||
drawingRect.bottom = h - getPaddingBottom();
|
||||
if (showOldColor) {
|
||||
setUpCenterRect();
|
||||
} else {
|
||||
setUpColorRect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setUpCenterRect() {
|
||||
final Rect dRect = drawingRect;
|
||||
int left = dRect.left + borderWidthPx;
|
||||
int top = dRect.top + borderWidthPx;
|
||||
int bottom = dRect.bottom - borderWidthPx;
|
||||
int right = dRect.right - borderWidthPx;
|
||||
centerRect = new RectF(left, top, right, bottom);
|
||||
}
|
||||
|
||||
private void setUpColorRect() {
|
||||
final Rect dRect = drawingRect;
|
||||
int left = dRect.left + borderWidthPx;
|
||||
int top = dRect.top + borderWidthPx;
|
||||
int bottom = dRect.bottom - borderWidthPx;
|
||||
int right = dRect.right - borderWidthPx;
|
||||
colorRect = new Rect(left, top, right, bottom);
|
||||
alphaPattern = new AlphaPatternDrawable(DrawingUtils.dpToPx(getContext(), 4));
|
||||
alphaPattern.setBounds(Math.round(colorRect.left),
|
||||
Math.round(colorRect.top),
|
||||
Math.round(colorRect.right),
|
||||
Math.round(colorRect.bottom));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the color that should be shown by this view.
|
||||
*
|
||||
* @param color
|
||||
* the color value
|
||||
*/
|
||||
public void setColor(int color) {
|
||||
this.color = color;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the color currently show by this view.
|
||||
*
|
||||
* @return the color value
|
||||
*/
|
||||
public int getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the original color. This is only used for previewing colors.
|
||||
*
|
||||
* @param color
|
||||
* The original color
|
||||
*/
|
||||
public void setOriginalColor(@ColorInt int color) {
|
||||
if (originalPaint != null) {
|
||||
originalPaint.setColor(color);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the color of the border surrounding the panel.
|
||||
*
|
||||
* @param color
|
||||
* the color value
|
||||
*/
|
||||
public void setBorderColor(int color) {
|
||||
borderColor = color;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the color of the border surrounding the panel.
|
||||
*/
|
||||
public int getBorderColor() {
|
||||
return borderColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the shape.
|
||||
*
|
||||
* @param shape
|
||||
* Either {@link ColorShape#SQUARE} or {@link ColorShape#CIRCLE}.
|
||||
*/
|
||||
public void setShape(@ColorShape int shape) {
|
||||
this.shape = shape;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the shape
|
||||
*
|
||||
* @return Either {@link ColorShape#SQUARE} or {@link ColorShape#CIRCLE}.
|
||||
*/
|
||||
@ColorShape public int getShape() {
|
||||
return shape;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a toast message with the hex color code below the view.
|
||||
*/
|
||||
public void showHint() {
|
||||
final int[] screenPos = new int[2];
|
||||
final Rect displayFrame = new Rect();
|
||||
getLocationOnScreen(screenPos);
|
||||
getWindowVisibleDisplayFrame(displayFrame);
|
||||
final Context context = getContext();
|
||||
final int width = getWidth();
|
||||
final int height = getHeight();
|
||||
final int midy = screenPos[1] + height / 2;
|
||||
int referenceX = screenPos[0] + width / 2;
|
||||
if (ViewCompat.getLayoutDirection(this) == ViewCompat.LAYOUT_DIRECTION_LTR) {
|
||||
final int screenWidth = context.getResources().getDisplayMetrics().widthPixels;
|
||||
referenceX = screenWidth - referenceX; // mirror
|
||||
}
|
||||
StringBuilder hint = new StringBuilder("#");
|
||||
if (Color.alpha(color) != 255) {
|
||||
hint.append(Integer.toHexString(color).toUpperCase(Locale.ENGLISH));
|
||||
} else {
|
||||
hint.append(String.format("%06X", 0xFFFFFF & color).toUpperCase(Locale.ENGLISH));
|
||||
}
|
||||
Toast cheatSheet = Toast.makeText(context, hint.toString(), Toast.LENGTH_SHORT);
|
||||
if (midy < displayFrame.height()) {
|
||||
// Show along the top; follow action buttons
|
||||
cheatSheet.setGravity(Gravity.TOP | GravityCompat.END, referenceX,
|
||||
screenPos[1] + height - displayFrame.top);
|
||||
} else {
|
||||
// Show along the bottom center
|
||||
cheatSheet.setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, height);
|
||||
}
|
||||
cheatSheet.show();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,879 @@
|
|||
/*
|
||||
* Copyright (C) 2017 JRummy Apps Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.jrummyapps.android.colorpicker;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Dialog;
|
||||
import android.app.DialogFragment;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.ColorInt;
|
||||
import android.support.annotation.IntDef;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.StringRes;
|
||||
import android.support.v4.graphics.ColorUtils;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.text.Editable;
|
||||
import android.text.InputFilter;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.TypedValue;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.View.OnTouchListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.WindowManager;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.GridView;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.TextView;
|
||||
import com.jrummyapps.android.colorpicker.ColorPickerView.OnColorChangedListener;
|
||||
import java.util.Arrays;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* <p>A dialog to pick a color.</p>
|
||||
*
|
||||
* <p>The {@link Activity activity} that shows this dialog should implement {@link ColorPickerDialogListener}</p>
|
||||
*
|
||||
* <p>Example usage:</p>
|
||||
*
|
||||
* <pre>
|
||||
* ColorPickerDialog.newBuilder().show(activity);
|
||||
* </pre>
|
||||
*/
|
||||
public class ColorPickerDialog extends DialogFragment implements OnTouchListener, OnColorChangedListener, TextWatcher {
|
||||
|
||||
private static final String ARG_ID = "id";
|
||||
private static final String ARG_TYPE = "dialogType";
|
||||
private static final String ARG_COLOR = "color";
|
||||
private static final String ARG_ALPHA = "alpha";
|
||||
private static final String ARG_PRESETS = "presets";
|
||||
private static final String ARG_ALLOW_PRESETS = "allowPresets";
|
||||
private static final String ARG_ALLOW_CUSTOM = "allowCustom";
|
||||
private static final String ARG_DIALOG_TITLE = "dialogTitle";
|
||||
private static final String ARG_SHOW_COLOR_SHADES = "showColorShades";
|
||||
private static final String ARG_COLOR_SHAPE = "colorShape";
|
||||
|
||||
public static final int TYPE_CUSTOM = 0;
|
||||
public static final int TYPE_PRESETS = 1;
|
||||
|
||||
static final int ALPHA_THRESHOLD = 165;
|
||||
|
||||
/**
|
||||
* Material design colors used as the default color presets
|
||||
*/
|
||||
public static final int[] MATERIAL_COLORS = {
|
||||
0xFFF44336, // RED 500
|
||||
0xFFE91E63, // PINK 500
|
||||
0xFFFF2C93, // LIGHT PINK 500
|
||||
0xFF9C27B0, // PURPLE 500
|
||||
0xFF673AB7, // DEEP PURPLE 500
|
||||
0xFF3F51B5, // INDIGO 500
|
||||
0xFF2196F3, // BLUE 500
|
||||
0xFF03A9F4, // LIGHT BLUE 500
|
||||
0xFF00BCD4, // CYAN 500
|
||||
0xFF009688, // TEAL 500
|
||||
0xFF4CAF50, // GREEN 500
|
||||
0xFF8BC34A, // LIGHT GREEN 500
|
||||
0xFFCDDC39, // LIME 500
|
||||
0xFFFFEB3B, // YELLOW 500
|
||||
0xFFFFC107, // AMBER 500
|
||||
0xFFFF9800, // ORANGE 500
|
||||
0xFF795548, // BROWN 500
|
||||
0xFF607D8B, // BLUE GREY 500
|
||||
0xFF9E9E9E, // GREY 500
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a new Builder for creating a {@link ColorPickerDialog} instance
|
||||
*
|
||||
* @return The {@link Builder builder} to create the {@link ColorPickerDialog}.
|
||||
*/
|
||||
public static Builder newBuilder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
ColorPickerDialogListener colorPickerDialogListener;
|
||||
FrameLayout rootView;
|
||||
int[] presets;
|
||||
@ColorInt int color;
|
||||
int dialogType;
|
||||
int dialogId;
|
||||
boolean showColorShades;
|
||||
int colorShape;
|
||||
|
||||
// -- PRESETS --------------------------
|
||||
ColorPaletteAdapter adapter;
|
||||
LinearLayout shadesLayout;
|
||||
SeekBar transparencySeekBar;
|
||||
TextView transparencyPercText;
|
||||
|
||||
// -- CUSTOM ---------------------------
|
||||
ColorPickerView colorPicker;
|
||||
ColorPanelView newColorPanel;
|
||||
EditText hexEditText;
|
||||
boolean showAlphaSlider;
|
||||
private boolean fromEditText;
|
||||
|
||||
@Override public void onAttach(Activity activity) {
|
||||
super.onAttach(activity);
|
||||
if (colorPickerDialogListener == null && activity instanceof ColorPickerDialogListener) {
|
||||
colorPickerDialogListener = (ColorPickerDialogListener) activity;
|
||||
}
|
||||
}
|
||||
|
||||
@Override public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
dialogId = getArguments().getInt(ARG_ID);
|
||||
showAlphaSlider = getArguments().getBoolean(ARG_ALPHA);
|
||||
showColorShades = getArguments().getBoolean(ARG_SHOW_COLOR_SHADES);
|
||||
colorShape = getArguments().getInt(ARG_COLOR_SHAPE);
|
||||
if (savedInstanceState == null) {
|
||||
color = getArguments().getInt(ARG_COLOR);
|
||||
dialogType = getArguments().getInt(ARG_TYPE);
|
||||
} else {
|
||||
color = savedInstanceState.getInt(ARG_COLOR);
|
||||
dialogType = savedInstanceState.getInt(ARG_TYPE);
|
||||
}
|
||||
|
||||
rootView = new FrameLayout(getActivity());
|
||||
if (dialogType == TYPE_CUSTOM) {
|
||||
rootView.addView(createPickerView());
|
||||
} else if (dialogType == TYPE_PRESETS) {
|
||||
rootView.addView(createPresetsView());
|
||||
}
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity())
|
||||
.setView(rootView)
|
||||
.setPositiveButton(R.string.cpv_select, new DialogInterface.OnClickListener() {
|
||||
@Override public void onClick(DialogInterface dialog, int which) {
|
||||
colorPickerDialogListener.onColorSelected(dialogId, color);
|
||||
}
|
||||
});
|
||||
|
||||
int dialogTitleStringRes = getArguments().getInt(ARG_DIALOG_TITLE);
|
||||
if (dialogTitleStringRes != 0) {
|
||||
builder.setTitle(dialogTitleStringRes);
|
||||
}
|
||||
|
||||
int neutralButtonStringRes;
|
||||
if (dialogType == TYPE_CUSTOM && getArguments().getBoolean(ARG_ALLOW_PRESETS)) {
|
||||
neutralButtonStringRes = R.string.cpv_presets;
|
||||
} else if (dialogType == TYPE_PRESETS && getArguments().getBoolean(ARG_ALLOW_CUSTOM)) {
|
||||
neutralButtonStringRes = R.string.cpv_custom;
|
||||
} else {
|
||||
neutralButtonStringRes = 0;
|
||||
}
|
||||
|
||||
if (neutralButtonStringRes != 0) {
|
||||
builder.setNeutralButton(neutralButtonStringRes, null);
|
||||
}
|
||||
|
||||
return builder.create();
|
||||
}
|
||||
|
||||
@Override public void onStart() {
|
||||
super.onStart();
|
||||
AlertDialog dialog = (AlertDialog) getDialog();
|
||||
|
||||
// http://stackoverflow.com/a/16972670/1048340
|
||||
//noinspection ConstantConditions
|
||||
dialog.getWindow()
|
||||
.clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
|
||||
dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
|
||||
|
||||
// Do not dismiss the dialog when clicking the neutral button.
|
||||
Button neutralButton = dialog.getButton(AlertDialog.BUTTON_NEUTRAL);
|
||||
if (neutralButton != null) {
|
||||
neutralButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override public void onClick(View v) {
|
||||
rootView.removeAllViews();
|
||||
switch (dialogType) {
|
||||
case TYPE_CUSTOM:
|
||||
dialogType = TYPE_PRESETS;
|
||||
((Button) v).setText(R.string.cpv_custom);
|
||||
rootView.addView(createPresetsView());
|
||||
break;
|
||||
case TYPE_PRESETS:
|
||||
dialogType = TYPE_CUSTOM;
|
||||
((Button) v).setText(R.string.cpv_presets);
|
||||
rootView.addView(createPickerView());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void onDismiss(DialogInterface dialog) {
|
||||
super.onDismiss(dialog);
|
||||
colorPickerDialogListener.onDialogDismissed(dialogId);
|
||||
}
|
||||
|
||||
@Override public void onSaveInstanceState(Bundle outState) {
|
||||
outState.putInt(ARG_COLOR, color);
|
||||
outState.putInt(ARG_TYPE, dialogType);
|
||||
super.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the callback
|
||||
*
|
||||
* @param colorPickerDialogListener
|
||||
* The callback invoked when a color is selected or the dialog is dismissed.
|
||||
*/
|
||||
public void setColorPickerDialogListener(ColorPickerDialogListener colorPickerDialogListener) {
|
||||
this.colorPickerDialogListener = colorPickerDialogListener;
|
||||
}
|
||||
|
||||
// region Custom Picker
|
||||
|
||||
View createPickerView() {
|
||||
View contentView = View.inflate(getActivity(), R.layout.cpv_dialog_color_picker, null);
|
||||
colorPicker = (ColorPickerView) contentView.findViewById(R.id.cpv_color_picker_view);
|
||||
ColorPanelView oldColorPanel = (ColorPanelView) contentView.findViewById(R.id.cpv_color_panel_old);
|
||||
newColorPanel = (ColorPanelView) contentView.findViewById(R.id.cpv_color_panel_new);
|
||||
ImageView arrowRight = (ImageView) contentView.findViewById(R.id.cpv_arrow_right);
|
||||
hexEditText = (EditText) contentView.findViewById(R.id.cpv_hex);
|
||||
|
||||
try {
|
||||
final TypedValue value = new TypedValue();
|
||||
TypedArray typedArray =
|
||||
getActivity().obtainStyledAttributes(value.data, new int[]{android.R.attr.textColorPrimary});
|
||||
int arrowColor = typedArray.getColor(0, Color.BLACK);
|
||||
typedArray.recycle();
|
||||
arrowRight.setColorFilter(arrowColor);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
|
||||
colorPicker.setAlphaSliderVisible(showAlphaSlider);
|
||||
oldColorPanel.setColor(getArguments().getInt(ARG_COLOR));
|
||||
colorPicker.setColor(color, true);
|
||||
newColorPanel.setColor(color);
|
||||
setHex(color);
|
||||
|
||||
if (!showAlphaSlider) {
|
||||
hexEditText.setFilters(new InputFilter[]{new InputFilter.LengthFilter(6)});
|
||||
}
|
||||
|
||||
newColorPanel.setOnClickListener(new View.OnClickListener() {
|
||||
@Override public void onClick(View v) {
|
||||
if (newColorPanel.getColor() == color) {
|
||||
colorPickerDialogListener.onColorSelected(dialogId, color);
|
||||
dismiss();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
contentView.setOnTouchListener(this);
|
||||
colorPicker.setOnColorChangedListener(this);
|
||||
hexEditText.addTextChangedListener(this);
|
||||
|
||||
hexEditText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
|
||||
@Override
|
||||
public void onFocusChange(View v, boolean hasFocus) {
|
||||
if (hasFocus) {
|
||||
InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
imm.showSoftInput(hexEditText, InputMethodManager.SHOW_IMPLICIT);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return contentView;
|
||||
}
|
||||
|
||||
@Override public boolean onTouch(View v, MotionEvent event) {
|
||||
if (v != hexEditText && hexEditText.hasFocus()) {
|
||||
hexEditText.clearFocus();
|
||||
InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
imm.hideSoftInputFromWindow(hexEditText.getWindowToken(), 0);
|
||||
hexEditText.clearFocus();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override public void onColorChanged(int newColor) {
|
||||
color = newColor;
|
||||
newColorPanel.setColor(newColor);
|
||||
if (!fromEditText) {
|
||||
setHex(newColor);
|
||||
if (hexEditText.hasFocus()) {
|
||||
InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
imm.hideSoftInputFromWindow(hexEditText.getWindowToken(), 0);
|
||||
hexEditText.clearFocus();
|
||||
}
|
||||
}
|
||||
fromEditText = false;
|
||||
}
|
||||
|
||||
@Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
|
||||
}
|
||||
|
||||
@Override public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
|
||||
}
|
||||
|
||||
@Override public void afterTextChanged(Editable s) {
|
||||
if (hexEditText.isFocused()) {
|
||||
int color = parseColorString(s.toString());
|
||||
if (color != colorPicker.getColor()) {
|
||||
fromEditText = true;
|
||||
colorPicker.setColor(color, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setHex(int color) {
|
||||
if (showAlphaSlider) {
|
||||
hexEditText.setText(String.format("%08X", (color)));
|
||||
} else {
|
||||
hexEditText.setText(String.format("%06X", (0xFFFFFF & color)));
|
||||
}
|
||||
}
|
||||
|
||||
private int parseColorString(String colorString) throws NumberFormatException {
|
||||
int a, r, g, b = 0;
|
||||
if (colorString.startsWith("#")) {
|
||||
colorString = colorString.substring(1);
|
||||
}
|
||||
if (colorString.length() == 0) {
|
||||
r = 0;
|
||||
a = 255;
|
||||
g = 0;
|
||||
} else if (colorString.length() <= 2) {
|
||||
a = 255;
|
||||
r = 0;
|
||||
b = Integer.parseInt(colorString, 16);
|
||||
g = 0;
|
||||
} else if (colorString.length() == 3) {
|
||||
a = 255;
|
||||
r = Integer.parseInt(colorString.substring(0, 1), 16);
|
||||
g = Integer.parseInt(colorString.substring(1, 2), 16);
|
||||
b = Integer.parseInt(colorString.substring(2, 3), 16);
|
||||
} else if (colorString.length() == 4) {
|
||||
a = 255;
|
||||
r = Integer.parseInt(colorString.substring(0, 2), 16);
|
||||
g = r;
|
||||
r = 0;
|
||||
b = Integer.parseInt(colorString.substring(2, 4), 16);
|
||||
} else if (colorString.length() == 5) {
|
||||
a = 255;
|
||||
r = Integer.parseInt(colorString.substring(0, 1), 16);
|
||||
g = Integer.parseInt(colorString.substring(1, 3), 16);
|
||||
b = Integer.parseInt(colorString.substring(3, 5), 16);
|
||||
} else if (colorString.length() == 6) {
|
||||
a = 255;
|
||||
r = Integer.parseInt(colorString.substring(0, 2), 16);
|
||||
g = Integer.parseInt(colorString.substring(2, 4), 16);
|
||||
b = Integer.parseInt(colorString.substring(4, 6), 16);
|
||||
} else if (colorString.length() == 7) {
|
||||
a = Integer.parseInt(colorString.substring(0, 1), 16);
|
||||
r = Integer.parseInt(colorString.substring(1, 3), 16);
|
||||
g = Integer.parseInt(colorString.substring(3, 5), 16);
|
||||
b = Integer.parseInt(colorString.substring(5, 7), 16);
|
||||
} else if (colorString.length() == 8) {
|
||||
a = Integer.parseInt(colorString.substring(0, 2), 16);
|
||||
r = Integer.parseInt(colorString.substring(2, 4), 16);
|
||||
g = Integer.parseInt(colorString.substring(4, 6), 16);
|
||||
b = Integer.parseInt(colorString.substring(6, 8), 16);
|
||||
} else {
|
||||
b = -1;
|
||||
g = -1;
|
||||
r = -1;
|
||||
a = -1;
|
||||
}
|
||||
return Color.argb(a, r, g, b);
|
||||
}
|
||||
|
||||
// -- endregion --
|
||||
|
||||
// region Presets Picker
|
||||
|
||||
View createPresetsView() {
|
||||
View contentView = View.inflate(getActivity(), R.layout.cpv_dialog_presets, null);
|
||||
shadesLayout = (LinearLayout) contentView.findViewById(R.id.shades_layout);
|
||||
transparencySeekBar = (SeekBar) contentView.findViewById(R.id.transparency_seekbar);
|
||||
transparencyPercText = (TextView) contentView.findViewById(R.id.transparency_text);
|
||||
GridView gridView = (GridView) contentView.findViewById(R.id.gridView);
|
||||
|
||||
loadPresets();
|
||||
|
||||
if (showColorShades) {
|
||||
createColorShades(color);
|
||||
} else {
|
||||
shadesLayout.setVisibility(View.GONE);
|
||||
contentView.findViewById(R.id.shades_divider).setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
adapter = new ColorPaletteAdapter(new ColorPaletteAdapter.OnColorSelectedListener() {
|
||||
@Override public void onColorSelected(int newColor) {
|
||||
if (color == newColor) {
|
||||
colorPickerDialogListener.onColorSelected(dialogId, color);
|
||||
dismiss();
|
||||
return;
|
||||
}
|
||||
color = newColor;
|
||||
if (showColorShades) {
|
||||
createColorShades(color);
|
||||
}
|
||||
}
|
||||
}, presets, getSelectedItemPosition(), colorShape);
|
||||
|
||||
gridView.setAdapter(adapter);
|
||||
|
||||
if (showAlphaSlider) {
|
||||
setupTransparency();
|
||||
} else {
|
||||
contentView.findViewById(R.id.transparency_layout).setVisibility(View.GONE);
|
||||
contentView.findViewById(R.id.transparency_title).setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
return contentView;
|
||||
}
|
||||
|
||||
private void loadPresets() {
|
||||
int alpha = Color.alpha(color);
|
||||
presets = getArguments().getIntArray(ARG_PRESETS);
|
||||
if (presets == null) presets = MATERIAL_COLORS;
|
||||
boolean isMaterialColors = presets == MATERIAL_COLORS;
|
||||
presets = Arrays.copyOf(presets, presets.length); // don't update the original array when modifying alpha
|
||||
if (alpha != 255) {
|
||||
// add alpha to the presets
|
||||
for (int i = 0; i < presets.length; i++) {
|
||||
int color = presets[i];
|
||||
int red = Color.red(color);
|
||||
int green = Color.green(color);
|
||||
int blue = Color.blue(color);
|
||||
presets[i] = Color.argb(alpha, red, green, blue);
|
||||
}
|
||||
}
|
||||
presets = unshiftIfNotExists(presets, color);
|
||||
if (isMaterialColors && presets.length == 19) {
|
||||
// Add black to have a total of 20 colors if the current color is in the material color palette
|
||||
presets = pushIfNotExists(presets, Color.argb(alpha, 0, 0, 0));
|
||||
}
|
||||
}
|
||||
|
||||
void createColorShades(@ColorInt final int color) {
|
||||
final int[] colorShades = getColorShades(color);
|
||||
|
||||
if (shadesLayout.getChildCount() != 0) {
|
||||
for (int i = 0; i < shadesLayout.getChildCount(); i++) {
|
||||
FrameLayout layout = (FrameLayout) shadesLayout.getChildAt(i);
|
||||
final ColorPanelView cpv = (ColorPanelView) layout.findViewById(R.id.cpv_color_panel_view);
|
||||
ImageView iv = (ImageView) layout.findViewById(R.id.cpv_color_image_view);
|
||||
cpv.setColor(colorShades[i]);
|
||||
cpv.setTag(false);
|
||||
iv.setImageDrawable(null);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
final int horizontalPadding = getResources().getDimensionPixelSize(R.dimen.cpv_item_horizontal_padding);
|
||||
|
||||
for (final int colorShade : colorShades) {
|
||||
int layoutResId;
|
||||
if (colorShape == ColorShape.SQUARE) {
|
||||
layoutResId = R.layout.cpv_color_item_square;
|
||||
} else {
|
||||
layoutResId = R.layout.cpv_color_item_circle;
|
||||
}
|
||||
|
||||
final View view = View.inflate(getActivity(), layoutResId, null);
|
||||
final ColorPanelView colorPanelView = (ColorPanelView) view.findViewById(R.id.cpv_color_panel_view);
|
||||
|
||||
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) colorPanelView.getLayoutParams();
|
||||
params.leftMargin = params.rightMargin = horizontalPadding;
|
||||
colorPanelView.setLayoutParams(params);
|
||||
colorPanelView.setColor(colorShade);
|
||||
shadesLayout.addView(view);
|
||||
|
||||
colorPanelView.post(new Runnable() {
|
||||
@Override public void run() {
|
||||
// The color is black when rotating the dialog. This is a dirty fix. WTF!?
|
||||
colorPanelView.setColor(colorShade);
|
||||
}
|
||||
});
|
||||
|
||||
colorPanelView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override public void onClick(View v) {
|
||||
if (v.getTag() instanceof Boolean && (Boolean) v.getTag()) {
|
||||
colorPickerDialogListener.onColorSelected(dialogId, ColorPickerDialog.this.color);
|
||||
dismiss();
|
||||
return; // already selected
|
||||
}
|
||||
ColorPickerDialog.this.color = colorPanelView.getColor();
|
||||
adapter.selectNone();
|
||||
for (int i = 0; i < shadesLayout.getChildCount(); i++) {
|
||||
FrameLayout layout = (FrameLayout) shadesLayout.getChildAt(i);
|
||||
ColorPanelView cpv = (ColorPanelView) layout.findViewById(R.id.cpv_color_panel_view);
|
||||
ImageView iv = (ImageView) layout.findViewById(R.id.cpv_color_image_view);
|
||||
iv.setImageResource(cpv == v ? R.drawable.cpv_preset_checked : 0);
|
||||
if (cpv == v && ColorUtils.calculateLuminance(cpv.getColor()) >= 0.65 ||
|
||||
Color.alpha(cpv.getColor()) <= ALPHA_THRESHOLD) {
|
||||
iv.setColorFilter(Color.BLACK, PorterDuff.Mode.SRC_IN);
|
||||
} else {
|
||||
iv.setColorFilter(null);
|
||||
}
|
||||
cpv.setTag(cpv == v);
|
||||
}
|
||||
}
|
||||
});
|
||||
colorPanelView.setOnLongClickListener(new View.OnLongClickListener() {
|
||||
@Override public boolean onLongClick(View v) {
|
||||
colorPanelView.showHint();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private int shadeColor(@ColorInt int color, double percent) {
|
||||
String hex = String.format("#%06X", (0xFFFFFF & color));
|
||||
long f = Long.parseLong(hex.substring(1), 16);
|
||||
double t = percent < 0 ? 0 : 255;
|
||||
double p = percent < 0 ? percent * -1 : percent;
|
||||
long R = f >> 16;
|
||||
long G = f >> 8 & 0x00FF;
|
||||
long B = f & 0x0000FF;
|
||||
int alpha = Color.alpha(color);
|
||||
int red = (int) (Math.round((t - R) * p) + R);
|
||||
int green = (int) (Math.round((t - G) * p) + G);
|
||||
int blue = (int) (Math.round((t - B) * p) + B);
|
||||
return Color.argb(alpha, red, green, blue);
|
||||
}
|
||||
|
||||
private int[] getColorShades(@ColorInt int color) {
|
||||
return new int[]{
|
||||
shadeColor(color, 0.9),
|
||||
shadeColor(color, 0.7),
|
||||
shadeColor(color, 0.5),
|
||||
shadeColor(color, 0.333),
|
||||
shadeColor(color, 0.166),
|
||||
shadeColor(color, -0.125),
|
||||
shadeColor(color, -0.25),
|
||||
shadeColor(color, -0.375),
|
||||
shadeColor(color, -0.5),
|
||||
shadeColor(color, -0.675),
|
||||
shadeColor(color, -0.7),
|
||||
shadeColor(color, -0.775),
|
||||
};
|
||||
}
|
||||
|
||||
private void setupTransparency() {
|
||||
int progress = 255 - Color.alpha(color);
|
||||
transparencySeekBar.setMax(255);
|
||||
transparencySeekBar.setProgress(progress);
|
||||
int percentage = (int) ((double) progress * 100 / 255);
|
||||
transparencyPercText.setText(String.format(Locale.ENGLISH, "%d%%", percentage));
|
||||
transparencySeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
|
||||
@Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
int percentage = (int) ((double) progress * 100 / 255);
|
||||
transparencyPercText.setText(String.format(Locale.ENGLISH, "%d%%", percentage));
|
||||
int alpha = 255 - progress;
|
||||
// update items in GridView:
|
||||
for (int i = 0; i < adapter.colors.length; i++) {
|
||||
int color = adapter.colors[i];
|
||||
int red = Color.red(color);
|
||||
int green = Color.green(color);
|
||||
int blue = Color.blue(color);
|
||||
adapter.colors[i] = Color.argb(alpha, red, green, blue);
|
||||
}
|
||||
adapter.notifyDataSetChanged();
|
||||
// update shades:
|
||||
for (int i = 0; i < shadesLayout.getChildCount(); i++) {
|
||||
FrameLayout layout = (FrameLayout) shadesLayout.getChildAt(i);
|
||||
ColorPanelView cpv = (ColorPanelView) layout.findViewById(R.id.cpv_color_panel_view);
|
||||
ImageView iv = (ImageView) layout.findViewById(R.id.cpv_color_image_view);
|
||||
if (layout.getTag() == null) {
|
||||
// save the original border color
|
||||
layout.setTag(cpv.getBorderColor());
|
||||
}
|
||||
int color = cpv.getColor();
|
||||
color = Color.argb(alpha, Color.red(color), Color.green(color), Color.blue(color));
|
||||
if (alpha <= ALPHA_THRESHOLD) {
|
||||
cpv.setBorderColor(color | 0xFF000000);
|
||||
} else {
|
||||
cpv.setBorderColor((int) layout.getTag());
|
||||
}
|
||||
if (cpv.getTag() != null && (Boolean) cpv.getTag()) {
|
||||
// The alpha changed on the selected shaded color. Update the checkmark color filter.
|
||||
if (alpha <= ALPHA_THRESHOLD) {
|
||||
iv.setColorFilter(Color.BLACK, PorterDuff.Mode.SRC_IN);
|
||||
} else {
|
||||
if (ColorUtils.calculateLuminance(color) >= 0.65) {
|
||||
iv.setColorFilter(Color.BLACK, PorterDuff.Mode.SRC_IN);
|
||||
} else {
|
||||
iv.setColorFilter(Color.WHITE, PorterDuff.Mode.SRC_IN);
|
||||
}
|
||||
}
|
||||
}
|
||||
cpv.setColor(color);
|
||||
}
|
||||
// update color:
|
||||
int red = Color.red(color);
|
||||
int green = Color.green(color);
|
||||
int blue = Color.blue(color);
|
||||
color = Color.argb(alpha, red, green, blue);
|
||||
}
|
||||
|
||||
@Override public void onStartTrackingTouch(SeekBar seekBar) {
|
||||
|
||||
}
|
||||
|
||||
@Override public void onStopTrackingTouch(SeekBar seekBar) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private int[] unshiftIfNotExists(int[] array, int value) {
|
||||
boolean present = false;
|
||||
for (int i : array) {
|
||||
if (i == value) {
|
||||
present = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!present) {
|
||||
int[] newArray = new int[array.length + 1];
|
||||
newArray[0] = value;
|
||||
System.arraycopy(array, 0, newArray, 1, newArray.length - 1);
|
||||
return newArray;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
private int[] pushIfNotExists(int[] array, int value) {
|
||||
boolean present = false;
|
||||
for (int i : array) {
|
||||
if (i == value) {
|
||||
present = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!present) {
|
||||
int[] newArray = new int[array.length + 1];
|
||||
newArray[newArray.length - 1] = value;
|
||||
System.arraycopy(array, 0, newArray, 0, newArray.length - 1);
|
||||
return newArray;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
private int getSelectedItemPosition() {
|
||||
for (int i = 0; i < presets.length; i++) {
|
||||
if (presets[i] == color) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region Builder
|
||||
|
||||
public static final class Builder {
|
||||
|
||||
@StringRes int dialogTitle = R.string.cpv_default_title;
|
||||
@DialogType int dialogType = TYPE_PRESETS;
|
||||
int[] presets = MATERIAL_COLORS;
|
||||
@ColorInt int color = Color.BLACK;
|
||||
int dialogId = 0;
|
||||
boolean showAlphaSlider = false;
|
||||
boolean allowPresets = true;
|
||||
boolean allowCustom = true;
|
||||
boolean showColorShades = true;
|
||||
@ColorShape int colorShape = ColorShape.CIRCLE;
|
||||
|
||||
/*package*/ Builder() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the dialog title string resource id
|
||||
*
|
||||
* @param dialogTitle
|
||||
* The string resource used for the dialog title
|
||||
* @return This builder object for chaining method calls
|
||||
*/
|
||||
public Builder setDialogTitle(@StringRes int dialogTitle) {
|
||||
this.dialogTitle = dialogTitle;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set which dialog view to show.
|
||||
*
|
||||
* @param dialogType
|
||||
* Either {@link ColorPickerDialog#TYPE_CUSTOM} or {@link ColorPickerDialog#TYPE_PRESETS}.
|
||||
* @return This builder object for chaining method calls
|
||||
*/
|
||||
public Builder setDialogType(@DialogType int dialogType) {
|
||||
this.dialogType = dialogType;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the colors used for the presets
|
||||
*
|
||||
* @param presets
|
||||
* An array of color ints.
|
||||
* @return This builder object for chaining method calls
|
||||
*/
|
||||
public Builder setPresets(@NonNull int[] presets) {
|
||||
this.presets = presets;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the original color
|
||||
*
|
||||
* @param color
|
||||
* The default color for the color picker
|
||||
* @return This builder object for chaining method calls
|
||||
*/
|
||||
public Builder setColor(int color) {
|
||||
this.color = color;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the dialog id used for callbacks
|
||||
*
|
||||
* @param dialogId
|
||||
* The id that is sent back to the {@link ColorPickerDialogListener}.
|
||||
* @return This builder object for chaining method calls
|
||||
*/
|
||||
public Builder setDialogId(int dialogId) {
|
||||
this.dialogId = dialogId;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the alpha slider
|
||||
*
|
||||
* @param showAlphaSlider
|
||||
* {@code true} to show the alpha slider. Currently only supported with the {@link ColorPickerView}.
|
||||
* @return This builder object for chaining method calls
|
||||
*/
|
||||
public Builder setShowAlphaSlider(boolean showAlphaSlider) {
|
||||
this.showAlphaSlider = showAlphaSlider;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show/Hide a neutral button to select preset colors.
|
||||
*
|
||||
* @param allowPresets
|
||||
* {@code false} to disable showing the presets button.
|
||||
* @return This builder object for chaining method calls
|
||||
*/
|
||||
public Builder setAllowPresets(boolean allowPresets) {
|
||||
this.allowPresets = allowPresets;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show/Hide the neutral button to select a custom color.
|
||||
*
|
||||
* @param allowCustom
|
||||
* {@code false} to disable showing the custom button.
|
||||
* @return This builder object for chaining method calls
|
||||
*/
|
||||
public Builder setAllowCustom(boolean allowCustom) {
|
||||
this.allowCustom = allowCustom;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show/Hide the color shades in the presets picker
|
||||
*
|
||||
* @param showColorShades
|
||||
* {@code false} to hide the color shades.
|
||||
* @return This builder object for chaining method calls
|
||||
*/
|
||||
public Builder setShowColorShades(boolean showColorShades) {
|
||||
this.showColorShades = showColorShades;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the shape of the color panel view.
|
||||
*
|
||||
* @param colorShape
|
||||
* Either {@link ColorShape#CIRCLE} or {@link ColorShape#SQUARE}.
|
||||
* @return This builder object for chaining method calls
|
||||
*/
|
||||
public Builder setColorShape(int colorShape) {
|
||||
this.colorShape = colorShape;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the {@link ColorPickerDialog} instance.
|
||||
*
|
||||
* @return A new {@link ColorPickerDialog}.
|
||||
* @see #show(Activity)
|
||||
*/
|
||||
public ColorPickerDialog create() {
|
||||
ColorPickerDialog dialog = new ColorPickerDialog();
|
||||
Bundle args = new Bundle();
|
||||
args.putInt(ARG_ID, dialogId);
|
||||
args.putInt(ARG_TYPE, dialogType);
|
||||
args.putInt(ARG_COLOR, color);
|
||||
args.putIntArray(ARG_PRESETS, presets);
|
||||
args.putBoolean(ARG_ALPHA, showAlphaSlider);
|
||||
args.putBoolean(ARG_ALLOW_CUSTOM, allowCustom);
|
||||
args.putBoolean(ARG_ALLOW_PRESETS, allowPresets);
|
||||
args.putInt(ARG_DIALOG_TITLE, dialogTitle);
|
||||
args.putBoolean(ARG_SHOW_COLOR_SHADES, showColorShades);
|
||||
args.putInt(ARG_COLOR_SHAPE, colorShape);
|
||||
dialog.setArguments(args);
|
||||
return dialog;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and show the {@link ColorPickerDialog} created with this builder.
|
||||
*
|
||||
* @param activity
|
||||
* The current activity.
|
||||
*/
|
||||
public void show(Activity activity) {
|
||||
create().show(activity.getFragmentManager(), "color-picker-dialog");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@IntDef({TYPE_CUSTOM, TYPE_PRESETS})
|
||||
public @interface DialogType {
|
||||
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (C) 2017 JRummy Apps Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.jrummyapps.android.colorpicker;
|
||||
|
||||
import android.support.annotation.ColorInt;
|
||||
|
||||
/**
|
||||
* Callback used for getting the selected color from a color picker dialog.
|
||||
*/
|
||||
public interface ColorPickerDialogListener {
|
||||
|
||||
/**
|
||||
* Callback that is invoked when a color is selected from the color picker dialog.
|
||||
*
|
||||
* @param dialogId
|
||||
* The dialog id used to create the dialog instance.
|
||||
* @param color
|
||||
* The selected color
|
||||
*/
|
||||
void onColorSelected(int dialogId, @ColorInt int color);
|
||||
|
||||
/**
|
||||
* Callback that is invoked when the color picker dialog was dismissed.
|
||||
*
|
||||
* @param dialogId
|
||||
* The dialog id used to create the dialog instance.
|
||||
*/
|
||||
void onDialogDismissed(int dialogId);
|
||||
|
||||
}
|
|
@ -0,0 +1,214 @@
|
|||
/*
|
||||
* Copyright (C) 2017 JRummy Apps Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.jrummyapps.android.colorpicker;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Color;
|
||||
import android.preference.Preference;
|
||||
import android.support.annotation.ColorInt;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import com.jrummyapps.android.colorpicker.ColorPickerDialog.DialogType;
|
||||
|
||||
/**
|
||||
* A Preference to select a color
|
||||
*/
|
||||
public class ColorPreference extends Preference implements ColorPickerDialogListener {
|
||||
|
||||
private static final int SIZE_NORMAL = 0;
|
||||
private static final int SIZE_LARGE = 1;
|
||||
|
||||
private OnShowDialogListener onShowDialogListener;
|
||||
private int color = Color.BLACK;
|
||||
private boolean showDialog;
|
||||
@DialogType
|
||||
private int dialogType;
|
||||
private int colorShape;
|
||||
private boolean allowPresets;
|
||||
private boolean allowCustom;
|
||||
private boolean showAlphaSlider;
|
||||
private boolean showColorShades;
|
||||
private int previewSize;
|
||||
private int[] presets;
|
||||
private int dialogTitle;
|
||||
|
||||
public ColorPreference(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init(attrs);
|
||||
}
|
||||
|
||||
public ColorPreference(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
init(attrs);
|
||||
}
|
||||
|
||||
private void init(AttributeSet attrs) {
|
||||
setPersistent(true);
|
||||
TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.ColorPreference);
|
||||
showDialog = a.getBoolean(R.styleable.ColorPreference_cpv_showDialog, true);
|
||||
//noinspection WrongConstant
|
||||
dialogType = a.getInt(R.styleable.ColorPreference_cpv_dialogType, ColorPickerDialog.TYPE_PRESETS);
|
||||
colorShape = a.getInt(R.styleable.ColorPreference_cpv_colorShape, ColorShape.CIRCLE);
|
||||
allowPresets = a.getBoolean(R.styleable.ColorPreference_cpv_allowPresets, true);
|
||||
allowCustom = a.getBoolean(R.styleable.ColorPreference_cpv_allowCustom, true);
|
||||
showAlphaSlider = a.getBoolean(R.styleable.ColorPreference_cpv_showAlphaSlider, false);
|
||||
showColorShades = a.getBoolean(R.styleable.ColorPreference_cpv_showColorShades, true);
|
||||
previewSize = a.getInt(R.styleable.ColorPreference_cpv_previewSize, SIZE_NORMAL);
|
||||
final int presetsResId = a.getResourceId(R.styleable.ColorPreference_cpv_colorPresets, 0);
|
||||
dialogTitle = a.getResourceId(R.styleable.ColorPreference_cpv_dialogTitle, R.string.cpv_default_title);
|
||||
if (presetsResId != 0) {
|
||||
presets = getContext().getResources().getIntArray(presetsResId);
|
||||
} else {
|
||||
presets = ColorPickerDialog.MATERIAL_COLORS;
|
||||
}
|
||||
if (colorShape == ColorShape.CIRCLE) {
|
||||
setWidgetLayoutResource(
|
||||
previewSize == SIZE_LARGE ? R.layout.cpv_preference_circle_large : R.layout.cpv_preference_circle);
|
||||
} else {
|
||||
setWidgetLayoutResource(
|
||||
previewSize == SIZE_LARGE ? R.layout.cpv_preference_square_large : R.layout.cpv_preference_square
|
||||
);
|
||||
}
|
||||
a.recycle();
|
||||
}
|
||||
|
||||
@Override protected void onClick() {
|
||||
super.onClick();
|
||||
if (onShowDialogListener != null) {
|
||||
onShowDialogListener.onShowColorPickerDialog((String) getTitle(), color);
|
||||
} else if (showDialog) {
|
||||
ColorPickerDialog dialog = ColorPickerDialog.newBuilder()
|
||||
.setDialogType(dialogType)
|
||||
.setDialogTitle(dialogTitle)
|
||||
.setColorShape(colorShape)
|
||||
.setPresets(presets)
|
||||
.setAllowPresets(allowPresets)
|
||||
.setAllowCustom(allowCustom)
|
||||
.setShowAlphaSlider(showAlphaSlider)
|
||||
.setShowColorShades(showColorShades)
|
||||
.setColor(color)
|
||||
.create();
|
||||
dialog.setColorPickerDialogListener(ColorPreference.this);
|
||||
Activity activity = (Activity) getContext();
|
||||
dialog.show(activity.getFragmentManager(), getFragmentTag());
|
||||
}
|
||||
}
|
||||
|
||||
@Override protected void onAttachedToActivity() {
|
||||
super.onAttachedToActivity();
|
||||
|
||||
if (showDialog) {
|
||||
Activity activity = (Activity) getContext();
|
||||
ColorPickerDialog fragment =
|
||||
(ColorPickerDialog) activity.getFragmentManager().findFragmentByTag(getFragmentTag());
|
||||
if (fragment != null) {
|
||||
// re-bind preference to fragment
|
||||
fragment.setColorPickerDialogListener(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override protected void onBindView(View view) {
|
||||
super.onBindView(view);
|
||||
ColorPanelView preview = (ColorPanelView) view.findViewById(R.id.cpv_preference_preview_color_panel);
|
||||
if (preview != null) {
|
||||
preview.setColor(color);
|
||||
}
|
||||
}
|
||||
|
||||
@Override protected void onSetInitialValue(boolean restorePersistedValue, Object defaultValue) {
|
||||
if (restorePersistedValue) {
|
||||
color = getPersistedInt(0xFF000000);
|
||||
} else {
|
||||
color = (Integer) defaultValue;
|
||||
persistInt(color);
|
||||
}
|
||||
}
|
||||
|
||||
@Override protected Object onGetDefaultValue(TypedArray a, int index) {
|
||||
return a.getInteger(index, Color.BLACK);
|
||||
}
|
||||
|
||||
@Override public void onColorSelected(int dialogId, @ColorInt int color) {
|
||||
saveValue(color);
|
||||
}
|
||||
|
||||
@Override public void onDialogDismissed(int dialogId) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the new color
|
||||
*
|
||||
* @param color
|
||||
* The newly selected color
|
||||
*/
|
||||
public void saveValue(@ColorInt int color) {
|
||||
this.color = color;
|
||||
persistInt(this.color);
|
||||
notifyChanged();
|
||||
callChangeListener(color);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the colors shown in the {@link ColorPickerDialog}.
|
||||
*
|
||||
* @param presets An array of color ints
|
||||
*/
|
||||
public void setPresets(@NonNull int[] presets) {
|
||||
this.presets = presets;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the colors that will be shown in the {@link ColorPickerDialog}.
|
||||
*
|
||||
* @return An array of color ints
|
||||
*/
|
||||
public int[] getPresets() {
|
||||
return presets;
|
||||
}
|
||||
|
||||
/**
|
||||
* The listener used for showing the {@link ColorPickerDialog}.
|
||||
* Call {@link #saveValue(int)} after the user chooses a color.
|
||||
* If this is set then it is up to you to show the dialog.
|
||||
*
|
||||
* @param listener
|
||||
* The listener to show the dialog
|
||||
*/
|
||||
public void setOnShowDialogListener(OnShowDialogListener listener) {
|
||||
onShowDialogListener = listener;
|
||||
}
|
||||
|
||||
/**
|
||||
* The tag used for the {@link ColorPickerDialog}.
|
||||
*
|
||||
* @return The tag
|
||||
*/
|
||||
public String getFragmentTag() {
|
||||
return "color_" + getKey();
|
||||
}
|
||||
|
||||
public interface OnShowDialogListener {
|
||||
|
||||
void onShowColorPickerDialog(String title, int currentColor);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright (C) 2017 JRummy Apps Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.jrummyapps.android.colorpicker;
|
||||
|
||||
import android.support.annotation.IntDef;
|
||||
|
||||
/**
|
||||
* The shape of the color preview
|
||||
*/
|
||||
@IntDef({ColorShape.SQUARE, ColorShape.CIRCLE})
|
||||
public @interface ColorShape {
|
||||
|
||||
int SQUARE = 0;
|
||||
|
||||
int CIRCLE = 1;
|
||||
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright (C) 2017 JRummy Apps Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.jrummyapps.android.colorpicker;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.TypedValue;
|
||||
|
||||
final class DrawingUtils {
|
||||
|
||||
static int dpToPx(Context c, float dipValue) {
|
||||
DisplayMetrics metrics = c.getResources().getDisplayMetrics();
|
||||
float val = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dipValue, metrics);
|
||||
int res = (int) (val + 0.5); // Round
|
||||
// Ensure at least 1 pixel if val was > 0
|
||||
return res == 0 && val > 0 ? 1 : res;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (C) 2017 JRummy Apps Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.jrummyapps.android.colorpicker;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.RestrictTo;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.GridView;
|
||||
|
||||
@RestrictTo(RestrictTo.Scope.LIBRARY)
|
||||
public class NestedGridView extends GridView {
|
||||
|
||||
public NestedGridView(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public NestedGridView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public NestedGridView(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
}
|
||||
|
||||
@Override public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
|
||||
super.onMeasure(widthMeasureSpec, expandSpec);
|
||||
}
|
||||
|
||||
}
|
After Width: | Height: | Size: 81 B |
After Width: | Height: | Size: 93 B |
After Width: | Height: | Size: 101 B |
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:drawable="@drawable/cpv_btn_background_pressed" android:state_focused="true" android:state_pressed="false"/>
|
||||
<item android:drawable="@drawable/cpv_btn_background_pressed" android:state_focused="true" android:state_pressed="true"/>
|
||||
<item android:drawable="@drawable/cpv_btn_background_pressed" android:state_focused="false" android:state_pressed="true"/>
|
||||
</selector>
|
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item
|
||||
android:alpha="0.1"
|
||||
android:bottom="6dp"
|
||||
android:top="6dp">
|
||||
<shape>
|
||||
<solid android:color="#20666666"/>
|
||||
<corners android:radius="3dp"/>
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
</layer-list>
|
|
@ -0,0 +1,10 @@
|
|||
<vector
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportHeight="24.0"
|
||||
android:viewportWidth="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M22,12l-4,-4v3H3v2h15v3z"/>
|
||||
</vector>
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="32dp"
|
||||
android:height="32dp"
|
||||
android:viewportHeight="24.0"
|
||||
android:viewportWidth="24.0">
|
||||
<path
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:pathData="M9,16.17L4.83,12l-1.42,1.41L9,19 21,7l-1.41,-1.41z"/>
|
||||
</vector>
|
|
@ -0,0 +1,93 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.jrummyapps.android.colorpicker.ColorPickerView
|
||||
android:id="@id/cpv_color_picker_view"
|
||||
style="@style/cpv_ColorPickerViewStyle"
|
||||
android:padding="16dp"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:paddingBottom="16dp"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp"
|
||||
tools:ignore="RtlHardcoded"
|
||||
>
|
||||
|
||||
<com.jrummyapps.android.colorpicker.ColorPanelView
|
||||
android:id="@id/cpv_color_panel_old"
|
||||
android:layout_width="@dimen/cpv_dialog_preview_width"
|
||||
android:layout_height="@dimen/cpv_dialog_preview_height"
|
||||
app:cpv_colorShape="square"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/cpv_arrow_right"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:paddingLeft="4dp"
|
||||
android:paddingRight="4dp"
|
||||
android:src="@drawable/cpv_ic_arrow_right_black_24dp"
|
||||
tools:ignore="ContentDescription"/>
|
||||
|
||||
<com.jrummyapps.android.colorpicker.ColorPanelView
|
||||
android:id="@id/cpv_color_panel_new"
|
||||
android:layout_width="@dimen/cpv_dialog_preview_width"
|
||||
android:layout_height="@dimen/cpv_dialog_preview_height"
|
||||
app:cpv_colorShape="square"/>
|
||||
|
||||
<Space
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:descendantFocusability="beforeDescendants"
|
||||
android:focusableInTouchMode="true"
|
||||
android:gravity="right"
|
||||
android:orientation="horizontal"
|
||||
tools:ignore="RtlHardcoded">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="#"
|
||||
android:typeface="monospace"
|
||||
tools:ignore="HardcodedText"/>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/cpv_hex"
|
||||
android:layout_width="110dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:digits="0123456789ABCDEFabcdef"
|
||||
android:focusable="true"
|
||||
android:imeOptions="actionGo"
|
||||
android:inputType="textNoSuggestions"
|
||||
android:maxLength="8"
|
||||
android:maxLines="1"
|
||||
android:typeface="monospace"
|
||||
tools:text="88888888"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
|
@ -0,0 +1,24 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:clickable="false">
|
||||
|
||||
<com.jrummyapps.android.colorpicker.ColorPanelView
|
||||
android:id="@+id/cpv_color_panel_view"
|
||||
android:layout_width="@dimen/cpv_item_size"
|
||||
android:layout_height="@dimen/cpv_item_size"
|
||||
android:layout_gravity="center"
|
||||
android:clickable="true"
|
||||
app:cpv_colorShape="circle"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/cpv_color_image_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:clickable="false"/>
|
||||
|
||||
</FrameLayout>
|
|
@ -0,0 +1,24 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:clickable="false">
|
||||
|
||||
<com.jrummyapps.android.colorpicker.ColorPanelView
|
||||
android:id="@+id/cpv_color_panel_view"
|
||||
android:layout_width="@dimen/cpv_item_size"
|
||||
android:layout_height="@dimen/cpv_item_size"
|
||||
android:layout_gravity="center"
|
||||
android:clickable="true"
|
||||
app:cpv_colorShape="square"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/cpv_color_image_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:clickable="false"/>
|
||||
|
||||
</FrameLayout>
|
|
@ -0,0 +1,90 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.jrummyapps.android.colorpicker.ColorPickerView
|
||||
android:id="@id/cpv_color_picker_view"
|
||||
style="@style/cpv_ColorPickerViewStyle"
|
||||
android:padding="16dp"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="16dp"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp"
|
||||
tools:ignore="RtlHardcoded"
|
||||
>
|
||||
|
||||
<com.jrummyapps.android.colorpicker.ColorPanelView
|
||||
android:id="@id/cpv_color_panel_old"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="match_parent"
|
||||
app:cpv_colorShape="square"
|
||||
/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/cpv_arrow_right"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:paddingLeft="3dp"
|
||||
android:paddingRight="3dp"
|
||||
android:src="@drawable/cpv_ic_arrow_right_black_24dp"
|
||||
tools:ignore="ContentDescription"/>
|
||||
|
||||
<com.jrummyapps.android.colorpicker.ColorPanelView
|
||||
android:id="@id/cpv_color_panel_new"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="match_parent"
|
||||
app:cpv_colorShape="square"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:descendantFocusability="beforeDescendants"
|
||||
android:focusableInTouchMode="true"
|
||||
android:gravity="right"
|
||||
android:orientation="horizontal"
|
||||
tools:ignore="RtlHardcoded">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="#"
|
||||
android:typeface="monospace"
|
||||
tools:ignore="HardcodedText"/>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/cpv_hex"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:digits="0123456789ABCDEFabcdef"
|
||||
android:focusable="true"
|
||||
android:imeOptions="actionGo"
|
||||
android:inputType="textNoSuggestions"
|
||||
android:maxLength="8"
|
||||
android:maxLines="1"
|
||||
android:minWidth="110dp"
|
||||
android:typeface="monospace"
|
||||
tools:text="88888888"/>
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
|
@ -0,0 +1,90 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp">
|
||||
|
||||
<com.jrummyapps.android.colorpicker.NestedGridView
|
||||
android:id="@+id/gridView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:cacheColorHint="@android:color/transparent"
|
||||
android:clickable="false"
|
||||
android:columnWidth="@dimen/cpv_column_width"
|
||||
android:horizontalSpacing="4dp"
|
||||
android:listSelector="@android:color/transparent"
|
||||
android:numColumns="auto_fit"
|
||||
android:stretchMode="spacingWidthUniform"
|
||||
android:verticalSpacing="8dp"/>
|
||||
|
||||
<View
|
||||
android:id="@+id/shades_divider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginBottom="12dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:background="?android:attr/dividerVertical"/>
|
||||
|
||||
<HorizontalScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:overScrollMode="never"
|
||||
android:scrollbars="none">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/shades_layout"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="4dp"
|
||||
android:layout_marginRight="4dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<!-- views added dynamically -->
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</HorizontalScrollView>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/transparency_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="12dp"
|
||||
android:text="@string/cpv_transparency"/>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/transparency_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:weightSum="100">
|
||||
|
||||
<SeekBar
|
||||
android:id="@+id/transparency_seekbar"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginRight="4dp"
|
||||
android:layout_weight="85"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/transparency_text"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_weight="15"
|
||||
android:textStyle="bold"
|
||||
android:typeface="monospace"
|
||||
tools:text="100%"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
|
@ -0,0 +1,7 @@
|
|||
<com.jrummyapps.android.colorpicker.ColorPanelView
|
||||
android:id="@id/cpv_preference_preview_color_panel"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="@dimen/cpv_color_preference_normal"
|
||||
android:layout_height="@dimen/cpv_color_preference_normal"
|
||||
app:cpv_colorShape="circle"/>
|
|
@ -0,0 +1,7 @@
|
|||
<com.jrummyapps.android.colorpicker.ColorPanelView
|
||||
android:id="@id/cpv_preference_preview_color_panel"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="@dimen/cpv_color_preference_large"
|
||||
android:layout_height="@dimen/cpv_color_preference_large"
|
||||
app:cpv_colorShape="circle"/>
|
|
@ -0,0 +1,7 @@
|
|||
<com.jrummyapps.android.colorpicker.ColorPanelView
|
||||
android:id="@id/cpv_preference_preview_color_panel"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="@dimen/cpv_color_preference_normal"
|
||||
android:layout_height="@dimen/cpv_color_preference_normal"
|
||||
app:cpv_colorShape="square"/>
|
|
@ -0,0 +1,7 @@
|
|||
<com.jrummyapps.android.colorpicker.ColorPanelView
|
||||
android:id="@id/cpv_preference_preview_color_panel"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="@dimen/cpv_color_preference_large"
|
||||
android:layout_height="@dimen/cpv_color_preference_large"
|
||||
app:cpv_colorShape="square"/>
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2013 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="cpv_custom">Personalizzato</string>
|
||||
<string name="cpv_default_title">Seleziona un Colore</string>
|
||||
<string name="cpv_presets">Predefiniti</string>
|
||||
<string name="cpv_select">Seleziona</string>
|
||||
<string name="cpv_transparency">Trasparenza</string>
|
||||
</resources>
|
|
@ -0,0 +1,23 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2013 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<!-- Default title for color picker dialog [CHAR LIMIT=30] -->
|
||||
<string name="cpv_default_title">色を選択</string>
|
||||
<string name="cpv_presets">プリセット</string>
|
||||
<string name="cpv_custom">カスタム</string>
|
||||
<string name="cpv_select">選択</string>
|
||||
<string name="cpv_transparency">透明度</string>
|
||||
</resources>
|
|
@ -0,0 +1,38 @@
|
|||
<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="ResourceName">
|
||||
|
||||
<declare-styleable name="ColorPanelView">
|
||||
<attr name="cpv_showOldColor" format="boolean"/>
|
||||
<attr name="cpv_colorShape" format="enum">
|
||||
<enum name="square" value="0"/>
|
||||
<enum name="circle" value="1"/>
|
||||
</attr>
|
||||
<attr name="cpv_borderColor" format="color|reference"/>
|
||||
</declare-styleable>
|
||||
|
||||
<declare-styleable name="ColorPickerView" parent="ColorPanelView">
|
||||
<attr name="cpv_alphaChannelVisible" format="boolean|reference"/>
|
||||
<attr name="cpv_alphaChannelText" format="string|reference"/>
|
||||
<attr name="cpv_sliderColor" format="color|reference"/>
|
||||
<attr name="cpv_borderColor"/>
|
||||
</declare-styleable>
|
||||
|
||||
<declare-styleable name="ColorPreference" parent="ColorPickerDialog">
|
||||
<attr name="cpv_showAlphaSlider" format="boolean|reference"/>
|
||||
<attr name="cpv_previewSize" format="enum">
|
||||
<enum name="regular" value="0"/>
|
||||
<enum name="large" value="1"/>
|
||||
</attr>
|
||||
<attr name="cpv_colorShape"/>
|
||||
<attr name="cpv_dialogTitle" format="reference"/>
|
||||
<attr name="cpv_colorPresets" format="reference"/>
|
||||
<attr name="cpv_dialogType" format="enum">
|
||||
<enum name="custom" value="0"/>
|
||||
<enum name="preset" value="1"/>
|
||||
</attr>
|
||||
<attr name="cpv_showColorShades" format="boolean|reference"/>
|
||||
<attr name="cpv_allowPresets" format="boolean|reference"/>
|
||||
<attr name="cpv_allowCustom" format="boolean|reference"/>
|
||||
<attr name="cpv_showDialog" format="boolean|reference"/>
|
||||
</declare-styleable>
|
||||
|
||||
</resources>
|
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<dimen name="cpv_required_padding">6dp</dimen>
|
||||
<dimen name="cpv_dialog_preview_width">66dp</dimen>
|
||||
<dimen name="cpv_dialog_preview_height">34dp</dimen>
|
||||
<dimen name="cpv_column_width">58dp</dimen>
|
||||
<dimen name="cpv_item_size">50dp</dimen>
|
||||
<dimen name="cpv_item_horizontal_padding">8dp</dimen>
|
||||
<dimen name="cpv_color_preference_normal">28dp</dimen>
|
||||
<dimen name="cpv_color_preference_large">40dp</dimen>
|
||||
</resources>
|
|
@ -0,0 +1,8 @@
|
|||
<resources>
|
||||
|
||||
<item name="cpv_color_picker_view" type="id"/>
|
||||
<item name="cpv_color_panel_old" type="id"/>
|
||||
<item name="cpv_color_panel_new" type="id"/>
|
||||
<item name="cpv_preference_preview_color_panel" type="id"/>
|
||||
|
||||
</resources>
|
|
@ -0,0 +1,23 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2013 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<!-- Default title for color picker dialog [CHAR LIMIT=30] -->
|
||||
<string name="cpv_default_title">Select a Color</string>
|
||||
<string name="cpv_presets">Presets</string>
|
||||
<string name="cpv_custom">Custom</string>
|
||||
<string name="cpv_select">Select</string>
|
||||
<string name="cpv_transparency">Transparency</string>
|
||||
</resources>
|
|
@ -0,0 +1,25 @@
|
|||
<!--
|
||||
~ Copyright (C) 2016 Jared Rummler <jared.rummler@gmail.com>
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
~
|
||||
-->
|
||||
|
||||
<resources xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<style name="cpv_ColorPickerViewStyle">
|
||||
<item name="android:layout_width">match_parent</item>
|
||||
<item name="android:layout_height">315dp</item>
|
||||
</style>
|
||||
|
||||
</resources>
|