Hello I have a launcher i've been working on and I want to make the folder icon a rounded square like this:.
right now its a circle the shape is made via java code no xml is used
here's the code:
package com.appname.viewutil;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PixelFormat;
import android.graphics.RectF;
import android.graphics.Region;
import android.graphics.drawable.Drawable;
import com.launchername.activity.Home;
import com.launchername.util.Tool;
public class GroupIconDrawable extends Drawable{
private int outlinepad;
Bitmap[] icons;
public float iconSize;
Paint paint;
Paint paint2;
Paint paint4;
private int iconSizeDiv2;
private float padding;
private float scaleFactor = 1;
private boolean needAnimate, needAnimateScale;
private float sx = 1;
private float sy = 1 ;
public GroupIconDrawable(Bitmap[] icons,float size){
init(icons,size);
}
private void init(Bitmap[] icons,float size){
this.icons = icons;
this.iconSize = size;
iconSizeDiv2 = Math.round(iconSize / 2f);
padding = iconSize /25f;
this.paint = new Paint();
paint.setColor(Color.WHITE);
paint.setAlpha(150);
paint.setAntiAlias(true);
this.paint4 = new Paint();
paint4.setColor(Color.WHITE);
paint4.setAntiAlias(true);
paint4.setFlags(Paint.ANTI_ALIAS_FLAG);
paint4.setStyle(Paint.Style.STROKE);
outlinepad = Tool.dp2px(2, Home.launcher);
paint4.setStrokeWidth(outlinepad);
this.paint2 = new Paint();
paint2.setAntiAlias(true);
paint2.setFilterBitmap(true);
}
public void popUp(){
sy = 1;
sx = 1;
needAnimate = true;
needAnimateScale = true;
invalidateSelf();
}
public void popBack(){
needAnimate = false;
needAnimateScale = false;
invalidateSelf();
}
#Override
public void draw(Canvas canvas) {
canvas.save();
if (needAnimateScale){
scaleFactor = Tool.clampFloat(scaleFactor-0.09f,0.5f,1f);
}else {
scaleFactor = Tool.clampFloat(scaleFactor+0.09f,0.5f,1f);
}
canvas.scale(scaleFactor,scaleFactor,iconSize/2,iconSize/2);
Path clipp = new Path();
clipp.addCircle(iconSize / 2,iconSize / 2,iconSize / 2-outlinepad, Path.Direction.CW);
canvas.clipPath(clipp, Region.Op.REPLACE);
canvas.drawCircle(iconSize / 2, iconSize / 2, iconSize / 2-outlinepad,paint);
canvas.drawBitmap(icons[0],null,new RectF(padding,padding, iconSizeDiv2-padding, iconSizeDiv2-padding),paint2);
canvas.drawBitmap(icons[1],null,new RectF(iconSizeDiv2+padding,padding,iconSize-padding, iconSizeDiv2-padding),paint2);
canvas.drawBitmap(icons[2],null,new RectF(padding, iconSizeDiv2+padding, iconSizeDiv2-padding,iconSize-padding),paint2);
canvas.drawBitmap(icons[3],null,new RectF(iconSizeDiv2+padding, iconSizeDiv2+padding,iconSize-padding,iconSize-padding),paint2);
canvas.clipRect(0,0,iconSize,iconSize, Region.Op.REPLACE);
canvas.drawCircle(iconSize / 2, iconSize / 2, iconSize/2-outlinepad,paint4);
canvas.restore();
if (needAnimate){
paint2.setAlpha(Tool.clampInt(paint2.getAlpha()-25,0,255));
invalidateSelf();
}else if (paint2.getAlpha() != 255){
paint2.setAlpha(Tool.clampInt(paint2.getAlpha()+25,0,255));
invalidateSelf();
}
}
#Override
public void setAlpha(int i) {}
#Override
public void setColorFilter(ColorFilter colorFilter) {}
#Override
public int getOpacity() {return PixelFormat.TRANSPARENT;}
}
any ideas on how to make it a rounded square like in the picture?
any help would be awesome!
thanks in advance :)
Replace the calls to addCircle and drawCircle with the appropriate RoundRect functions- addRoundRect and drawRoundRect.
Related
So i was trying to make a simple mobile game for a school project. I setted up a simple SurfaceView thing and builded it on my phone with Android 12 (Api 32), but it doesn't draw anything. It enters the draw function of the view, but i can't see an output. It only works on a old friend's tablet with Android 4.4.2.
MySurfaceView.java
package com.example.lyceumgame;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback {
Bitmap image;
Paint paint;
float iX, iY, tX = 0, tY = 0;
float dx = 0, dy = 0;
Resources res;
MyThread myThread;
float ws, hs;
float iw, ih;
boolean isFirstDraw = true;
public MySurfaceView(Context context) {
super(context);
getHolder().addCallback(this);
res = getResources();
iX = 100;
iY = 100;
paint = new Paint();
paint.setColor(Color.YELLOW);
paint.setStrokeWidth(5);
setAlpha(0);
}
#Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
myThread = new MyThread(surfaceHolder, this);
myThread.setRunning(true);
myThread.start();
}
#Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
}
#Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
boolean retry = true;
myThread.setRunning(false);
while (retry) {
try {
myThread.join();
retry = false;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
#Override
public void draw(Canvas canvas) {
super.draw(canvas);
setAlpha(0);
if (isFirstDraw){
ws = canvas.getWidth();
hs = canvas.getHeight();
isFirstDraw = false;
}
canvas.drawRGB(0,255,0);
canvas.drawLine(iX, iY, tX, tY, paint);
if(tX != 0)
delta();
iX += dx;
iY += dy;
checkScreen();
}
#Override
public boolean onTouchEvent(MotionEvent event) {
tX = event.getX();
tY = event.getY();
delta();
return true;
}
void delta(){
double ro = Math.sqrt(Math.pow(tX-iX, 2)+Math.pow(tY-iY, 2));
double k = 10;
dx = (float) (k * (tX - iX)/ro);
dy = (float) (k * (tY - iY)/ro);
}
private void checkScreen(){
if(iY + ih >= hs && iY <= 0)
dy = -dy;
if(iX + iw >= ws && iX <= 0)
dx = -dx;
}
}
MyThread.java
package com.example.lyceumgame;
import android.graphics.Canvas;
import android.view.SurfaceHolder;
public class MyThread extends Thread {
boolean isRunning = false;
SurfaceHolder surfaceHolder;
MySurfaceView mySurfaceView;
long prevTime, nowTime;
int FPS=60;
int c=1000;
int koeff=c/FPS;
public MyThread(SurfaceHolder holder, MySurfaceView surfaceView) {
surfaceHolder = holder;
mySurfaceView = surfaceView;
prevTime = System.currentTimeMillis();
}
#Override
public void run() {
Canvas canvas;
while (isRunning){
if(!surfaceHolder.getSurface().isValid())
continue;
canvas = null;
nowTime = System.currentTimeMillis();
long ellapsedTime = nowTime - prevTime;
if(ellapsedTime > koeff){
prevTime = nowTime;
canvas = surfaceHolder.lockCanvas(null);
synchronized (surfaceHolder){
mySurfaceView.draw(canvas);
}
if (canvas != null){
surfaceHolder.unlockCanvasAndPost(canvas);
}
}
}
}
void setRunning(boolean f){
isRunning = f;
}
}
MainActivity.java
package com.example.lyceumgame;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new MySurfaceView(this));
}
}
My SDK was in different location and code like this worked fine. I tried invalidating caches and moving SDK to previous location. It didn't work.
I am building an app where a user can draw lines in a custom canvas with a finger (multiple fragments have a canvas and this works) using the Path class.
I also managed to use SharedPreferences to save and load the drawn lines but when loaded the lines start from the top left (i.e (0, 0)) and the shape has changed to lines with a slight curve at the start (I say start because I found that the line ends from where the touch started).
The start points are kept in Path but from what I can see there are no endpoints kept. Is there any way I can get the endpoints?
I have previously tried passing the required variables to another ArrayList that uses another constructor with the endpoints (found with a method used for when the finger stops touching the screen) but the drawings no longer showed on the canvas unlike before.
Edit
I have changed to finding multiple points as I believe that getting the endpoint won't be enough and have altered the shown code to show my attempt with getPosTan but no drawings get shown as the elements in testing are null for some reason, so it won't go in the else.
Update
I found that pathMeasure.getLength() produces 0.0 so it isn't going into the while and therefore resulting in null elements but I don't know why it's producing 0.0 as somePath isn't null
PaintView.java
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BlurMaskFilter;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.EmbossMaskFilter;
import android.graphics.MaskFilter;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import java.util.ArrayList;
public class PaintView extends View {
public static int BRUSH_SIZE = 10;
public static final int DEFAULT_COLOR = Color.WHITE;
public static int DEFAULT_BG_COLOR = Color.GRAY;
private static final float TOUCH_TOLERANCE = 4;
private float mX, mY;
private Path mPath;
private Paint mPaint;
private static ArrayList<FingerPath> paths = new ArrayList<>();
private int currentColor;
private int backgroundColor = DEFAULT_BG_COLOR;
private int strokeWidth;
private boolean emboss;
private boolean blur;
private MaskFilter mEmboss;
private MaskFilter mBlur;
private Bitmap mBitmap;
public Canvas mCanvas;
private Paint mBitmapPaint = new Paint(Paint.DITHER_FLAG);
public PaintView(Context context) {
this(context, null);
}
public PaintView(Context context, AttributeSet attrs) {
super(context, attrs);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(DEFAULT_COLOR);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setXfermode(null);
mPaint.setAlpha(0xff);
mEmboss = new EmbossMaskFilter(new float[] {1, 1, 1}, 0.4f, 6, 3.5f);
mBlur = new BlurMaskFilter(5, BlurMaskFilter.Blur.NORMAL);
}
public ArrayList getPaths() {
return paths;
}
public ArrayList setPaths(ArrayList<FingerPath> list) {
return this.paths = list;
}
public void init(DisplayMetrics metrics) {
int height = metrics.heightPixels;
int width = metrics.widthPixels;
mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
loadDrawing(mCanvas);
currentColor = DEFAULT_COLOR;
strokeWidth = BRUSH_SIZE;
}
public void normal() {
emboss = false;
blur = false;
}
public void clear() {
backgroundColor = DEFAULT_BG_COLOR;
paths.clear();
normal();
invalidate();
}
#Override
protected void onDraw(Canvas canvas) {
canvas.save();
mCanvas.drawColor(backgroundColor);
for (FingerPath fp : paths) {
mPaint.setColor(fp.color);
mPaint.setStrokeWidth(fp.strokeWidth);
mPaint.setMaskFilter(null);
if (fp.emboss)
mPaint.setMaskFilter(mEmboss);
else if (fp.blur)
mPaint.setMaskFilter(mBlur);
mCanvas.drawPath(fp.path, mPaint);
}
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
canvas.restore();
}
private void touchStart(float x, float y) {
mPath = new Path();
FingerPath fp = new FingerPath(currentColor, emboss, blur, strokeWidth, mPath, x, y);
paths.add(fp);
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);}
#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;
}
private FloatPoint[] getPoint(Path somePath, float x, float y){
FloatPoint[] pointArray = new FloatPoint[20];
PathMeasure pathMeasure = new PathMeasure(somePath, false);
float length = pathMeasure.getLength();
float distance = 0f;
float speed = length / 20;
int counter = 0;
float[] aCoordinates = {x, y};
while ((distance < length) && (counter < 20)) {
pathMeasure.getPosTan(distance, aCoordinates, null);
pointArray[counter] = new FloatPoint(aCoordinates[0],
aCoordinates[1]);
counter++;
distance = distance + speed;
}
return pointArray;
}
public void loadDrawing(Canvas canvas) {
if (mCanvas != null) {
currentColor = DEFAULT_COLOR;
strokeWidth = BRUSH_SIZE;
if (! paths.isEmpty()) {
canvas.save();
mCanvas.drawColor(backgroundColor);
for (FingerPath fp : paths) {
mPaint.setColor(fp.color);
mPaint.setStrokeWidth(fp.strokeWidth);
mPaint.setMaskFilter(null);
if (fp.emboss)
mPaint.setMaskFilter(mEmboss);
else if (fp.blur)
mPaint.setMaskFilter(mBlur);
FloatPoint[] testing = getPoint(fp.path, fp.x, fp.y);
//need to figure out how to for loop testing
float sectionTestX = 0.0f;
float sectionTestY = 0.0f;
for (FloatPoint testingPoint : testing) {
if (sectionTestX == 0.0f && sectionTestY == 0.0f) {
sectionTestX = testingPoint.getX();
sectionTestY = testingPoint.getY();
continue;
} else {
fp.path.quadTo(sectionTestX, sectionTestY,
testingPoint.getX(), testingPoint.getY());
sectionTestX = testingPoint.getX();
sectionTestY = testingPoint.getY();
}
}
/*xTest = fp.x;
yTest = fp.y;*/
}
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
canvas.restore();
}
}
}
}
FloatPoint.java
public class FloatPoint {
static float x, y;
public FloatPoint(float x, float y) {
this.x = x;
this.y = y;
}
public static float getX() {
return x;
}
public static float getY() {
return y;
}
}
I have a rectangle I want to move up the screen at a constant rate and am confused as to why my code isn't working. Below is the code:
package com.ashmore.MyGame;
import java.util.ArrayList;
import java.util.List;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.Log;
import com.ashmore.framework.Game;
import com.ashmore.framework.Graphics;
import com.ashmore.framework.Image;
import com.ashmore.framework.Screen;
import com.ashmore.framework.Input.TouchEvent;
public class GameScreen extends Screen {
enum GameState {
Ready, Running, Paused
}
GameState state = GameState.Ready;
boolean BarisMoving = false;
private ArrayList<Rect> rectangles = new ArrayList<Rect>();
int bar_x = 32;
int bar_y = 653;
int bar_width = 183;
int bar_height = 648;
Rect bar;
Paint paint;
public GameScreen(Game game) {
super(game);
// Initialize game objects here
bar = new Rect();
bar.set(bar_x, bar_y, bar_width, bar_height);
// Defining a paint object
paint = new Paint();
paint.setTextSize(30);
paint.setTextAlign(Paint.Align.CENTER);
paint.setAntiAlias(true);
paint.setColor(Color.WHITE);
}
private void updateRunning(List<TouchEvent> touchEvents, float deltaTime) {
// 1. All touch input is handled here:
int len = touchEvents.size();
for (int i = 0; i < len; i++) {
TouchEvent event = touchEvents.get(i);
BarisMoving = true;
if (event.type == TouchEvent.TOUCH_UP) {
if (ScalesScreen.scaleType.equals("C")) {
rectangles.add(new Rect(56, 400, 80, 435));
//rectangles.get(0);
break;
}
if (BarisMoving) {
bar_y = bar_y -= 10;
}
for (Rect rect : rectangles) {
if(bar.intersect(rect)) {
checkButtons();
}
}
}
}
private void checkButtons() {
Log.d("GameScreen","Note and Bar Intersected");
}
#Override
public void paint(float deltaTime) {
Graphics g = game.getGraphics();
Paint paint = new Paint();
Paint paint2 = new Paint();
paint.setColor(Color.RED);
paint2.setColor(Color.RED);
for (Rect rect : rectangles) {
g.drawRect(rect, paint);
}
g.drawRect(bar, paint2);
}
private boolean inBounds(TouchEvent event, int x, int y, int width,
int height) {
if (event.x > x && event.x < x + width - 1 && event.y > y
&& event.y < y + height - 1)
return true;
else
return false;
}
}
I am probably missing something really basic. However, I can't seem to find the issue. Any help is appreciated!
I have figured out my problem. The problem was where my code was placed in the updateRunning() method. In my question, the setting of the boolean BarisMoving was set equal to "true" when there was a touch event:
int len = touchEvents.size();
for (int i = 0; i < len; i++) {
TouchEvent event = touchEvents.get(i);
BarisMoving = true;
The boolean had to be moved outside of this (above int len = touchEvents.size();) and outside of the whole touch event area to work the way I wanted (outside of the for () { and the ending bracket }).
I am having trouble with collision detection in a 2d java game that I am currently trying to make. For some reason I keep on getting the following error:
Exception in thread "Thread-2" java.lang.NullPointerException
at Objects.Bullet.Collision(Bullet.java:57)
at Objects.Bullet.tick(Bullet.java:39)
at window.Handler.tick(Handler.java:15)
at window.Game.tick(Game.java:96)
at window.Game.run(Game.java:76)
at java.lang.Thread.run(Unknown Source)
Here the code that I currently have for my bullet:
package Objects;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.util.LinkedList;
import window.Game;
import window.Handler;
import Framework.GameObject;
import Framework.ObjectId;
import Framework.Texture;
public class Bullet extends GameObject{
private float width=32,height=32;
private final float MAX_SPEED = 10;
private Handler handler;
Texture tex= Game.getInstance();
public Bullet(float x,float y, ObjectId id,int velX){
super(x,y,id);
this.velX = velX;
}
public void tick(LinkedList<GameObject> object) {
x+=velX;
y+=velY;
if(velX<0)orientation =-1;
else if(velX>0)orientation=1;
if(velY>MAX_SPEED){
velY = MAX_SPEED;}
Collision(object);
}
public void render(Graphics g){
g.drawImage(tex.bullet[0],(int)x ,(int)y,null);
}
public Rectangle getBoundsRight() {
return new Rectangle((int) ((int)x+width-5),(int)y+5,(int)5, (int)height-10);
}
public Rectangle getBoundsLeft() {
return new Rectangle((int)x,(int)y+5,(int)5,(int)height-10);
}
private void Collision(LinkedList<GameObject>object){
for(int i=0; i<handler.object.size();i++){
GameObject tempObject = handler.object.get(i);
if(tempObject.getId() == ObjectId.Block){
if(getBoundsRight().intersects(tempObject.getBounds())){
velX=0;
x = tempObject.getX()- width;
}
if(getBoundsLeft().intersects(tempObject.getBounds())){
velX = 0;
x = tempObject.getX()+ (30);
}
}
}
}
public Rectangle getBounds() {
return null;
}
}
I basically copied the code from my player class in which everything works perfectly but for some reason I am getting errors with my bullet class
The code for my player class is shown below:
package Objects;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.util.LinkedList;
import window.Animation;
import window.Game;
import window.Handler;
import Framework.GameObject;
import Framework.ObjectId;
import Framework.Texture;
public class Player extends GameObject{
private float width = 64, height = 64;
private float gravity = 0.5f;
private final float MAX_SPEED = 10;
private Handler handler;
Texture tex = Game.getInstance();
//1= right
//-1= left
private Animation playerWalk,playerWalkLeft;
public Player(float x, float y,Handler handler, ObjectId id) {
super(x, y, id);
this.handler = handler;
playerWalk = new Animation(5,tex.player[1],tex.player[2],tex.player[3],tex.player[4],tex.player[5],tex.player[6]);
playerWalkLeft = new Animation(5,tex.player[7],tex.player[8],tex.player[9],tex.player[10],tex.player[11],tex.player[12]);
}
public void tick(LinkedList<GameObject> object) {
x+=velX;
y+=velY;
if(velX<0)orientation =-1;
else if(velX>0)orientation=1;
if(falling||jumping){
velY+=gravity;
if(velY>MAX_SPEED){
velY = MAX_SPEED;
}
}
Collision(object);
playerWalk.runAnimation();
playerWalkLeft.runAnimation();
}
private void Collision(LinkedList<GameObject>object){
for(int i=0; i<handler.object.size();i++){
GameObject tempObject = handler.object.get(i);
if(tempObject.getId() == ObjectId.Block){
if(getBoundsTop().intersects(tempObject.getBounds())){
y= tempObject.getY()+40 ;
velY=0;
}
if(getBounds().intersects(tempObject.getBounds())){
velY=0;
y= tempObject.getY()-height;
falling = false;
jumping = false;
}else
falling = true;
//Right
if(getBoundsRight().intersects(tempObject.getBounds())){
x = tempObject.getX()- width;
}
//Left
if(getBoundsLeft().intersects(tempObject.getBounds())){
x = tempObject.getX()+ (30);
}
}
}
}
public void render(Graphics g) {
g.setColor(Color.BLUE);
if(velX != 0 ){
if(orientation == 1)
playerWalk.drawAnimation(g,(int)x,(int)y,64,64);
else
playerWalkLeft.drawAnimation(g,(int)x,(int)y,64,64);
}else
if(orientation == 1)
g.drawImage(tex.player[1],(int)x,(int)y,64,64,null); //change here to change the size of the ball. does not account for hit-box must change in the width and height global variables above
else if(orientation == -1)
g.drawImage(tex.player[12],(int)x,(int)y,64,64,null);
}
public Rectangle getBounds() {
return new Rectangle((int) ((int)x+(width/2)-((width/2)/2)),(int) ((int)y+(height/2)),(int)width/2,(int)height/2);
}
public Rectangle getBoundsTop() {
return new Rectangle((int) ((int)x+(width/2)-((width/2)/2)),(int)y,(int)width/2,(int)height/2);
}
public Rectangle getBoundsRight() {
return new Rectangle((int) ((int)x+width-5),(int)y+5,(int)5,(int)height-10);
}
public Rectangle getBoundsLeft() {
return new Rectangle((int)x,(int)y+5,(int)5,(int)height-10);
}
}
Any form of help/hints.or suggestions will be greatly appreciated
I have an array of objects that need to be drawn to a canvas; each object is represented as:
scatterPlot.java
package scatter.plot;
import java.util.ArrayList;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.view.View;
public class scatterPoint extends View {
private final Point coordinates;
private final int itemShape;
private Paint itemColour = new Paint(Paint.ANTI_ALIAS_FLAG);
private scatterPoint[] mShapes;
public scatterPoint(Context context, Point p, int shape, Paint colour) { // Constructor
super(context);
coordinates = p;
itemShape = shape;
itemColour = colour;
}
//get set points
public void setPoints(scatterPoint[] p){
mShapes = p;
}
public scatterPoint[] getScatterPoints(){
return mShapes;
}
#Override
protected void onDraw(Canvas canvas) {
//super.onDraw(canvas);
int radius = 10;
for (scatterPoint i : mShapes) {
switch(itemShape){
case 0:
canvas.drawRect(i.coordinates.x - radius, i.coordinates.y - radius, i.coordinates.x + radius, i.coordinates.y + radius, i.itemColour);
break;
case 1:
Path path = new Path();
path.moveTo(i.coordinates.x - radius, i.coordinates.y - radius);
path.lineTo(i.coordinates.x, i.coordinates.y + radius);
path.lineTo(i.coordinates.x + radius, i.coordinates.y - radius);
path.lineTo(i.coordinates.x - radius, i.coordinates.y - radius);
path.close();
canvas.drawPath(path, i.itemColour);
break;
case 2:
canvas.drawCircle(i.coordinates.x, i.coordinates.y, radius, i.itemColour);
break;
}
}
}
public Point getCoordinates(){
return coordinates;
}
public int getShape(){
return itemShape;
}
public Paint getColour(){
return itemColour;
}
}
Relevant methods from main (ScatterPlotActivity.java):
package scatter.plot;
import java.util.Random;
import android.app.Activity;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.os.Bundle;
import android.view.Display;
import android.view.WindowManager;
import android.widget.FrameLayout;
public class ScatterPlotActivity extends Activity {
FrameLayout main;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
main = (FrameLayout) findViewById(R.id.main_view);
scatterPoint[] points = generatePoints();
//
//add scatterPoint to main
//
}
public scatterPoint[] generatePoints(){
//
return points;
}
}
Any ideas on what is wrong with how I'm trying to draw these objects?
I think the problem comes from the fact that you're creating each time a new FrameLayout. Declare your FrameLayout in your main and then call your method drawPoints like this:
drawPoint(points[i], main);
and your method will look like this :
public void drawPoint(scatterPoint point, FrameLayout main) {
main.addView(point);
}
This way they will always be added to the same Layout.
The problem is:
public void drawPoint(scatterPoint point) {
FrameLayout main = (FrameLayout) findViewById(R.id.main_view);
main.addView(point);
}
Make your FrameLayout main; a global variable. Then, right after you call setContentView(R.layout.x); in onActivityCreated(), call main = (FrameLayout) findViewById(R.id.main_view);
You only want to make this call once. Every time the current implementation calls public void drawPoint(scatterPoint point);, the FrameLayout is being reinitialized and clearing all the old drawings.
By the looks of things, you are actually drawing all of your scatter point views. However, due to how you are adding them to the FrameLayout, they are stacking on top of each other. Look in your drawPoint() method. You add the point to FrameLayout, which was designed to only handle one view (for more on this statement refer to FrameLayout), and the FrameLayout just draws the new view right over the last view drawn.
class ScatterShape {
public float mX = 0, mY = 0;
public int mShape = 0;
public Paint mColor = new Paint();
public ScatterShape(float x, float y, int shape, int color) {
mX = x;
mY = y;
mShape = shape;
mColor.setColor(color);
}
}
public class ScatterShaperDrawer extends View {
private List<ScatterShape> mShapes = new ArrayList<ScatterShapes>();
private float mmRadius = 5;
// Make getter and setter
#Override public void onDraw(Canvas canvas) {
for (ScatterShape i : mShapes) {
switch(i.mShape){
case 0:
canvas.drawRect(i.mX - mRadius, i.mY - mRadius, i.mX + mRadius, i.mY + mRadius, itemColor);
break;
case 1:
Path path = new Path();
path.moveTo(i.mX - mRadius, i.mY - mRadius);
path.lineTo(i.mX, i.mY + mRadius);
path.lineTo(i.mX + mRadius, i.mY - mRadius);
path.lineTo(i.mX - mRadius, i.mY - mRadius);
path.close();
canvas.drawPath(path, i.mColor);
break;
case 2:
canvas.drawCircle(i.mX, i.mY, mRadius, i.mColor);
break;
}
}
}
}