I have a canvas drawing, I am going to use onTouch to change the colour of the drawing. It is a house, and on touching the screen once it will change to a darker shade. I have only been told that I will need to move the method calls into dayTime and nightTime, switchable by boolean, and that the text daytime and night time has to be rendered on the image accordingly.
Below is the code I used to draw the image. Any help on how to finish this would be appreciated:
/*
* DrawView.java
*/
public class DrawView extends View implements OnTouchListener
{
private Paint backgroundPaint = new Paint();
private Paint drawPaint_grass = new Paint();
private Paint drawPaint_door = new Paint();
private Paint drawPaint_house = new Paint();
private Paint drawPaint_roof = new Paint();
private Paint circlePaint = new Paint();
private Paint circlePaint_sun = new Paint();
private Paint textPaint = new Paint();
private Paint path = new Paint();
private Path trianglePath;
private float sx, sy;
public DrawView(Context context)
{
super(context);
setFocusable(true);
setFocusableInTouchMode(true);
backgroundPaint.setColor(Color.rgb(135,250,205));
backgroundPaint.setAntiAlias(true);
backgroundPaint.setStyle(Style.FILL);
drawPaint_grass.setColor(Color.rgb(124, 252, 0));
drawPaint_grass.setStyle(Style.FILL);
drawPaint_door.setColor(Color.RED);
drawPaint_door.setStyle(Style.FILL);
//drawPaint_.setColor(Color.RED);
//drawPaint_door.setStyle(Style.FILL);
drawPaint_house.setColor(Color.rgb(205, 133, 63));
drawPaint_house.setStyle(Style.FILL);
drawPaint_roof.setColor(Color.rgb(160, 82, 45));
drawPaint_roof.setStyle(Style.FILL);
circlePaint_sun.setColor(Color.rgb(255, 255, 0));
circlePaint_sun.setStyle(Style.FILL);
trianglePath = new Path();
trianglePath.moveTo(70, 300); // starting point
trianglePath.lineTo(170,250); // 1st vertix
trianglePath.lineTo(270, 300); // 2nd vertix
trianglePath.lineTo(70, 300); // 3rd vertix and close
//path.moveTo(getRight()/2, getLeft()/2, getTop()/2, getBottom()/2);
textPaint.setColor(Color.BLACK);
textPaint.setStyle(Style.FILL);
//255, 255, 240
circlePaint.setColor(Color.rgb(211, 211, 211));
circlePaint.setStyle(Style.FILL);
this.setOnTouchListener(this);
}
#Override
public void onDraw(Canvas canvas)
{
//canvas.drawPath(path, paint);
//canvas.drawPath(path, paint);
// Draw white background
canvas.drawRect(this.getLeft(), this.getTop(), this.getRight(), this.getBottom(), backgroundPaint);
//draw a rectangle with blue paint
canvas.drawRect(0,400, 540,600, drawPaint_grass);
canvas.drawRect(100,400, 240,300, drawPaint_house);
canvas.drawRect(150,400, 190,335, drawPaint_door);
canvas.drawPath(trianglePath, drawPaint_roof);
//draw text with green paint
canvas.drawText("Muhibur Rahim", 232, 565, textPaint);
//draw a circle with red paint with the touch coordinates
canvas.drawCircle(sx-30,sy-30, 3, circlePaint);
canvas.drawCircle(80, 80, 30, circlePaint_sun);
}
public boolean onTouch(View v, MotionEvent event)
{
//update the coordinates for the OnDraw method above, with wherever we touch
sx = event.getX();
sy = event.getY();
invalidate();
return true;
}
}
I was thinking of putting the colouring part of code (circlePaint_sun.setColor(Color.rgb(255, 255, 0)) into methods (eg. static void dayTime() under private Drawview(Context, Context), and then assigning the two methods values 0 and 1, and on touch or click (i think onclick would be better) a counter increases and the values alternate between 0 and 1. However I am not sure how to use that in a code after repeated tries, any help is appreciated...
Add a private boolean dark = false; to your variables.
In your onDraw method, add something like
if (dark) backgroundPaint.setColor(Color.rgb(0,0,0));
else backgroundPaint.setColor(Color.rgb(255,255,255));
before you draw your background.
Change your boolean inside the onTouch method:
if (event.getAction() == MotionEvent.ACTION_DOWN) {
dark = !dark;
DrawView();
}
Related
I'm new to Android and I want to draw points on top of my view using a canvas, but when my OnDrawListener is hit, nothing is drawn on my view and I can't figure out why.
new OnDrawListener() {
#Override
public void onLayerDrawn(Canvas canvas, float pageWidth, float pageHeight, int displayedPage) {
canvas.drawPoint(pageHeight /2, pageHeight /2, paint);
view.draw(canvas);
}
}
Here's how I setup my paint :
paint.setColor(Color.RED);
paint.setStyle(Paint.Style.FILL);
paint.setStrokeWidth(3);
Thank you.
UPDATE :
Here you can find my full class :
https://pastebin.com/ehB5NamS
I'm currently trying to put in a color from my colors resources xml into my app using ContextCompact.getColor() but for some reason I cannot pass in a single version of context.
I'm using a class as a handler so I am not trying to pass in from an activity. In my activity I can use them, but in my class I cannot pass in getActivityContext() this etc. Nothing works. What do I do?
Also, I'm adding the color to a canvas so I cannot add the color in in an xml.
canvas.drawColor(Color.BLACK);
Is what I'm currently forced to use. I want to replace it with a color from my xml. ( I'm trying to set the background of the canvas essentially )
full code of my class: (I'm making this app as a "note" app so that I can look back on it for future projects, hence all the comments)
public class GameHandling {
private SurfaceHolder holder;
private Resources resources;
private int screenWidth;
private int screenHeight;
private Ball ball;
private Bat player;
private Bat opponent;
public GameHandling(int width, int height, SurfaceHolder holder, Resources resources){
this.holder = holder;
this.resources = resources;
this.screenWidth = width;
this.screenHeight = height;
this.ball = new Ball(screenWidth, screenHeight, 400, 400);
this.player = new Bat(screenWidth, screenHeight, 0, 0, Bat.Position.LEFT);
this.opponent = new Bat(screenWidth, screenHeight, 0, 0, Bat.Position.RIGHT);
}
// setting the ball images to be drawn
public void inIt(){
Bitmap ballShadow = BitmapFactory.decodeResource(resources, R.mipmap.grey_dot);
Bitmap ballImage = BitmapFactory.decodeResource(resources, R.mipmap.red_dot);
Bitmap batPlayer = BitmapFactory.decodeResource(resources, R.mipmap.bat_player);
Bitmap batOpponent = BitmapFactory.decodeResource(resources, R.mipmap.bat_opponent);
ball.inIt(ballImage, ballShadow, 2, 0);
player.inIt(batPlayer, batPlayer, 0, 0);
opponent.inIt(batOpponent, batOpponent, 0, 0);
}
// calling Balls update method to update the ball
public void update(long elapsed){
ball.update(elapsed);
}
public void draw(){
Canvas canvas = holder.lockCanvas(); // Making a canvas object to draw on - .lockcanvas locks canvas
if(canvas != null) {
// draw in area between locking and unlocking
canvas.drawColor(Color.BLACK);
ball.draw(canvas);
player.draw(canvas);
opponent.draw(canvas);
holder.unlockCanvasAndPost(canvas); //-unlockcanvasandposts unlocks the canvas
}
}
}
Change your constructor to this and use ContextCompat.getColor(context,... pattern.
Wherever you are creating this class (activity/fragment), pass the context calling either getActivity() or getApplicationContext()
new GameHandling( getActivity()/getApplicationContext(), ...)
public GameHandling(Context context, int width, int height, SurfaceHolder holder, Resources resources){
this.context = context;
this.holder = holder;
this.resources = resources;
this.screenWidth = width;
this.screenHeight = height;
this.ball = new Ball(screenWidth, screenHeight, 400, 400);
this.player = new Bat(screenWidth, screenHeight, 0, 0, Bat.Position.LEFT);
this.opponent = new Bat(screenWidth, screenHeight, 0, 0, Bat.Position.RIGHT);
}
I kind of came up with a workaround, I created an image with my desirable color and then used that as the background of the app.
However it is still a workaround, so it doesn't solve my issue
I have problem with animation in android.
My animations working good only on 1080x1920 480dpi display. But i don't know how made app for any display.
If I use method from http://www.i-programmer.info/programming/android/8797-android-adventures-beginning-bitmap-graphics.html?start=4 Animations run, ok but made shadows, so no rewrite display if I write on display something I not delete thise from display.
If I use method. Main activity have one threat
public class UpdateThread implements Runnable {
#Override
public void run() {
while(bez){
try {
myThread.sleep(50);
} catch (Exception ex) {}
MainActivity.this.updateHandler.sendEmptyMessage(0);
}
}
and Class Game who every 50ms do
public void update() {
x += 1;
y += 2;
}
And on draw method in this class
protected void onDraw(Canvas canvas) {
Plocha pozadie = new Plocha(paint, canvas, X0, Y0, vzdialenost);
if (nehra==true) {
paint.setStrokeWidth(13F);
paint.setStyle(Paint.Style.STROKE);
LevelUp(level);
paint.setTypeface(Typeface.DEFAULT_BOLD);
paint.setStyle(Paint.Style.FILL);
pozadie.vypis(paint, canvas, "Score", 100, 100, 6);
pozadie.vypis(paint, canvas, Integer.toString(zasah), 90, 200, 9);
pozadie.vypis(paint, canvas, "Level", 850, 100, 6);
pozadie.vypis(paint, canvas, Integer.toString(level), 850, 200, 8);
pozadie.vypis(paint, canvas, "Clicks", 1080 / 2 - 100, 100, 7);
pozadie.vypis(paint, canvas, Integer.toString(click), 1080 / 2, 200, 9);
}
everything be okay (y) but only one type display.
If use
Bitmap b = Bitmap.createBitmap(1080,
1920,Bitmap.Config.ARGB_8888);
this.canvas = new Canvas(b);
this.canvas.drawColor(Color.WHITE);
this.b=b;
and rewrite some parts of code
application result is these canvas
protected void onDraw( Canvas canvas ) {
I don't know why...
ImageView im=(ImageView)findViewById(R.id.imageView222);
game = new Game(this,im);
setContentView(game);
I think so If I save setContentView(game); to imageview. will be everything okay. But I try and every ideas finish more errors.
I'm sad from...
Thanks from some ideas.
I'm new in Android and I've written the following sample code.
public class Circle extends View {
Paint paint = new Paint();
Path path = new Path();
private static final String s = "Hello world example";
public Circle(Context context) {
super(context);
paint.setColor(Color.BLACK);
paint.setStyle(Style.STROKE);
paint.setStrokeWidth(2);
paint.setAntiAlias(true);
paint.setTextSize(30);
}
public void onDraw(Canvas c) {
path.addCircle(getWidth()/2, getHeight()/2, 180, Direction.CW);
c.drawTextOnPath(s, path, 0, 10, paint);
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
}
The Canvas.drawTextOnPath() is displaying the the text beginning from the right side (I mean positive X-axis). I want to display the text from top in a clock-wise. I want to change the starting position of the text. I'm confused about Android Canvas.translate() and Canvas.scale(). Or should I use Canvas.rotate()? I've pasted the output below for clear understanding my question.
I want to display the output in this form.
I've finally fixed my Canvas issue by adding the Canvas.rotate(float degrees, float px, float py) in my code before applying and Canvas methods. Below is the code.
public class Circle extends View {
Paint paint = new Paint();
Path path = new Path();
private static final String s = "Hello world example";
public Circle(Context context) {
super(context);
paint.setColor(Color.BLACK);
paint.setStyle(Style.STROKE);
paint.setStrokeWidth(2);
paint.setAntiAlias(true);
paint.setTextSize(30);
}
public void onDraw(Canvas c) {
c.rotate(-90, getWidth()/2, getHeight()/2);
path.addCircle(getWidth()/2, getHeight()/2, 180, Direction.CW);
c.drawTextOnPath(s, path, 0, 10, paint);
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
}
I tried Canvas.rotate(float degrees) before but didn't worked. However, Canvas.rotate(float degrees, float px, float py) worked!
Instead of circle, arc can be used:
Path path = new Path();
RectF rect = new RectF(width/2 - radius, height/2 - radius, width/2 + radius, height/2 + radius);
path.addArc(rect 270, 270);
canvas.drawTextOnPath(msg., path, 0, 0, paint);
The path can be translated, rotated and scaled by using Matrix.
For example, the above code will draw the text starting from the first quadrant, i.e, from (y, 0). To start the drawing from (-y, 0) in clockwise direction,
Path path = new Path();
RectF rect = new RectF(width/2 - radius, height/2 - radius, width/2 + radius, height/2 + radius);
Matrix matrix = new Matrix();
matrix.setScale(-1, -1, width/2, height/2);
path.addArc(rect, 270, 270);
path.transform(matrix);
canvas.drawTextOnPath(msg, path, 0, 0, paint);
How do I find the coordinates of the screen? I know e.g. a phone would have say a 960 x 540 resolution, but in the emulators some of the edges are not filled if I draw a shape to that resolution. Is there a way around this?
For the colour of the rectangle, it is seen there are two rectangles, and two of them have the same colour despite giving two separate colours for drawPaint. Just setting a new variable e.g. drawPaint2 returns errors. How to change the colour of both?
How to use the path function in the canvas. E.g. to draw a triangle? I have included my attempt in the code but it doesn't display a triangle.
public class DrawView extends View implements OnTouchListener
{
private Paint backgroundPaint = new Paint();
private Paint drawPaint = new Paint();
private Paint circlePaint = new Paint();
private Paint textPaint = new Paint();
private Paint path = new Paint();
private float sx, sy;
public DrawView(Context context)
{
super(context);
setFocusable(true);
setFocusableInTouchMode(true);
backgroundPaint.setColor(Color.CYAN);
backgroundPaint.setAntiAlias(true);
backgroundPaint.setStyle(Style.FILL);
drawPaint.setColor(Color.WHITE);
drawPaint.setStyle(Style.FILL);
circlePaint.setColor(Color.DKGRAY);
circlePaint.setStyle(Style.FILL);
textPaint.setColor(Color.WHITE);
textPaint.setStyle(Style.FILL);
drawPaint.setColor(Color.GREEN);
drawPaint.setStyle(Style.FILL);
circlePaint.setColor(Color.RED);
circlePaint.setStyle(Style.FILL);
path.setColor(android.graphics.Color.RED);
path.setStyle(Paint.Style.FILL);
Path path = new Path();
path.moveTo(1, 1);
path.lineTo(20, 50);
path.moveTo(20, 50);
path.lineTo(100, 100);
path.moveTo(100, 100);
path.lineTo(1, 1);
path.close();
this.setOnTouchListener(this);
}
#Override
public void onDraw(Canvas canvas)
{
//canvas.drawPath(path, paint); <-- error
// to draw background
canvas.drawRect(this.getLeft(), this.getTop(), this.getRight(), this.getBottom(), backgroundPaint);
//to draw two rectangle with blue and green paint
canvas.drawRect(100,100, 340,540, drawPaint);
canvas.drawRect(00,00, 120,80, drawPaint);
//draw text with paint
canvas.drawText("Hello Dear Leader!", 110, 160, textPaint);
//draw a circle with green paint with the touch coordinates
canvas.drawCircle(sx-30,sy-30, 30, circlePaint);
//draw a circle with red paint with the touch coordinates
canvas.drawCircle(sx-80, sy-80, 10, circlePaint);
}
public boolean onTouch(View v, MotionEvent event)
{
//update the coordinates for the OnDraw method above, with wherever we touch
sx = event.getX();
sy = event.getY();
invalidate();
return true;
}
}
for the size you can easily call canvas.getWidth() and canvas.getHeight() and do all your values a percentage of those. Do never assume a constant!
You need to use two separate Paints to use two different colors. And remember that each paint is an object that needs initialisation.
// objects
private Paint drawPaint_WH = new Paint();
private Paint drawPaint_GR = new Paint();
// during construction
drawPaint_WH.setColor(Color.WHITE);
drawPaint_WH.setStyle(Style.FILL);
drawPaint_GR.setColor(Color. GREEN);
drawPaint_GR.setStyle(Style.FILL);
// and then during draw()
canvas.drawRect(100,100, 340,540, drawPaint_WH);
canvas.drawRect(0,0, 120,80, drawPaint_GR);
and then to make a triangle:
// object
private Path trianglePath;
// during construction
trianglePath = new Path();
trianglePath.moveTo(10, 10); // starting point
trianglePath.lineTo(10, 50); // 1st vertix
trianglePath.lineTo(50, 10); // 2nd vertix
trianglePath.lineTo(10, 10); // 3rd vertix and close
// then during draw()
canvas.drawPath(trianglePath, drawPaint_GR) // or whatever paint you want
ps.: do color the background it's easier to call canvas.drawColor(int colorVal);