我有一个自定义视图,我必须用手指绘制(就像在FingerPaint示例中一样)。
我尝试通过制作一个LinearLayout并向其添加所需的视图,以编程方式在此视图下方添加一个按钮。
但是,我看不到按钮本身。
我理解这是由于我实现了onMeasure而导致的问题,因为如果我恢复为默认值,则会显示按钮,但视图不会显示。
MainActivity Class
public class FingerPaintActivity extends Activity implements ColorPickerDialog.OnColorChangedListener
{
MyView mv;
AlertDialog dialog;
ArrayList<Integer> colorList;
private LinearLayout.LayoutParams params;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
LinearLayout layout = new LinearLayout(this);
params = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
layout.setLayoutParams(params);
Button submitButton = new Button(this);
params = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
submitButton.setLayoutParams(params);
submitButton.setGravity(Gravity.CENTER);
submitButton.setText("Done");
mv = new MyView(this);
params = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
mv.setLayoutParams(params);
mv.setDrawingCacheEnabled(true);
mv.setAdjustViewBounds(true);
layout.addView(mv);
layout.addView(submitButton);
setContentView(layout);
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(6);
}
private Paint mPaint;
@Override
public void colorChanged(int color)
{
mPaint.setColor(color);
Log.i("COLOR", color + "");
}
public class MyView extends ImageView
{
private Bitmap mBitmap, originalBitmap, originalNonResizedBitmap;
private Canvas mCanvas;
private Path mPath;
private Paint mBitmapPaint;
Context context;
private BitmapFactory.Options options = new BitmapFactory.Options();
public MyView(Context c)
{
super(c);
context = c;
mPath = new Path();
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
options.inMutable = true;
originalNonResizedBitmap = Bitmap.createBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.amsler_boundary, options));
originalNonResizedBitmap = getResizedBitmap(originalNonResizedBitmap);
originalBitmap = originalNonResizedBitmap.copy(Bitmap.Config.ARGB_8888, true);
mBitmap = originalBitmap.copy(Bitmap.Config.ARGB_8888, true);
mCanvas = new Canvas(mBitmap);
}
public MyView(Context context, AttributeSet attrs)
{
super(context, attrs);
}
@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);
// mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
}
@Override
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
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();
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SCREEN));
// mPaint.setMaskFilter(null);
}
@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();
// Need to set null or clogs the Paint
mPaint.setXfermode(null);
invalidate();
break;
}
return true;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
int newWidthMeasure = MeasureSpec.makeMeasureSpec(mBitmap.getWidth(), MeasureSpec.EXACTLY);
int newHeightMeasure = MeasureSpec.makeMeasureSpec(mBitmap.getHeight(), MeasureSpec.EXACTLY);
setMeasuredDimension(newWidthMeasure, newHeightMeasure);
// super.setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec),
// MeasureSpec.getSize(heightMeasureSpec));
// super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
public void clearScreen()
{
mCanvas.drawColor(Color.TRANSPARENT);
mCanvas.drawBitmap(originalBitmap, 0, 0, mBitmapPaint);
invalidate();
}
public Rect getCoordinateRect()
{
return new Rect(0, 0, mBitmap.getWidth(), mBitmap.getHeight());
}
}
public Bitmap getResizedBitmap(Bitmap bm)
{
int width = bm.getWidth();
int height = bm.getHeight();
WindowManager wm = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int newDimen = size.x;
float scaleWidth = ((float) newDimen) / width;
float scaleHeight = ((float) newDimen) / height;
Matrix matrix = new Matrix();
matrix.postScale(scaleWidth, scaleHeight);
Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, false);
return resizedBitmap;
}
这是上面代码的布局: