Android SDKには、色を選択するダイアログが無いので、使えそうなものをネットで探していたけど、なかなか用途に合ったものが見つからなかった。というわけで去年、自分で作ってみた。一年かけて少しずつ改良したので、現在のバージョンを公開します。使用はご自由に。
RGBの値をスライダーで細かく制御可能で、モノクロにも対応しています。
http://fumobox.com/file/demo/ColorEditorDemo.zip
ソースをgithubにも置きました。こっちが最新版です。
https://github.com/fumobox/simple_color_chooser_demo
Eclipseのプロジェクトファイルになっています。Android 4.2以上推奨。
使い方は簡単。MainActivityにイベントリスナーを追加して、下のようなコードを呼び出すだけ。
ColorEditDialogFragment.show("Color", _colbox.getColor(), MainActivity.this, MainActivity.this);
主なファイルは以下の3個です。インターフェースの実装方法に問題ありそうだけど、一番シンプルな方法で書いてみました。
MainActivity.java(抜粋)
メインクラス
public class MainActivity extends Activity implements ColorEditDialogFragment.OnColorChangedListener{
private ColorBoxView _colbox;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
_colbox = (ColorBoxView) findViewById(R.id.colbox);
Button bt = (Button) findViewById(R.id.button1);
bt.setOnClickListener(new android.view.View.OnClickListener() {
@Override
public void onClick(View v) {
ColorEditDialogFragment.show("Color", _colbox.getColor(), MainActivity.this, MainActivity.this);
}
});
}
@Override
public void colorChanged(int color, int r, int g, int b) {
_colbox.setColor(color);
}
}
ColorEditDialogFragment.java(抜粋)
メインダイアログ
public class ColorEditDialogFragment extends DialogFragment {
private OnColorChangedListener _listener;
public static void show(String title, int color, OnColorChangedListener listener, Activity act) {
ColorEditDialogFragment d = new ColorEditDialogFragment();
d._listener = listener;
Bundle args = new Bundle();
args.putString("title", title);
args.putInt("color", color);
d.setArguments(args);
d.show(act.getFragmentManager(), "dialog");
}
public interface OnColorChangedListener {
void colorChanged(int color, int r, int g, int b);
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
ColorEditDialog d = new ColorEditDialog(this.getActivity());
return d;
}
private class ColorEditDialog extends Dialog {
private int _color;
private int _r, _g, _b;
private CheckBox _cb_mono;
private TextView _tv01;
private ColorBoxView _colbox;
private SeekBar[] _sb;
public ColorEditDialog(Context context) {
super(context);
}
public void onCreate(Bundle savedInstanceState) {
setCanceledOnTouchOutside(true);
setContentView(this.getLayoutInflater().inflate(R.layout.color_edit, null));
String title = getArguments().getString("title");
this.setTitle(title);
_color = getArguments().getInt("color");
_colbox = (ColorBoxView) findViewById(R.id.colbox);
_sb = new SeekBar[3];
_sb[0] = (SeekBar) findViewById(R.id.sb_gap);
_sb[0].setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (!fromUser) {
return;
}
_r = progress;
if (_cb_mono.isChecked()) {
_sb[1].setProgress(progress);
_sb[2].setProgress(progress);
_g = progress;
_b = progress;
}
combineColor();
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
_sb[1] = (SeekBar) findViewById(R.id.sb_g);
_sb[1].setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (!fromUser) {
return;
}
_g = progress;
if (_cb_mono.isChecked()) {
_sb[0].setProgress(progress);
_sb[2].setProgress(progress);
_r = progress;
_b = progress;
}
combineColor();
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
_sb[2] = (SeekBar) findViewById(R.id.sb_b);
_sb[2].setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (!fromUser) {
return;
}
_b = progress;
if (_cb_mono.isChecked()) {
_sb[0].setProgress(progress);
_sb[1].setProgress(progress);
_r = progress;
_g = progress;
}
combineColor();
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
_tv01 = (TextView) findViewById(R.id.tv01);
_cb_mono = (CheckBox) findViewById(R.id.cb_marge);
_cb_mono.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
if (_cb_mono.isChecked()) {
_r = _sb[0].getProgress();
_sb[1].setProgress(_r);
_sb[2].setProgress(_r);
_g = _r;
_b = _r;
combineColor();
} else {
}
}
});
Button bt_ok = (Button) findViewById(R.id.bt_ok);
bt_ok.setOnClickListener(new android.view.View.OnClickListener() {
@Override
public void onClick(View v) {
ColorEditDialog.this.dismiss();
if (_listener != null) {
_listener.colorChanged(_color, _r, _g, _b);
}
}
});
Button bt_cancel = (Button) findViewById(R.id.bt_cancel);
bt_cancel.setOnClickListener(new android.view.View.OnClickListener() {
@Override
public void onClick(View v) {
dismiss();
}
});
adjustBar();
}
public void adjustBar() {
_r = (_color >>> 16) & 0xff;
_g = (_color >>> 8) & 0xff;
_b = (_color >>> 0) & 0xff;
_sb[0].setProgress(_r);
_sb[1].setProgress(_g);
_sb[2].setProgress(_b);
_colbox.setColor(_color);
_tv01.setText("#" + Integer.toHexString(_color & 0x00ffffff) + " (" + _r + ", " + _g + ", " + _b + ")");
}
public void combineColor() {
_color = 0xff000000;
_color |= _r << 16;
_color |= _g << 8;
_color |= _b;
_colbox.setColor(_color);
_tv01.setText("#" + Integer.toHexString(_color & 0x00ffffff) + " (" + _r + ", " + _g + ", " + _b + ")");
}
}
}
ColorEditDialogFragment.java(抜粋)
色の表示用ボックス
public class ColorBoxView extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder _sh;
public static final int PADDING_DEFAULT = 4;
private int _padding = PADDING_DEFAULT;
public static final int COLOR_DEFAULT = 0xffffffff;
private int _color = COLOR_DEFAULT;
public ColorBoxView(Context context) {
super(context);
init();
}
public ColorBoxView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public ColorBoxView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
_sh = getHolder();
_sh.addCallback(this);
_sh.setFormat(PixelFormat.TRANSLUCENT);
setFocusable(true);
setZOrderOnTop(true);
}
@Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
}
@Override
public void surfaceCreated(SurfaceHolder arg0) {
draw();
}
@Override
public void surfaceDestroyed(SurfaceHolder arg0) {
}
public void draw() {
Canvas canvas = _sh.lockCanvas();
if(canvas == null) {
return;
}
float w = this.getWidth();
float h = this.getHeight();
float bw = w - _padding * 2f;
float bh = h - _padding * 2f;
RectF rect = new RectF(_padding, _padding, _padding + bw, _padding + bh);
Paint p = new Paint();
p.setAntiAlias(true);
canvas.drawColor(Color.TRANSPARENT, android.graphics.PorterDuff.Mode.CLEAR);
p.setStyle(Style.FILL);
p.setColor(_color);
canvas.drawRoundRect(rect, 4, 4, p);
p.setStyle(Style.STROKE);
p.setStrokeWidth(2);
p.setColor(0xff666666);
canvas.drawRoundRect(rect, 4, 4, p);
_sh.unlockCanvasAndPost(canvas);
}
@Override
public boolean onTouchEvent(MotionEvent e) {
return true;
}
public int getColor() {
return _color;
}
public void setColor(int color) {
_color = color | 0xff000000;
draw();
}
}
1/18 追記
ソースをgithubにも置きました。こっちが最新版です。
https://github.com/fumobox/simple_color_chooser_demo

0 件のコメント:
コメントを投稿