Browse Source

Update ColorPicker to 696bb05

pull/554/head
TacoTheDank 4 years ago
parent
commit
660478aafc
  1. 1
      app/build.gradle
  2. 139
      app/src/main/java/net/margaritov/preference/colorpicker/AlphaPatternDrawable.java
  3. 321
      app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerDialog.java
  4. 208
      app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPanelView.java
  5. 549
      app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPreference.java
  6. 1355
      app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerView.java
  7. 111
      app/src/main/res/layout-land/dialog_color_picker.xml
  8. 117
      app/src/main/res/layout/dialog_color_picker.xml

1
app/build.gradle

@ -78,6 +78,7 @@ android {
dependencies { dependencies {
// Android support // Android support
implementation 'androidx.appcompat:appcompat:1.1.0' implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.preference:preference:1.1.1'
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.0.0' implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.0.0'
implementation 'com.google.android.material:material:1.1.0' implementation 'com.google.android.material:material:1.1.0'

139
app/src/main/java/net/margaritov/preference/colorpicker/AlphaPatternDrawable.java

@ -14,6 +14,8 @@
* limitations under the License. * limitations under the License.
*/ */
// Taken from https://github.com/attenzione/android-ColorPickerPreference/tree/696bb050527d6a7ae14e47b7472a0640a7ff08e6
package net.margaritov.preference.colorpicker; package net.margaritov.preference.colorpicker;
import android.graphics.Bitmap; import android.graphics.Bitmap;
@ -28,101 +30,102 @@ import android.graphics.drawable.Drawable;
* This drawable that draws a simple white and gray chessboard pattern. * This drawable that draws a simple white and gray chessboard pattern.
* It's pattern you will often see as a background behind a * It's pattern you will often see as a background behind a
* partly transparent image in many applications. * partly transparent image in many applications.
*
* @author Daniel Nilsson * @author Daniel Nilsson
*/ */
public class AlphaPatternDrawable extends Drawable { public class AlphaPatternDrawable extends Drawable {
private int mRectangleSize = 10; private int mRectangleSize = 10;
private Paint mPaint = new Paint(); private Paint mPaint = new Paint();
private Paint mPaintWhite = new Paint(); private Paint mPaintWhite = new Paint();
private Paint mPaintGray = new Paint(); private Paint mPaintGray = new Paint();
private int numRectanglesHorizontal; private int numRectanglesHorizontal;
private int numRectanglesVertical; private int numRectanglesVertical;
/** /**
* Bitmap in which the pattern will be cahched. * Bitmap in which the pattern will be cahched.
*/ */
private Bitmap mBitmap; private Bitmap mBitmap;
public AlphaPatternDrawable(int rectangleSize) { public AlphaPatternDrawable(int rectangleSize) {
mRectangleSize = rectangleSize; mRectangleSize = rectangleSize;
mPaintWhite.setColor(0xffffffff); mPaintWhite.setColor(0xffffffff);
mPaintGray.setColor(0xffcbcbcb); mPaintGray.setColor(0xffcbcbcb);
} }
@Override @Override
public void draw(Canvas canvas) { public void draw(Canvas canvas) {
canvas.drawBitmap(mBitmap, null, getBounds(), mPaint); canvas.drawBitmap(mBitmap, null, getBounds(), mPaint);
} }
@Override @Override
public int getOpacity() { public int getOpacity() {
return 0; return 0;
} }
@Override @Override
public void setAlpha(int alpha) { public void setAlpha(int alpha) {
throw new UnsupportedOperationException("Alpha is not supported by this drawwable."); throw new UnsupportedOperationException("Alpha is not supported by this drawwable.");
} }
@Override @Override
public void setColorFilter(ColorFilter cf) { public void setColorFilter(ColorFilter cf) {
throw new UnsupportedOperationException("ColorFilter is not supported by this drawwable."); throw new UnsupportedOperationException("ColorFilter is not supported by this drawwable.");
} }
@Override @Override
protected void onBoundsChange(Rect bounds) { protected void onBoundsChange(Rect bounds) {
super.onBoundsChange(bounds); super.onBoundsChange(bounds);
int height = bounds.height(); int height = bounds.height();
int width = bounds.width(); int width = bounds.width();
numRectanglesHorizontal = (int) Math.ceil((width / mRectangleSize)); numRectanglesHorizontal = (int) Math.ceil((width / mRectangleSize));
numRectanglesVertical = (int) Math.ceil(height / mRectangleSize); numRectanglesVertical = (int) Math.ceil(height / mRectangleSize);
generatePatternBitmap(); generatePatternBitmap();
} }
/** /**
* This will generate a bitmap with the pattern * This will generate a bitmap with the pattern
* as big as the rectangle we were allow to draw on. * as big as the rectangle we were allow to draw on.
* We do this to chache the bitmap so we don't need to * We do this to chache the bitmap so we don't need to
* recreate it each time draw() is called since it * recreate it each time draw() is called since it
* takes a few milliseconds. * takes a few milliseconds.
*/ */
private void generatePatternBitmap() { private void generatePatternBitmap() {
if (getBounds().width() <= 0 || getBounds().height() <= 0) { if (getBounds().width() <= 0 || getBounds().height() <= 0) {
return; return;
} }
mBitmap = Bitmap.createBitmap(getBounds().width(), getBounds().height(), Config.ARGB_8888); mBitmap = Bitmap.createBitmap(getBounds().width(), getBounds().height(), Config.ARGB_8888);
Canvas canvas = new Canvas(mBitmap); Canvas canvas = new Canvas(mBitmap);
Rect r = new Rect(); Rect r = new Rect();
boolean verticalStartWhite = true; boolean verticalStartWhite = true;
for (int i = 0; i <= numRectanglesVertical; i++) { for (int i = 0; i <= numRectanglesVertical; i++) {
boolean isWhite = verticalStartWhite; boolean isWhite = verticalStartWhite;
for (int j = 0; j <= numRectanglesHorizontal; j++) { for (int j = 0; j <= numRectanglesHorizontal; j++) {
r.top = i * mRectangleSize; r.top = i * mRectangleSize;
r.left = j * mRectangleSize; r.left = j * mRectangleSize;
r.bottom = r.top + mRectangleSize; r.bottom = r.top + mRectangleSize;
r.right = r.left + mRectangleSize; r.right = r.left + mRectangleSize;
canvas.drawRect(r, isWhite ? mPaintWhite : mPaintGray); canvas.drawRect(r, isWhite ? mPaintWhite : mPaintGray);
isWhite = !isWhite; isWhite = !isWhite;
} }
verticalStartWhite = !verticalStartWhite; verticalStartWhite = !verticalStartWhite;
} }
} }
} }

321
app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerDialog.java

@ -14,123 +14,240 @@
* limitations under the License. * limitations under the License.
*/ */
// Taken from https://github.com/attenzione/android-ColorPickerPreference/tree/696bb050527d6a7ae14e47b7472a0640a7ff08e6
package net.margaritov.preference.colorpicker; package net.margaritov.preference.colorpicker;
import android.app.Dialog;
import android.content.Context; import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.graphics.PixelFormat; import android.graphics.PixelFormat;
import android.os.Bundle; import android.os.Bundle;
import android.text.InputFilter;
import android.text.InputType;
import android.view.KeyEvent;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewTreeObserver;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.TextView;
import org.transdroid.R; import androidx.appcompat.app.AppCompatDialog;
public class ColorPickerDialog extends Dialog implements ColorPickerView.OnColorChangedListener, View.OnClickListener {
private ColorPickerView mColorPicker;
private ColorPickerPanelView mOldColor;
private ColorPickerPanelView mNewColor;
private OnColorChangedListener mListener;
public interface OnColorChangedListener {
public void onColorChanged(int color);
}
public ColorPickerDialog(Context context, int initialColor) {
super(context);
init(initialColor);
}
private void init(int color) {
// To fight color banding.
getWindow().setFormat(PixelFormat.RGBA_8888);
setUp(color);
}
private void setUp(int color) { import org.transdroid.R;
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.dialog_color_picker, null);
setContentView(layout);
setTitle(R.string.dialog_color_picker);
mColorPicker = (ColorPickerView) layout.findViewById(R.id.color_picker_view);
mOldColor = (ColorPickerPanelView) layout.findViewById(R.id.old_color_panel);
mNewColor = (ColorPickerPanelView) layout.findViewById(R.id.new_color_panel);
((LinearLayout) mOldColor.getParent())
.setPadding(Math.round(mColorPicker.getDrawingOffset()), 0, Math.round(mColorPicker.getDrawingOffset()),
0);
mOldColor.setOnClickListener(this);
mNewColor.setOnClickListener(this);
mColorPicker.setOnColorChangedListener(this);
mOldColor.setColor(color);
mColorPicker.setColor(color, true);
}
@Override
public void onColorChanged(int color) {
mNewColor.setColor(color); import java.util.Locale;
public class ColorPickerDialog
extends
AppCompatDialog
implements
ColorPickerView.OnColorChangedListener,
View.OnClickListener, ViewTreeObserver.OnGlobalLayoutListener {
private ColorPickerView mColorPicker;
private ColorPickerPanelView mOldColor;
private ColorPickerPanelView mNewColor;
private EditText mHexVal;
private boolean mHexValueEnabled = false;
private ColorStateList mHexDefaultTextColor;
private OnColorChangedListener mListener;
private int mOrientation;
private View mLayout;
private String mTitle;
@Override
public void onGlobalLayout() {
if (getContext().getResources().getConfiguration().orientation != mOrientation) {
final int oldcolor = mOldColor.getColor();
final int newcolor = mNewColor.getColor();
mLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
setUp(oldcolor);
mNewColor.setColor(newcolor);
mColorPicker.setColor(newcolor);
}
}
public interface OnColorChangedListener {
public void onColorChanged(int color);
}
public ColorPickerDialog(Context context, int initialColor, String title) {
super(context);
mTitle = title;
init(initialColor);
}
private void init(int color) {
// To fight color banding.
getWindow().setFormat(PixelFormat.RGBA_8888);
setUp(color);
}
private void setUp(int color) {
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mLayout = inflater.inflate(R.layout.dialog_color_picker, null);
mLayout.getViewTreeObserver().addOnGlobalLayoutListener(this);
mOrientation = getContext().getResources().getConfiguration().orientation;
setContentView(mLayout);
setTitle(mTitle);
mColorPicker = (ColorPickerView) mLayout.findViewById(R.id.color_picker_view);
mOldColor = (ColorPickerPanelView) mLayout.findViewById(R.id.old_color_panel);
mNewColor = (ColorPickerPanelView) mLayout.findViewById(R.id.new_color_panel);
mHexVal = (EditText) mLayout.findViewById(R.id.hex_val);
mHexVal.setInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
mHexDefaultTextColor = mHexVal.getTextColors();
mHexVal.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE) {
InputMethodManager imm = (InputMethodManager) v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
String s = mHexVal.getText().toString();
if (s.length() > 5 || s.length() < 10) {
try {
int c = ColorPickerPreference.convertToColorInt(s.toString());
mColorPicker.setColor(c, true);
mHexVal.setTextColor(mHexDefaultTextColor);
} catch (IllegalArgumentException e) {
mHexVal.setTextColor(Color.RED);
}
} else {
mHexVal.setTextColor(Color.RED);
}
return true;
}
return false;
}
});
((LinearLayout) mOldColor.getParent()).setPadding(
Math.round(mColorPicker.getDrawingOffset()),
0,
Math.round(mColorPicker.getDrawingOffset()),
0
);
mOldColor.setOnClickListener(this);
mNewColor.setOnClickListener(this);
mColorPicker.setOnColorChangedListener(this);
mOldColor.setColor(color);
mColorPicker.setColor(color, true);
}
@Override
public void onColorChanged(int color) {
mNewColor.setColor(color);
if (mHexValueEnabled)
updateHexValue(color);
/* /*
if (mListener != null) { if (mListener != null) {
mListener.onColorChanged(color); mListener.onColorChanged(color);
} }
*/ */
} }
public void setAlphaSliderVisible(boolean visible) { public void setHexValueEnabled(boolean enable) {
mColorPicker.setAlphaSliderVisible(visible); mHexValueEnabled = enable;
} if (enable) {
mHexVal.setVisibility(View.VISIBLE);
/** updateHexLengthFilter();
* Set a OnColorChangedListener to get notified when the color updateHexValue(getColor());
* selected by the user has changed. } else
* @param listener mHexVal.setVisibility(View.GONE);
*/ }
public void setOnColorChangedListener(OnColorChangedListener listener) {
mListener = listener; public boolean getHexValueEnabled() {
} return mHexValueEnabled;
}
public int getColor() {
return mColorPicker.getColor(); private void updateHexLengthFilter() {
} if (getAlphaSliderVisible())
mHexVal.setFilters(new InputFilter[]{new InputFilter.LengthFilter(9)});
@Override else
public void onClick(View v) { mHexVal.setFilters(new InputFilter[]{new InputFilter.LengthFilter(7)});
if (v.getId() == R.id.new_color_panel) { }
if (mListener != null) {
mListener.onColorChanged(mNewColor.getColor()); private void updateHexValue(int color) {
} if (getAlphaSliderVisible()) {
} mHexVal.setText(ColorPickerPreference.convertToARGB(color).toUpperCase(Locale.getDefault()));
dismiss(); } else {
} mHexVal.setText(ColorPickerPreference.convertToRGB(color).toUpperCase(Locale.getDefault()));
}
@Override mHexVal.setTextColor(mHexDefaultTextColor);
public Bundle onSaveInstanceState() { }
Bundle state = super.onSaveInstanceState();
state.putInt("old_color", mOldColor.getColor()); public void setAlphaSliderVisible(boolean visible) {
state.putInt("new_color", mNewColor.getColor()); mColorPicker.setAlphaSliderVisible(visible);
return state; if (mHexValueEnabled) {
} updateHexLengthFilter();
updateHexValue(getColor());
@Override }
public void onRestoreInstanceState(Bundle savedInstanceState) { }
super.onRestoreInstanceState(savedInstanceState);
mOldColor.setColor(savedInstanceState.getInt("old_color")); public boolean getAlphaSliderVisible() {
mColorPicker.setColor(savedInstanceState.getInt("new_color"), true); return mColorPicker.getAlphaSliderVisible();
} }
/**
* Set a OnColorChangedListener to get notified when the color
* selected by the user has changed.
*
* @param listener
*/
public void setOnColorChangedListener(OnColorChangedListener listener) {
mListener = listener;
}
public int getColor() {
return mColorPicker.getColor();
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.new_color_panel) {
if (mListener != null) {
mListener.onColorChanged(mNewColor.getColor());
}
}
dismiss();
}
@Override
public Bundle onSaveInstanceState() {
Bundle state = super.onSaveInstanceState();
state.putInt("old_color", mOldColor.getColor());
state.putInt("new_color", mNewColor.getColor());
return state;
}
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
mOldColor.setColor(savedInstanceState.getInt("old_color"));
mColorPicker.setColor(savedInstanceState.getInt("new_color"), true);
}
} }

