I need to denote progress by the border of view.
E.g. Initially view will not have any border at all, when 50% progress is reached, only 50% of view will get border.Find the attached image.
I did lot of googling but no luck.The view I used is textview.
Edited
The following code, cuts the edges of bitmap.
What I've done in this code is -
1. Bg is set to Black Hexagon
2. And I've taken hollow green bordered hexagon & revealing this hollow hexagon, so that it will look like border is getting accumulated.
public class MyView extends View {
private Bitmap mBitmap;
private Paint mPaint;
private RectF mOval;
private float mAngle = 135;
private Paint mTextPaint;
private Bitmap bgBitmap;
public MyView(Context context) {
super(context);
doInit();
}
/**
* #param context
* #param attrs
* #param defStyleAttr
*/
public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
// TODO Auto-generated constructor stub
doInit();
}
/**
* #param context
* #param attrs
*/
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
doInit();
}
private void doInit() {
// use your bitmap insted of R.drawable.ic_launcher
mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.hexagon_border);
bgBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.view_message_small_hexagon);
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mOval = new RectF();
mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mTextPaint.setTextSize(48);
mTextPaint.setTextAlign(Align.CENTER);
mTextPaint.setColor(0xffffaa00);
mTextPaint.setTypeface(Typeface.DEFAULT_BOLD);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
Matrix m = new Matrix();
RectF src = new RectF(0, 0, mBitmap.getWidth(), mBitmap.getHeight());
RectF dst = new RectF(0, 0, w, h);
m.setRectToRect(src, dst, ScaleToFit.CENTER);
Shader shader = new BitmapShader(mBitmap, TileMode.CLAMP, TileMode.CLAMP);
shader.setLocalMatrix(m);
mPaint.setShader(shader);
m.mapRect(mOval, src);
}
#Override
protected void onDraw(Canvas canvas) {
//canvas.drawColor(0xff0000aa);
Matrix matrix = new Matrix();
canvas.drawBitmap(bgBitmap, matrix, null);
canvas.drawArc(mOval, -90, mAngle, true, mPaint);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
float w2 = getWidth() / 2f;
float h2 = getHeight() / 2f;
mAngle = (float) Math.toDegrees(Math.atan2(event.getY() - h2, event.getX() - w2));
mAngle += 90 + 360;
mAngle %= 360;
invalidate();
return true;
}
}
try this SO answer:
public class MyView extends View {
private Bitmap mBitmap;
private Paint mPaint;
private RectF mOval;
private float mAngle = 135;
private Paint mTextPaint;
public MyView(Context context) {
super(context);
// use your bitmap insted of R.drawable.ic_launcher
mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mOval = new RectF();
mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mTextPaint.setTextSize(48);
mTextPaint.setTextAlign(Align.CENTER);
mTextPaint.setColor(0xffffaa00);
mTextPaint.setTypeface(Typeface.DEFAULT_BOLD);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
Matrix m = new Matrix();
RectF src = new RectF(0, 0, mBitmap.getWidth(), mBitmap.getHeight());
RectF dst = new RectF(0, 0, w, h);
m.setRectToRect(src, dst, ScaleToFit.CENTER);
Shader shader = new BitmapShader(mBitmap, TileMode.CLAMP, TileMode.CLAMP);
shader.setLocalMatrix(m);
mPaint.setShader(shader);
m.mapRect(mOval, src);
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(0xff0000aa);
canvas.drawArc(mOval, -90, mAngle, true, mPaint);
canvas.drawText("click me", getWidth() / 2, getHeight() / 2, mTextPaint);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
float w2 = getWidth() / 2f;
float h2 = getHeight() / 2f;
mAngle = (float) Math.toDegrees(Math.atan2(event.getY() - h2, event.getX() - w2));
mAngle += 90 + 360;
mAngle %= 360;
invalidate();
return true;
}
}
Getting a good circular progress spinner is difficult in itself. The ProgressWheel is a good custom View that does this. You should be able to modify the ProgressWheel's onDraw() class to do something very similar to what you want.
Related
Im trying to draw an arc in android, between two textView using drawArc. My requirement is to achieve an arc as shown in the image which is correct arc shape.
But when i tried ,i'm not getting an perfect arc shape and i got the arc which is of semi ovalshaped.
Here is my code snippet:
public class ArcView extends View {
final RectF oval = new RectF();
Path myPath = new Path();
Paint paint;
float left, top, right, bottom;
public FlightStatusArcView(Context context) {
super(context);
}
public FlightStatusArcView(Context context, AttributeSet attrs) {
super(context, attrs);
init(attrs);
}
public FlightStatusArcView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(attrs);
}
private void init(AttributeSet set) {
if (set == null)
return;
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
public void setArcProperties(float l, float t, float r, float b) {
left = l;
top = t;
right = r;
bottom = b;
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
oval.set(left, top, right, bottom);
paint.setColor(Color.WHITE);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(5f);
canvas.drawArc(oval, 180f, 180f, false, paint);
drawArrow(canvas);
}
private void drawArrow(Canvas canvas) {
canvas.save();
Paint p = new Paint();
p.setColor(Color.WHITE);
p.setStyle(Paint.Style.FILL);
p.setStrokeWidth(4f);
float startX = oval.left + 20;
float startY = oval.top + (oval.centerY() - oval.top)/ 2;
Path path = new Path();
path.moveTo(startX, startY-20);
path.lineTo(startX + 20, startY + 20);
path.lineTo(startX + 30, startY -17);
path.close();
canvas.drawPath(path, p);
canvas.restore();
}
}
Please help how to achieve the perfect arc shape using the canvas apis.
You could use a Path together with quadTo or cubicTo to draw a curve like this. This will allow you to draw quadratic or cubic bezier curves. For instance, a cubic bezier curve with two identical control points (x2, y2) is constructed like this:
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
paint.setColor(Color.BLACK);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(5f);
Path p = new Path();
float x1 = 100;
float y1 = 256;
float x2 = 400;
float y2 = 32;
float x3 = 700;
float y3 = 256;
p.moveTo(x1, y1);
p.cubicTo(x2, y2, x2, y2, x3, y3);
canvas.drawPath(p, paint);
drawArrow(canvas);
}
This is the result:
You can find more information on cubicTo and quadTo in the official documentation
I'm trying to get the text view '2' (in black) to appear in the centre of my view but for some reason it won't appear. Does anyone know what's wrong here and how this error can be fixed? Is there way of showing it and changing the colour of it programmatically rather than using XML?
XML
<com.apptacularapps.car.RectangleTextView
android:layout_width="120dp"
android:layout_height="40dp"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:text="2"
android:gravity="center"
android:background="#808080"/>
Java
public class RectangleTextView extends View {
Paint paint;
private TextPaint mTextPaint;
public RectangleTextView(Context context) {
super(context);
init();
}
public RectangleTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public RectangleTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
paint = new Paint();
paint.setColor(Color.RED);
paint.setStrokeWidth(1); // convert to dp?
paint.setStyle(Paint.Style.STROKE); // delete line for filled rect
mTextPaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG);
mTextPaint.setTextAlign(Paint.Align.CENTER);
mTextPaint.setColor(Color.BLACK);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawText("2", 0, 0, paint);
paint.setTextSize(20);
int w = canvas.getWidth();
int h = canvas.getHeight();
int rectWidth = w/5;
int space = w/15;
int topRectHeight = getPaddingTop();
int bottomRectHeight = getPaddingBottom();
for (int i = 0; i < 4; i++) {
int left = i * (rectWidth + space);
int right = left + rectWidth;
Rect rect = new Rect(left, 0, right, topRectHeight);
canvas.drawRect(rect, paint);
Rect rect2 = new Rect(left, h - bottomRectHeight, right, h);
canvas.drawRect(rect2, paint);
}
}
}
You do not have a paint object that defines how your text will be drawn and neither have you called canvas.drawText() in your onDraw() method. Do it this way:
private TextPaint mTextPaint;
private void init() {
mTextPaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG);
// You can tweak the appearance of the textpaint here
mTextPaint.setTextAlign(Align.CENTER);
mTextPaint.setColor(color);
}
#Override
public void onDraw() {
super.onDraw()
// You can tweak the positioning of the text here
canvas.drawText("2", 25, 25, mTextPaint);
}
I'm searching how I can change style of pen. I would like to get something like array of pixels. Not a stroke. When user will touch the screen, on the canvas appear a black square.
My code:
public class DrawingView extends View {
private Bitmap cacheBitmap;
private Canvas cacheCanvas;
private Paint paint;
private Paint BitmapPaint;
private Path path;
private int height;
private int width;
/** Last saved X-coordinate */
private float pX;
/** Last saved Y-coordinate*/
private float pY;
private int counterxy=0;
/** Initial color */
private int paintColor = Color.BLACK;
private static Paint.Style paintStyle = Paint.Style.STROKE;
/** Paint Point size */
private static int paintWidth = 8;
private Canvas canvas;
private DrawingViewInterface mInterface;
/** get the height and width */
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
height = h;
width = w;
init();
}
public void setViewListener(DrawingViewInterface interface1) {
mInterface = interface1;
}
private void init(){
cacheBitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);
cacheCanvas = new Canvas(cacheBitmap);
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
path = new Path();
BitmapPaint = new Paint();
updatePaint();
}
private void updatePaint(){
paint.setColor(paintColor);
paint.setStyle(paintStyle);
paint.setStrokeWidth(paintWidth);
}
public DrawingView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public DrawingView(Context context){
super(context);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
path.moveTo(event.getX(), event.getY());
pX = event.getX();
pY = event.getY();
break;
case MotionEvent.ACTION_MOVE:
path.quadTo(pX, pY, event.getX(), event.getY());
pX = event.getX();
pY = event.getY();
counterxy++;
mInterface.onActionFinished(pX, pY, counterxy); // Wyslanie wspolrzednych do MainActivity
break;
case MotionEvent.ACTION_UP:
cacheCanvas.drawPath(path, paint);
path.reset();
break;
}
invalidate();
return true;
}
#Override
protected void onDraw(Canvas canvas) {
this.canvas = canvas;
BitmapPaint = new Paint();
canvas.drawBitmap(cacheBitmap, 0,0, BitmapPaint);
canvas.drawPath(path, paint);
}
}
Paint.setStrokeWidth may be enough if all you want is a rectangle. Otherwise you may want setPathEffect(), although for something complex you may need to create your own PathEffect.
I need to scale a graph to a desired fit, now I've been looking into it but what I want to know is when I should scale the graph, whether I scale it in the GraphView class, of in the class that calls the graph. See code below:
GraphView:
public final class GraphView extends View {
private static final float SCALE = 0.008f; // map (min,max) to ( 0, 1)
private static final float WIDTH = 0.02f; // map (min,max) to ( 0, 1)
private final static String TAG = "HearingTest";
ArrayList<EarSrt> mPoints;
// drawing tools
private RectF rimRect;
private RectF rimRectTop;
private RectF rimRectBottom;
private float[] centreLine;
private RectF topSideBar;
private RectF bottomSideBar;
private Paint rimPaintTop;
private Paint rimPaintBottom;
private Paint outerRimPaint;
private Paint centreLinePaint;
private Paint topSideBarPaint;
private Paint bottomSideBarPaint;
private Paint titlePaint;
private Paint keyPaint;
private Paint correctPointPaint;
private Paint incorrectPointPaint;
private Paint linePaint;
private Paint pointOutlinePaint;
private Paint averagePaint;
private Paint backgroundPaint;
// end drawing tools
private Bitmap background; // holds the cached static part
private float mAverage;
public GraphView(Context context) {
super(context);
init();
}
public GraphView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public GraphView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
initDrawingTools();
}
private String getTitle() {
return getContext().getString(R.string.Normal_hearing);
}
private void initDrawingTools() {
rimRect = new RectF(0.0f, 0.0f, 1.0f, 1.0f);
rimRectTop = new RectF(0.0f, 0.5f, 1.0f, 1.0f);
rimRectBottom = new RectF(0.0f, 0.0f, 1.0f, 0.5f);
centreLine = new float[4];
centreLine[0]=0.0f;
centreLine[1]=0.5f;
centreLine[2]=1.0f;
centreLine[3]=0.5f;
topSideBar = new RectF(0.95f, 0.5f, 1.0f, 1.0f);
bottomSideBar = new RectF(0.95f, 0.0f, 1.0f, 0.5f);
// the linear gradient is a bit skewed for realism
rimPaintTop = new Paint();
rimPaintTop.setFlags(Paint.ANTI_ALIAS_FLAG);
rimPaintTop.setShader(new LinearGradient(0.40f, 0.0f, 0.60f, 1.0f,
0xff9ea3ac,
0xffc0c2c6,
TileMode.CLAMP));
rimPaintBottom = new Paint();
rimPaintBottom.setFlags(Paint.ANTI_ALIAS_FLAG);
rimPaintBottom.setShader(new LinearGradient(0.40f, 0.0f, 0.60f, 1.0f,
0xffc5cbbd,
0xff3d4649,
TileMode.CLAMP));
outerRimPaint = new Paint();
outerRimPaint.setAntiAlias(true);
outerRimPaint.setStyle(Paint.Style.STROKE);
outerRimPaint.setColor(Color.argb(0x4f, 0x33, 0x36, 0x33));
outerRimPaint.setStrokeWidth(0.001f);
centreLinePaint = new Paint();
centreLinePaint.setStyle(Paint.Style.STROKE);
centreLinePaint.setColor(0xff90cc38);
centreLinePaint.setAntiAlias(true);
centreLinePaint.setStrokeWidth(0.02f);
topSideBarPaint = new Paint();
topSideBarPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
topSideBarPaint.setShader(new LinearGradient(0.40f, 0.0f, 0.60f, 1.0f,
0xffc5cbbd,
0xff3d4649,
TileMode.CLAMP));
bottomSideBarPaint = new Paint();
bottomSideBarPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
bottomSideBarPaint.setShader(new LinearGradient(0.40f, 0.0f, 0.60f, 1.0f,
0xff4c9b3e,
0xffa0dd61,
TileMode.CLAMP));
titlePaint = new Paint();
titlePaint.setColor(0xffffffff);
titlePaint.setAntiAlias(true);
titlePaint.setTypeface(Typeface.DEFAULT_BOLD);
titlePaint.setTextAlign(Paint.Align.LEFT);
titlePaint.setTextSize(0.05f);
titlePaint.setTextScaleX(0.8f);
titlePaint.setLinearText(true);
keyPaint = new Paint();
keyPaint.setColor(0xff000000);
keyPaint.setAntiAlias(true);
keyPaint.setTypeface(Typeface.DEFAULT_BOLD);
keyPaint.setTextAlign(Paint.Align.LEFT);
keyPaint.setTextSize(0.05f);
keyPaint.setTextScaleX(0.8f);
keyPaint.setLinearText(true);
backgroundPaint = new Paint();
backgroundPaint.setFilterBitmap(true);
backgroundPaint.setColor(0xff000000);
linePaint = new Paint();
linePaint.setColor(0xffffffff);
linePaint.setStrokeWidth(0);
averagePaint = new Paint();
averagePaint.setColor(0xff000000);
averagePaint.setStyle(Paint.Style.FILL);
correctPointPaint = new Paint();
correctPointPaint.setColor(0xff90cc38);
correctPointPaint.setStyle(Paint.Style.FILL);
incorrectPointPaint = new Paint();
incorrectPointPaint.setColor(0xffb1b3ba);
correctPointPaint.setStyle(Paint.Style.FILL);
pointOutlinePaint = new Paint();
pointOutlinePaint.setStyle(Paint.Style.STROKE);
pointOutlinePaint.setColor(0xffffffff);
pointOutlinePaint.setAntiAlias(true);
pointOutlinePaint.setStrokeWidth(0.0f);
}
private void drawRim(Canvas canvas) {
// first, draw the metallic body
canvas.drawRect(rimRectTop, rimPaintTop);
canvas.drawRect(rimRectBottom, rimPaintBottom);
// now the outer rim circle
canvas.drawRect(rimRect, outerRimPaint);
// Draw middleline
canvas.drawLines(centreLine, centreLinePaint);
// Draw sidebars
canvas.drawRect(topSideBar, topSideBarPaint);
canvas.drawRect(bottomSideBar, bottomSideBarPaint);
}
public void setPoints( ArrayList<EarSrt> aPoints){
mPoints = aPoints;
}
private void drawTitle(Canvas canvas) {
String title = getTitle();
canvas.drawText(title, 0.1f, 0.1f, titlePaint);
}
private void drawBackground(Canvas canvas) {
if (background == null) {
} else {
canvas.drawBitmap(background, 0, 0, backgroundPaint);
}
}
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// We purposely disregard child measurements because act as a
// wrapper to a SurfaceView that centers the camera preview instead
// of stretching it.
final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);
final int height = (int)(width * 0.8f);
setMeasuredDimension(width, height);
}
#Override
protected void onDraw(Canvas canvas) {
drawBackground(canvas);
canvas.restore();
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
regenerateBackground();
}
private void regenerateBackground() {
// free the old bitmap
if (background != null) {
background.recycle();
}
background = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
Canvas backgroundCanvas = new Canvas(background);
float scaleWidth = (float) getWidth();
float scaleHeight = (float) getHeight();
backgroundCanvas.scale(scaleWidth, scaleHeight/1.23f);
drawRim(backgroundCanvas);
drawTitle(backgroundCanvas);
drawPoints(backgroundCanvas);
drawKey(backgroundCanvas);
}
private void drawPoints(Canvas canvas) {
float gap = 1.0f/((float)mPoints.size()+2);
// Iterate though the points twice, once to
// draw the line and one to draw the points
// doesn't appear to be the most efficient
// method, but calculations of point size etc
// Draw line
int count = 1;
float prev_x = 0.0f;
float prev_y = 0.0f;
for ( EarSrt vo : mPoints){
float y_pos = 0.5f + 2*( vo.getSrt() - 24.0f)*SCALE;
float x_pos = gap*count;
if ( count != 1 ){
canvas.drawLine(prev_x, prev_y, x_pos, y_pos, linePaint);
}
count++;
prev_x = x_pos;
prev_y = y_pos;
}
// draw points
count = 1;
for ( EarSrt vo : mPoints){
float y_pos = 0.5f + 2*( vo.getSrt() - 24.0f)*SCALE;
float x_pos = gap*count;
count++;
RectF rect = new RectF(x_pos - WIDTH, y_pos - WIDTH, x_pos + WIDTH, y_pos + WIDTH);
if ( vo.isCorrect() ) {
canvas.drawRect(rect, correctPointPaint);
} else {
canvas.drawRect(rect, incorrectPointPaint);
}
canvas.drawRect(rect, pointOutlinePaint);
}
// Plot average line
float yAverage = 0.5f + 2*( mAverage - 24.0f)*SCALE;
RectF averageRect = new RectF(0.95f, yAverage - WIDTH/2.0f, 1.0f, yAverage + WIDTH/2.0f);
canvas.drawRect(averageRect, averagePaint);
}
private void drawKey(Canvas canvas) {
float rightEdge = 0.05f;
float leftEdge = 0.05f + 4 * WIDTH;
//float leftEdge = WIDTH;
// Example correct square
RectF rect = new RectF(rightEdge, 1.1f - WIDTH, rightEdge + 2 * WIDTH, 1.1f + WIDTH);
canvas.drawRect(rect, correctPointPaint);
canvas.drawRect(rect, pointOutlinePaint);
String correctResults = getContext().getString(R.string.Correct_results);
canvas.drawText(correctResults, leftEdge, 1.1f + WIDTH, keyPaint);
// Test result line
RectF averageRect = new RectF(rightEdge, 1.2f - WIDTH/2.0f, rightEdge + 2 * WIDTH, 1.2f + WIDTH/2.0f);
canvas.drawRect(averageRect, averagePaint);
String testResults = getContext().getString(R.string.Your_test_result);
canvas.drawText(testResults, leftEdge, 1.2f + WIDTH/2.0f, keyPaint);
}
public void setAverage(float aAverage) {
mAverage = aAverage;
}
}
Method calling GraphView:
public class RightEarResults extends SherlockFragment{
private Button btn;
private TextView txt;
private final static String TAG = "HearingTest";
String resultsString;
private ArrayList<EarSrt> rightAnswerList;
float rightAverage;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.result_tab, container, false);
btn = (Button) rootView.findViewById(R.id.locate_btn);
resultsString = getArguments() != null ? getArguments().getString("results") : "No data";
rightAnswerList = getArguments().getParcelableArrayList("graph");
rightAverage = getArguments().getFloat("average");
txt = (TextView) rootView.findViewById(R.id.results_text);
GraphView graphView = (GraphView)rootView.findViewById(R.id.graphview);
graphView.setPoints(rightAnswerList);
graphView.setAverage(rightAverage);
txt.setText(resultsString);
btn.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent(getActivity(), MapActivity.class);
startActivity(intent);
}
});
return rootView;
}
}
Graph Screenshot:
I need to scale it down a lot as you can see because it cuts off loads of information!
Basically, do I scale the Graph in the GraphView class and where in that class would I scale it? Or do I scale it in my RightEarResults class? Any help would be gladly appreciated. Thanks
I have been developing the application for drawing. I have following code for main activity:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
Display display = getWindow().getWindowManager().getDefaultDisplay();
mMainView = new MyView(this, display.getWidth(), display.getHeight());
setContentView(mMainView);
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);
}
And code for my custom view for drawing:
public class MyView extends View {
private static final float TOUCH_TOLERANCE = 4;
private static final float MINP = 0.25f;
private static final float MAXP = 0.75f;
private Bitmap mBitmap;
private Canvas mCanvas;
private Path mPath;
private Paint mBitmapPaint;
private float mX, mY;
public MyView(Context context, int width, int height) {
super(context);
this.setDrawingCacheEnabled(true);
mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
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);
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(0xFF000000);
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
canvas.drawPath(mPath, mPaint);
}
public void clearView() {
mBitmap.eraseColor(Color.TRANSPARENT);
}
public Bitmap getState() {
return mBitmap;
}
private void touchStart(float x, float y) {
mPath.reset();
mPath.moveTo(x, y);
mX = x;
mY = y;
}
private void touchMove(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 touchUp() {
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:
touchStart(x, y);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
touchMove(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP:
touchUp();
invalidate();
break;
}
return true;
}
}
So, because if I try to save resulted bitmap as jpeg file using bitmap compress then all is good, but if I try to save as png file I will get file with transparent background (white) and red picture. I need that I can save using JPEG/PNG with black background and red picture. Code for saving is good, don't worry. Thank you.
you can draw a black rectangle on the bitmap, like so:
Bitmap myBitmap = Bitmap.createBitmap(width, height, ...);
Canvas mCanvas = new Canvas(myBitmap);
// create a black rectangle
final int color = 0xffffffff;
final Paint p1 = new Paint();
final Rect rect = new Rect(0, 0, width, height);
final RectF rectF = new RectF(rect);
// draw it to the canvas
mCanvas.drawARGB(0, 0, 0, 0);
p1.setColor(color);
mCanvas.drawRect(rectF, p1);
That should force a black background, and you can overlay additional bitmaps on the canvas, and finally use myBitmap to export as png.
I think the black background you have now is a jpeg default, since it does not have transparency.