我想使用高级颜色选择器对话框而不是谷歌的默认颜色
- ColorPickerView.java(见上面的链接)
- CreativePainterActivity.java
package jlab.creativePainter;
import java.io.*;
import java.util.*;
import com.google.ads.*;
import jlab.creativePainter.R;
import android.app.Activity;
import android.content.*;
import android.graphics.*;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.PorterDuff.Mode;
import android.media.*;
import android.media.MediaScannerConnection.MediaScannerConnectionClient;
import android.net.*;
import android.os.*;
import android.util.*;
import android.view.*;
import android.view.ViewGroup.LayoutParams;
import android.widget.*;
//public class CreativePainterActivity extends Activity implements ColorPickerDialog.OnColorChangedListener {
public class CreativePainterActivity extends Activity implements ColorPickerView.OnColorChangedListener {
MyView vw;
public void onCreate(Bundle savedInstaneState) {
super.onCreate(savedInstaneState);
vw = new MyView(this);
setContentView(vw);
//addContentView(R.layout.main);
addContentView( LayoutInflater.from( this ).inflate( R.layout.main, null), new LayoutParams( LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT ) ) ;
//adMob
AdView adview = (AdView)findViewById(R.id.adView);
AdRequest re = new AdRequest();
re.setTesting(true);
adview.loadAd(re);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(0xFFFF0000);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(12);
mEmboss = new EmbossMaskFilter(new float[] { 1, 1, 1 }, 0.4f, 6, 3.5f);
mBlur = new BlurMaskFilter(8, BlurMaskFilter.Blur.NORMAL);
//
Toast.makeText(this, "Draw it!", Toast.LENGTH_SHORT).show();
}
private Paint mPaint;
private MaskFilter mEmboss;
private MaskFilter mBlur;
public void colorChanged(int color) {
mPaint.setColor(color);
}
protected class MyView extends View {
private static final float MINP = 0.25f;
private static final float MAXP = 0.75f;
private Bitmap mBitmap, mBitmap2;
private Canvas mCanvas;
private Path mPath;
private Paint mBitmapPaint;
public MyView(Context context){
super(context);
///added by JLab
setDrawingCacheEnabled(true);
//
mPath = new Path();
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
}
public void onDraw(Canvas canvas){
canvas.drawColor(Color.BLACK);
//added from fingerPaint.java
//canvas.drawColor(0xFFAAAAAA);
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
//added By JEON
canvas.drawPath(mPath, mPaint);
}
private float mX, mY;
private static final float TOUCH_TOLERANCE = 4;
private void touch_start(float x, float y) {
mPath.reset();
mPath.moveTo(x, y);
mX = x;
mY = y;
}
private void touch_move(float x, float y) {
float dx = Math.abs(x - mX);
float dy = Math.abs(y - mY);
if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2);
mX = x;
mY = y;
}
}
private void touch_up() {
mPath.lineTo(mX, mY);
// commit the path to our offscreen
mCanvas.drawPath(mPath, mPaint);
// kill this so we don't double draw
mPath.reset();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touch_start(x, y);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
touch_move(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP:
touch_up();
invalidate();
break;
}
return true;
}
//clear method
public void clear() {
if (mCanvas != null) {
int color;
color = mPaint.getColor();
mPaint.setColor(Color.BLACK);
mCanvas.drawPaint(mPaint);
invalidate();
mPaint.setColor(color);
//mFadeSteps = MAX_FADE_STEPS;
}
}
}//end of the class MyView
//Menu Items
private static final int COLOR_MENU_ID = Menu.FIRST;
private static final int CLEAR_MENU_ID = Menu.FIRST + 1;
// private static final int EMBOSS_MENU_ID = Menu.FIRST + 2;
private static final int LOAD_MENU_ID = Menu.FIRST + 2;
private static final int BLUR_MENU_ID = Menu.FIRST + 3;
private static final int ERASE_MENU_ID = Menu.FIRST + 4;
// private static final int SRCATOP_MENU_ID = Menu.FIRST + 5;
private static final int SAVE_MENU_ID = Menu.FIRST + 5;
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
menu.add(0, COLOR_MENU_ID, 0, "Color").setShortcut('3', 'c');
menu.add(0, CLEAR_MENU_ID, 0, "Clear").setShortcut('4', 's');
// menu.add(0, EMBOSS_MENU_ID, 0, "Emboss").setShortcut('4', 's');
menu.add(0, LOAD_MENU_ID, 0, "LOAD").setShortcut('5', 'z');
menu.add(0, BLUR_MENU_ID, 0, "Blur").setShortcut('5', 'z');
menu.add(0, ERASE_MENU_ID, 0, "Erase").setShortcut('5', 'z');
// menu.add(0, SRCATOP_MENU_ID, 0, "SrcATop").setShortcut('5', 'z');
menu.add(0, SAVE_MENU_ID, 0, "SAVE").setShortcut('5', 'z');
/**** Is this the mechanism to extend with filter effects?
Intent intent = new Intent(null, getIntent().getData());
intent.addCategory(Intent.CATEGORY_ALTERNATIVE);
menu.addIntentOptions(
Menu.ALTERNATIVE, 0,
new ComponentName(this, NotesList.class),
null, intent, 0, null);
*****/
return true;
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
mPaint.setXfermode(null);
mPaint.setAlpha(0xFF);
File imageFileFolder;
File imageFileName;
switch (item.getItemId()) {
case COLOR_MENU_ID:
//new ColorPickerDialog(this, this, mPaint.getColor()).show();
new ColorPickerView(this).draw(vw.mCanvas);
return true;
case CLEAR_MENU_ID:
vw.clear();
return true;
/*
case EMBOSS_MENU_ID:
if (mPaint.getMaskFilter() != mEmboss) {
mPaint.setMaskFilter(mEmboss);
} else {
mPaint.setMaskFilter(null);
}
return true;
*/
case LOAD_MENU_ID:
/*
String sdLPath;
sdLPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/";
Bitmap bitmap = BitmapFactory.decodeFile(sdLPath+"image.jpeg");
vw.clear();
vw.mCanvas.drawBitmap(bitmap, 0, 0, vw.mBitmapPaint);
invalidate();
*/
vw.clear();
//vw.invalidate();
Intent intent = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, 0);
return true;
case BLUR_MENU_ID:
if (mPaint.getMaskFilter() != mBlur) {
mPaint.setMaskFilter(mBlur);
} else {
mPaint.setMaskFilter(null);
}
return true;
case ERASE_MENU_ID:
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
return true;
/*
case SRCATOP_MENU_ID:
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP));
mPaint.setAlpha(0x80);
return true;
*/
case SAVE_MENU_ID:
//added by JLab
Bitmap b = vw.getDrawingCache();
//vw.destroyDrawingCache();
imageFileFolder = new File(Environment.getExternalStorageDirectory(),"CreativePainter");
imageFileFolder.mkdir();
FileOutputStream out = null;
Calendar c = Calendar.getInstance();
String date = fromInt(c.get(Calendar.MONTH))
+ fromInt(c.get(Calendar.DAY_OF_MONTH))
+ fromInt(c.get(Calendar.YEAR))
+ fromInt(c.get(Calendar.HOUR_OF_DAY))
+ fromInt(c.get(Calendar.MINUTE))
+ fromInt(c.get(Calendar.SECOND));
imageFileName = new File(imageFileFolder, date.toString() + ".jpg");
try
{
out = new FileOutputStream(imageFileName);
b.compress(Bitmap.CompressFormat.JPEG, 95, out);
//out.flush();
//out.close();
Toast.makeText(this, imageFileName.toString(), Toast.LENGTH_SHORT).show();
scanPhoto(imageFileName.toString());
vw.destroyDrawingCache();
//out = null;
} catch (Exception e)
{
Toast.makeText(this, "An error has occured", Toast.LENGTH_SHORT).show();
}
/////
return true;
}//end SWITCH
return super.onOptionsItemSelected(item);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
//Toast.makeText(this, Integer.toString(requestCode), Toast.LENGTH_SHORT).show();
//Toast.makeText(this, Integer.toString(resultCode), Toast.LENGTH_SHORT).show();
if (resultCode == RESULT_OK){
Uri targetUri = data.getData();
Bitmap bitmap;
Bitmap bitmap2;
//resize the image
Display display = getWindowManager().getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();
try {
bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(targetUri));
//resize
bitmap2 = Bitmap.createScaledBitmap(bitmap, width, height, true);
vw.mCanvas.drawBitmap(bitmap2, 0, 0, vw.mBitmapPaint);
//invalidate();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
Toast.makeText(this, "File Not Found!", Toast.LENGTH_SHORT).show();
}
}
vw.invalidate();
}//end of the onActivityResult method
//scanPhoto method
private MediaScannerConnection msConn;
public void scanPhoto(final String imageFileName)
{
msConn = new MediaScannerConnection(this, new MediaScannerConnectionClient()
{
public void onMediaScannerConnected()
{
msConn.scanFile(imageFileName, null);
Log.i("msClient obj in Photo Utility","connection established");
}
public void onScanCompleted(String path, Uri uri)
{
Log.i("msClient obj in Photo Utility","scan completed");
}
});
msConn.connect();
}
///added
public String fromInt(int val)
{
return String.valueOf(val);
}
public void onColorChanged(int color) {
// TODO Auto-generated method stub
}
}//end of the class CreativePainterActivity
但是,将应用程序放到Android设备后
它显示错误(log cat)
09-01 05:08:02.617: E/AndroidRuntime(15718): FATAL EXCEPTION: main
09-01 05:08:02.617: E/AndroidRuntime(15718): java.lang.NullPointerException
09-01 05:08:02.617: E/AndroidRuntime(15718): at jlab.creativePainter.ColorPickerView.onDraw(ColorPickerView.java:195)
09-01 05:08:02.617: E/AndroidRuntime(15718): at android.view.View.draw(View.java:13458)
09-01 05:08:02.617: E/AndroidRuntime(15718): at jlab.creativePainter.CreativePainterActivity.onOptionsItemSelected(CreativePainterActivity.java:228)
...
我认为错误可能由以下声明发生
switch (item.getItemId()) {
case COLOR_MENU_ID:
//new ColorPickerDialog(this, this, mPaint.getColor()).show();
**new ColorPickerView(this).draw(vw.mCanvas);**
return true;
我该如何解决?
答案 0 :(得分:1)
如果我在ColorPickerView中理解正确,则有方法onDraw:
@Override
protected void onDraw(Canvas canvas) {
if (mDrawingRect.width() <= 0 || mDrawingRect.height() <= 0) {
return;
}
drawSatValPanel(canvas);
drawHuePanel(canvas);
drawAlphaPanel(canvas);
}
正如您所看到的,有mDrawingRect对象(他为null)。他在onSizeChanged初始化
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mDrawingRect = new RectF();
mDrawingRect.left = mDrawingOffset + getPaddingLeft();
mDrawingRect.right = w - mDrawingOffset - getPaddingRight();
mDrawingRect.top = mDrawingOffset + getPaddingTop();
mDrawingRect.bottom = h - mDrawingOffset - getPaddingBottom();
setUpSatValRect();
setUpHueRect();
setUpAlphaRect();
}
因此,如果在向布局添加视图之前立即调用draw(),则不会调用onSizeChanged。在构造函数中初始化mDrawindRect,或者在添加到布局之前不要调用draw()方法。