208
app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPanelView.java

@ -14,6 +14,8 @@
* limitations under the License. * limitations under the License.
*/ */
// Taken from https://github.com/attenzione/android-ColorPickerPreference/tree/696bb050527d6a7ae14e47b7472a0640a7ff08e6
package net.margaritov.preference.colorpicker; package net.margaritov.preference.colorpicker;
import android.content.Context; import android.content.Context;
@ -27,140 +29,148 @@ import android.view.View;
* This class draws a panel which which will be filled with a color which can be set. * 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 * It can be used to show the currently selected color which you will get from
* the {@link ColorPickerView}. * the {@link ColorPickerView}.
*
* @author Daniel Nilsson * @author Daniel Nilsson
*/ */
public class ColorPickerPanelView extends View { public class ColorPickerPanelView extends View {
/** /**
* The width in pixels of the border * The width in pixels of the border
* surrounding the color panel. * surrounding the color panel.
*/ */
private final static float BORDER_WIDTH_PX = 1; private final static float BORDER_WIDTH_PX = 1;
private float mDensity = 1f;
private int mBorderColor = 0xff6E6E6E;
private int mColor = 0xff000000;
private Paint mBorderPaint; private float mDensity = 1f;
private Paint mColorPaint;
private RectF mDrawingRect; private int mBorderColor = 0xff6E6E6E;
private RectF mColorRect; private int mColor = 0xff000000;
private AlphaPatternDrawable mAlphaPattern; private Paint mBorderPaint;
private Paint mColorPaint;
private RectF mDrawingRect;
private RectF mColorRect;
public ColorPickerPanelView(Context context) { private AlphaPatternDrawable mAlphaPattern;
this(context, null);
}
public ColorPickerPanelView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ColorPickerPanelView(Context context, AttributeSet attrs, int defStyle) { public ColorPickerPanelView(Context context) {
super(context, attrs, defStyle); this(context, null);
init(); }
}
private void init() { public ColorPickerPanelView(Context context, AttributeSet attrs) {
mBorderPaint = new Paint(); this(context, attrs, 0);
mColorPaint = new Paint(); }
mDensity = getContext().getResources().getDisplayMetrics().density;
}
public ColorPickerPanelView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
@Override private void init() {
protected void onDraw(Canvas canvas) { mBorderPaint = new Paint();
mColorPaint = new Paint();
mDensity = getContext().getResources().getDisplayMetrics().density;
}
final RectF rect = mColorRect;
if (BORDER_WIDTH_PX > 0) { @Override
mBorderPaint.setColor(mBorderColor); protected void onDraw(Canvas canvas) {
canvas.drawRect(mDrawingRect, mBorderPaint);
}
if (mAlphaPattern != null) { final RectF rect = mColorRect;
mAlphaPattern.draw(canvas);
}
mColorPaint.setColor(mColor); if (BORDER_WIDTH_PX > 0) {
mBorderPaint.setColor(mBorderColor);
canvas.drawRect(mDrawingRect, mBorderPaint);
}
canvas.drawRect(rect, mColorPaint); if (mAlphaPattern != null) {
} mAlphaPattern.draw(canvas);
}
@Override mColorPaint.setColor(mColor);
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = MeasureSpec.getSize(widthMeasureSpec); canvas.drawRect(rect, mColorPaint);
int height = MeasureSpec.getSize(heightMeasureSpec); }
setMeasuredDimension(width, height); @Override
} protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
@Override int width = MeasureSpec.getSize(widthMeasureSpec);
protected void onSizeChanged(int w, int h, int oldw, int oldh) { int height = MeasureSpec.getSize(heightMeasureSpec);
super.onSizeChanged(w, h, oldw, oldh);
mDrawingRect = new RectF(); setMeasuredDimension(width, height);
mDrawingRect.left = getPaddingLeft(); }
mDrawingRect.right = w - getPaddingRight();
mDrawingRect.top = getPaddingTop();
mDrawingRect.bottom = h - getPaddingBottom();
setUpColorRect(); @Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
} mDrawingRect = new RectF();
mDrawingRect.left = getPaddingLeft();
mDrawingRect.right = w - getPaddingRight();
mDrawingRect.top = getPaddingTop();
mDrawingRect.bottom = h - getPaddingBottom();
private void setUpColorRect() { setUpColorRect();
final RectF dRect = mDrawingRect;
float left = dRect.left + BORDER_WIDTH_PX; }
float top = dRect.top + BORDER_WIDTH_PX;
float bottom = dRect.bottom - BORDER_WIDTH_PX;
float right = dRect.right - BORDER_WIDTH_PX;
mColorRect = new RectF(left, top, right, bottom); private void setUpColorRect() {
final RectF dRect = mDrawingRect;
mAlphaPattern = new AlphaPatternDrawable((int) (5 * mDensity)); float left = dRect.left + BORDER_WIDTH_PX;
float top = dRect.top + BORDER_WIDTH_PX;
float bottom = dRect.bottom - BORDER_WIDTH_PX;
float right = dRect.right - BORDER_WIDTH_PX;
mAlphaPattern.setBounds(Math.round(mColorRect.left), Math.round(mColorRect.top), Math.round(mColorRect.right), mColorRect = new RectF(left, top, right, bottom);
Math.round(mColorRect.bottom));
} mAlphaPattern = new AlphaPatternDrawable((int) (5 * mDensity));
/** mAlphaPattern.setBounds(
* Set the color that should be shown by this view. Math.round(mColorRect.left),
* @param color Math.round(mColorRect.top),
*/ Math.round(mColorRect.right),
public void setColor(int color) { Math.round(mColorRect.bottom)
mColor = color; );
invalidate();
}
/** }
* Get the color currently show by this view.
* @return
*/
public int getColor() {
return mColor;
}
/** /**
* Set the color of the border surrounding the panel. * Set the color that should be shown by this view.
* @param color *
*/ * @param color
public void setBorderColor(int color) { */
mBorderColor = color; public void setColor(int color) {
invalidate(); mColor = color;
} invalidate();
}
/** /**
* Get the color of the border surrounding the panel. * Get the color currently show by this view.
*/ *
public int getBorderColor() { * @return
return mBorderColor; */
} public int getColor() {
return mColor;
}
/**
* Set the color of the border surrounding the panel.
*
* @param color
*/
public void setBorderColor(int color) {
mBorderColor = color;
invalidate();
}
/**
* Get the color of the border surrounding the panel.
*/
public int getBorderColor() {
return mBorderColor;
}
} }

549
app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPreference.java

@ -14,6 +14,8 @@
* limitations under the License. * limitations under the License.
*/ */
// Taken from https://github.com/attenzione/android-ColorPickerPreference/tree/696bb050527d6a7ae14e47b7472a0640a7ff08e6
package net.margaritov.preference.colorpicker; package net.margaritov.preference.colorpicker;
import android.content.Context; import android.content.Context;
@ -24,259 +26,312 @@ import android.graphics.Color;
import android.os.Bundle; import android.os.Bundle;
import android.os.Parcel; import android.os.Parcel;
import android.os.Parcelable; import android.os.Parcelable;
import android.preference.Preference;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.view.View; import android.view.View;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import androidx.preference.Preference;
import androidx.preference.PreferenceViewHolder;
/** /**
* A preference type that allows a user to choose a time * A preference type that allows a user to choose a color
*
* @author Sergey Margaritov * @author Sergey Margaritov
*/ */
public class ColorPickerPreference extends Preference public class ColorPickerPreference
implements Preference.OnPreferenceClickListener, ColorPickerDialog.OnColorChangedListener { extends
Preference
View mView; implements
ColorPickerDialog mDialog; Preference.OnPreferenceClickListener,
private int mValue = Color.BLACK; ColorPickerDialog.OnColorChangedListener {
private float mDensity = 0;
private boolean mAlphaSliderEnabled = false; View mView;
ColorPickerDialog mDialog;
public ColorPickerPreference(Context context) { private int mValue = Color.BLACK;
super(context); private float mDensity = 0;
init(context, null); private boolean mAlphaSliderEnabled = false;
} private boolean mHexValueEnabled = false;
public ColorPickerPreference(Context context, AttributeSet attrs) { public ColorPickerPreference(Context context) {
super(context, attrs); super(context);
init(context, attrs); init(context, null);
} }
public ColorPickerPreference(Context context, AttributeSet attrs, int defStyle) { public ColorPickerPreference(Context context, AttributeSet attrs) {
super(context, attrs, defStyle); super(context, attrs);
init(context, attrs); init(context, attrs);
} }
@Override public ColorPickerPreference(Context context, AttributeSet attrs, int defStyle) {
protected Object onGetDefaultValue(TypedArray a, int index) { super(context, attrs, defStyle);
return a.getColor(index, Color.BLACK); init(context, attrs);
} }
@Override /**Method edited by
protected void onSetInitialValue(boolean restoreValue, Object defaultValue) { * @author Anna Berkovitch
onColorChanged(restoreValue ? getPersistedInt(mValue) : (Integer) defaultValue); * added functionality to accept hex string as defaultValue
} * and to properly persist resources reference string, such as @color/someColor
* previously persisted 0*/
private void init(Context context, AttributeSet attrs) { @Override
mDensity = getContext().getResources().getDisplayMetrics().density; protected Object onGetDefaultValue(TypedArray a, int index) {
setOnPreferenceClickListener(this); int colorInt;
if (attrs != null) { String mHexDefaultValue = a.getString(index);
mAlphaSliderEnabled = attrs.getAttributeBooleanValue(null, "alphaSlider", false); if (mHexDefaultValue != null && mHexDefaultValue.startsWith("#")) {
} colorInt = convertToColorInt(mHexDefaultValue);
} return colorInt;
@Override } else {
protected void onBindView(View view) { return a.getColor(index, Color.BLACK);
super.onBindView(view); }
mView = view; }
setPreviewColor();
} @Override
protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
private void setPreviewColor() { onColorChanged(restoreValue ? getPersistedInt(mValue) : (Integer) defaultValue);
if (mView == null) { }
return;
} private void init(Context context, AttributeSet attrs) {
ImageView iView = new ImageView(getContext()); mDensity = getContext().getResources().getDisplayMetrics().density;
LinearLayout widgetFrameView = ((LinearLayout) mView.findViewById(android.R.id.widget_frame)); setOnPreferenceClickListener(this);
if (widgetFrameView == null) { if (attrs != null) {
return; mAlphaSliderEnabled = attrs.getAttributeBooleanValue(null, "alphaSlider", false);
} mHexValueEnabled = attrs.getAttributeBooleanValue(null, "hexValue", false);
widgetFrameView.setVisibility(View.VISIBLE); }
widgetFrameView }
.setPadding(widgetFrameView.getPaddingLeft(), widgetFrameView.getPaddingTop(), (int) (mDensity * 8),
widgetFrameView.getPaddingBottom()); @Override
// remove already create preview image public void onBindViewHolder(PreferenceViewHolder holder) {
int count = widgetFrameView.getChildCount(); super.onBindViewHolder(holder);
if (count > 0) {
widgetFrameView.removeViews(0, count); mView = holder.itemView;
} setPreviewColor();
widgetFrameView.addView(iView); }
widgetFrameView.setMinimumWidth(0);
iView.setBackgroundDrawable(new AlphaPatternDrawable((int) (5 * mDensity))); private void setPreviewColor() {
iView.setImageBitmap(getPreviewBitmap()); if (mView == null) return;
} ImageView iView = new ImageView(getContext());
LinearLayout widgetFrameView = ((LinearLayout) mView.findViewById(android.R.id.widget_frame));
private Bitmap getPreviewBitmap() { if (widgetFrameView == null) return;
int d = (int) (mDensity * 31); //30dip widgetFrameView.setVisibility(View.VISIBLE);
int color = mValue; widgetFrameView.setPadding(
Bitmap bm = Bitmap.createBitmap(d, d, Config.ARGB_8888); widgetFrameView.getPaddingLeft(),
int w = bm.getWidth(); widgetFrameView.getPaddingTop(),
int h = bm.getHeight(); (int) (mDensity * 8),
int c = color; widgetFrameView.getPaddingBottom()
for (int i = 0; i < w; i++) { );
for (int j = i; j < h; j++) { // remove already create preview image
c = (i <= 1 || j <= 1 || i >= w - 2 || j >= h - 2) ? Color.GRAY : color; int count = widgetFrameView.getChildCount();
bm.setPixel(i, j, c); if (count > 0) {
if (i != j) { widgetFrameView.removeViews(0, count);
bm.setPixel(j, i, c); }
} widgetFrameView.addView(iView);
} widgetFrameView.setMinimumWidth(0);
} iView.setBackgroundDrawable(new AlphaPatternDrawable((int) (5 * mDensity)));
iView.setImageBitmap(getPreviewBitmap());
return bm; }
}
private Bitmap getPreviewBitmap() {
@Override int d = (int) (mDensity * 31); //30dip
public void onColorChanged(int color) { int color = mValue;
if (isPersistent()) { Bitmap bm = Bitmap.createBitmap(d, d, Config.ARGB_8888);
persistInt(color); int w = bm.getWidth();
} int h = bm.getHeight();
mValue = color; int c = color;
setPreviewColor(); for (int i = 0; i < w; i++) {
try { for (int j = i; j < h; j++) {
getOnPreferenceChangeListener().onPreferenceChange(this, color); c = (i <= 1 || j <= 1 || i >= w - 2 || j >= h - 2) ? Color.GRAY : color;
} catch (NullPointerException e) { bm.setPixel(i, j, c);
if (i != j) {
} bm.setPixel(j, i, c);
} }
}
public boolean onPreferenceClick(Preference preference) { }
showDialog(null);
return false; return bm;
} }
protected void showDialog(Bundle state) { @Override
mDialog = new ColorPickerDialog(getContext(), mValue); public void onColorChanged(int color) {
mDialog.setOnColorChangedListener(this); if (isPersistent()) {
if (mAlphaSliderEnabled) { persistInt(color);
mDialog.setAlphaSliderVisible(true); }
} mValue = color;
if (state != null) { setPreviewColor();
mDialog.onRestoreInstanceState(state); try {
} getOnPreferenceChangeListener().onPreferenceChange(this, color);
mDialog.show(); } catch (NullPointerException e) {
}
}
/** }
* Toggle Alpha Slider visibility (by default it's disabled)
* @param enable public boolean onPreferenceClick(Preference preference) {
*/ showDialog(null);
public void setAlphaSliderEnabled(boolean enable) { return false;
mAlphaSliderEnabled = enable; }
}
protected void showDialog(Bundle state) {
/** mDialog = new ColorPickerDialog(getContext(), mValue, getTitle().toString());
* For custom purposes. Not used by ColorPickerPreferrence mDialog.setOnColorChangedListener(this);
* @param color if (mAlphaSliderEnabled) {
* @author Unknown mDialog.setAlphaSliderVisible(true);
*/ }
public static String convertToARGB(int color) { if (mHexValueEnabled) {
String alpha = Integer.toHexString(Color.alpha(color)); mDialog.setHexValueEnabled(true);
String red = Integer.toHexString(Color.red(color)); }
String green = Integer.toHexString(Color.green(color)); if (state != null) {
String blue = Integer.toHexString(Color.blue(color)); mDialog.onRestoreInstanceState(state);
}
if (alpha.length() == 1) { mDialog.show();
alpha = "0" + alpha; }
}
/**
if (red.length() == 1) { * Toggle Alpha Slider visibility (by default it's disabled)
red = "0" + red; *
} * @param enable
*/
if (green.length() == 1) { public void setAlphaSliderEnabled(boolean enable) {
green = "0" + green; mAlphaSliderEnabled = enable;
} }
if (blue.length() == 1) { /**
blue = "0" + blue; * Toggle Hex Value visibility (by default it's disabled)
} *
* @param enable
return "#" + alpha + red + green + blue; */
} public void setHexValueEnabled(boolean enable) {
mHexValueEnabled = enable;
/** }
* For custom purposes. Not used by ColorPickerPreferrence
* @param argb /**
* @throws NumberFormatException * For custom purposes. Not used by ColorPickerPreferrence
* @author Unknown *
*/ * @param color
public static int convertToColorInt(String argb) throws NumberFormatException { * @author Unknown
*/
if (argb.startsWith("#")) { public static String convertToARGB(int color) {
argb = argb.replace("#", ""); String alpha = Integer.toHexString(Color.alpha(color));
} String red = Integer.toHexString(Color.red(color));
String green = Integer.toHexString(Color.green(color));
int alpha = -1, red = -1, green = -1, blue = -1; String blue = Integer.toHexString(Color.blue(color));
if (argb.length() == 8) { if (alpha.length() == 1) {
alpha = Integer.parseInt(argb.substring(0, 2), 16); alpha = "0" + alpha;
red = Integer.parseInt(argb.substring(2, 4), 16); }
green = Integer.parseInt(argb.substring(4, 6), 16);
blue = Integer.parseInt(argb.substring(6, 8), 16); if (red.length() == 1) {
} else if (argb.length() == 6) { red = "0" + red;
alpha = 255; }
red = Integer.parseInt(argb.substring(0, 2), 16);
green = Integer.parseInt(argb.substring(2, 4), 16); if (green.length() == 1) {
blue = Integer.parseInt(argb.substring(4, 6), 16); green = "0" + green;
} }
return Color.argb(alpha, red, green, blue); if (blue.length() == 1) {
} blue = "0" + blue;
}
@Override
protected Parcelable onSaveInstanceState() { return "#" + alpha + red + green + blue;
final Parcelable superState = super.onSaveInstanceState(); }
if (mDialog == null || !mDialog.isShowing()) {
return superState; /**
} * Method currently used by onGetDefaultValue method to
* convert hex string provided in android:defaultValue to color integer.
final SavedState myState = new SavedState(superState); *
myState.dialogBundle = mDialog.onSaveInstanceState(); * @param color
return myState; * @return A string representing the hex value of color,
} * without the alpha value
* @author Charles Rosaaen
@Override */
protected void onRestoreInstanceState(Parcelable state) { public static String convertToRGB(int color) {
if (state == null || !(state instanceof SavedState)) { String red = Integer.toHexString(Color.red(color));
// Didn't save state for us in onSaveInstanceState String green = Integer.toHexString(Color.green(color));
super.onRestoreInstanceState(state); String blue = Integer.toHexString(Color.blue(color));
return;
} if (red.length() == 1) {
red = "0" + red;
SavedState myState = (SavedState) state; }
super.onRestoreInstanceState(myState.getSuperState());
showDialog(myState.dialogBundle); if (green.length() == 1) {
} green = "0" + green;
}
private static class SavedState extends BaseSavedState {
Bundle dialogBundle; if (blue.length() == 1) {
blue = "0" + blue;
public SavedState(Parcel source) { }
super(source);
dialogBundle = source.readBundle(); return "#" + red + green + blue;
} }
@Override /**
public void writeToParcel(Parcel dest, int flags) { * For custom purposes. Not used by ColorPickerPreferrence
super.writeToParcel(dest, flags); *
dest.writeBundle(dialogBundle); * @param argb
} * @throws NumberFormatException
* @author Unknown
public SavedState(Parcelable superState) { */
super(superState); public static int convertToColorInt(String argb) throws IllegalArgumentException {
}
if (!argb.startsWith("#")) {
@SuppressWarnings("unused") argb = "#" + argb;
public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>() { }
public SavedState createFromParcel(Parcel in) {
return new SavedState(in); return Color.parseColor(argb);
} }
public SavedState[] newArray(int size) { @Override
return new SavedState[size]; protected Parcelable onSaveInstanceState() {
} final Parcelable superState = super.onSaveInstanceState();
}; if (mDialog == null || !mDialog.isShowing()) {
} return superState;
}
final SavedState myState = new SavedState(superState);
myState.dialogBundle = mDialog.onSaveInstanceState();
return myState;
}
@Override
protected void onRestoreInstanceState(Parcelable state) {
if (state == null || !(state instanceof SavedState)) {
// Didn't save state for us in onSaveInstanceState
super.onRestoreInstanceState(state);
return;
}
SavedState myState = (SavedState) state;
super.onRestoreInstanceState(myState.getSuperState());
showDialog(myState.dialogBundle);
}
private static class SavedState extends BaseSavedState {
Bundle dialogBundle;
public SavedState(Parcel source) {
super(source);
dialogBundle = source.readBundle();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeBundle(dialogBundle);
}
public SavedState(Parcelable superState) {
super(superState);
}
@SuppressWarnings("unused")
public static final Parcelable.Creator<SavedState> CREATOR =
new Parcelable.Creator<SavedState>() {
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
} }

1355
app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerView.java

File diff suppressed because it is too large Load Diff

111
app/src/main/res/layout-land/dialog_color_picker.xml

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?><!--
<!-- Copyright (C) 2010 Daniel Nilsson Copyright (C) 2010 Daniel Nilsson
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -10,68 +10,73 @@
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and limitations under the License.
limitations under the License.
// Taken from https://github.com/attenzione/android-ColorPickerPreference/tree/696bb050527d6a7ae14e47b7472a0640a7ff08e6
--> -->
<LinearLayout <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingLeft="5dp" android:paddingLeft="5dp"
android:paddingRight="5dp" android:paddingRight="5dp">
android:orientation="horizontal">
<net.margaritov.preference.colorpicker.ColorPickerView <net.margaritov.preference.colorpicker.ColorPickerView
android:id="@+id/color_picker_view" android:id="@+id/color_picker_view"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:tag="landscape" android:layerType="software"
android:layerType="software" android:tag="landscape" />
/>
<LinearLayout <LinearLayout
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:layout_marginBottom="10dp"
android:layout_marginBottom="10dp"> android:orientation="vertical">
<TextView <EditText
android:layout_width="wrap_content" android:id="@+id/hex_val"
android:layout_height="wrap_content" android:layout_width="fill_parent"
android:text="@string/press_color_to_apply" android:layout_height="wrap_content"
android:gravity="center" android:hint="HEX"
android:layout_marginTop="6dp" android:imeOptions="actionDone"
android:layout_marginLeft="6dp" android:maxLength="7"
android:layout_marginRight="6dp" android:singleLine="true"
android:layout_marginBottom="5dp" android:inputType="textCapCharacters"
android:textAppearance="?android:attr/textAppearanceSmall" android:visibility="gone"></EditText>
/>
<net.margaritov.preference.colorpicker.ColorPickerPanelView <TextView
android:id="@+id/old_color_panel" android:layout_width="wrap_content"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:layout_height="40dp" android:layout_marginBottom="5dp"
android:layout_weight="0.5" android:layout_marginLeft="6dp"
/> android:layout_marginRight="6dp"
android:layout_marginTop="6dp"
android:gravity="center"
android:text="@string/press_color_to_apply"
android:textAppearance="?android:attr/textAppearanceSmall" />
<TextView <net.margaritov.preference.colorpicker.ColorPickerPanelView
android:layout_width="fill_parent" android:id="@+id/old_color_panel"
android:layout_height="wrap_content" android:layout_width="fill_parent"
android:text="↓" android:layout_height="40dp"
android:textSize="20sp" android:layout_weight="0.5" />
android:gravity="center"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
/>
<net.margaritov.preference.colorpicker.ColorPickerPanelView <TextView
android:id="@+id/new_color_panel" android:layout_width="fill_parent"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:layout_height="40dp" android:layout_marginBottom="10dp"
android:layout_weight="0.5" android:layout_marginTop="10dp"
/> android:gravity="center"
android:text="↓"
android:textSize="20sp" />
</LinearLayout> <net.margaritov.preference.colorpicker.ColorPickerPanelView
android:id="@+id/new_color_panel"
android:layout_width="fill_parent"
android:layout_height="40dp"
android:layout_weight="0.5" />
</LinearLayout>
</LinearLayout> </LinearLayout>

117
app/src/main/res/layout/dialog_color_picker.xml

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?><!--
<!-- Copyright (C) 2010 Daniel Nilsson Copyright (C) 2010 Daniel Nilsson
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -10,68 +10,79 @@
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and limitations under the License.
limitations under the License.
// Taken from https://github.com/attenzione/android-ColorPickerPreference/tree/696bb050527d6a7ae14e47b7472a0640a7ff08e6
--> -->
<LinearLayout <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingLeft="5dp" android:paddingLeft="5dp"
android:paddingRight="5dp" android:paddingRight="5dp">
android:orientation="vertical">
<net.margaritov.preference.colorpicker.ColorPickerView
android:id="@+id/color_picker_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layerType="software"
android:tag="portrait" />
<net.margaritov.preference.colorpicker.ColorPickerView <LinearLayout
android:id="@+id/color_picker_view" android:id="@+id/text_hex_wrapper"
android:layout_width="wrap_content" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" android:layout_marginBottom="5dp"
android:tag="portrait" android:layout_marginLeft="6dp"
android:layerType="software" android:layout_marginRight="6dp">
/>
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/press_color_to_apply" android:gravity="left"
android:gravity="left" android:text="@string/press_color_to_apply"
android:layout_marginLeft="6dp" android:textAppearance="?android:attr/textAppearanceSmall" />
android:layout_marginRight="6dp"
android:layout_marginBottom="5dp"
android:textAppearance="?android:attr/textAppearanceSmall"
/>
<LinearLayout <EditText
android:layout_width="wrap_content" android:id="@+id/hex_val"
android:layout_height="40dp" android:layout_width="0dp"
android:orientation="horizontal" android:layout_height="wrap_content"
android:layout_marginBottom="10dp"> android:layout_weight="1"
android:hint="HEX"
android:imeOptions="actionDone"
android:maxLength="7"
android:singleLine="true"
android:inputType="textCapCharacters"
android:visibility="gone"></EditText>
</LinearLayout>
<net.margaritov.preference.colorpicker.ColorPickerPanelView <LinearLayout
android:id="@+id/old_color_panel" android:layout_width="wrap_content"
android:layout_width="0px" android:layout_height="40dp"
android:layout_height="fill_parent" android:layout_marginBottom="10dp"
android:layout_weight="0.5" android:orientation="horizontal">
/>
<TextView <net.margaritov.preference.colorpicker.ColorPickerPanelView
android:layout_width="wrap_content" android:id="@+id/old_color_panel"
android:layout_height="fill_parent" android:layout_width="0px"
android:text="→" android:layout_height="fill_parent"
android:textSize="20sp" android:layout_weight="0.5" />
android:gravity="center"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
/>
<net.margaritov.preference.colorpicker.ColorPickerPanelView <TextView
android:id="@+id/new_color_panel" android:layout_width="wrap_content"
android:layout_width="0px" android:layout_height="fill_parent"
android:layout_height="wrap_content" android:layout_marginLeft="10dp"
android:layout_weight="0.5" android:layout_marginRight="10dp"
/> android:gravity="center"
android:text="→"
android:textSize="20sp" />
</LinearLayout> <net.margaritov.preference.colorpicker.ColorPickerPanelView
android:id="@+id/new_color_panel"
android:layout_width="0px"
android:layout_height="wrap_content"
android:layout_weight="0.5" />
</LinearLayout>
</LinearLayout> </LinearLayout>
Loading…
Cancel
Save