I'm in need of assistance with the program that I'm writing.
The code basically list of words from an array, chops it into specific Strings at certain indexes, then into Chars and displaying it into the canvas.
Then, the chars animates while sliding down the canvas.
But, whenever it animates slowly, the characters are on top of each other, and whenever it animates fast, the characters are separated.
How do I get the chars to be separated equally WHILE animating slowly?
One solution I came up with was to find a way to edit the frame rate, but I don't know how to do it :(.
public sketchUp(Context context) {
super(context);
}
String arr [] = {"love","happiness"};
protected void onDraw (Canvas canvas){
super.onDraw(canvas);
Rect disRect = new Rect();
disRect.set(0,0, canvas.getWidth(), canvas.getHeight()/2);
Paint col = new Paint();
Paint txt = new Paint();
txt.setTextSize(20);
txt.setColor(Color.BLACK);
col.setColor(Color.GREEN);
col.setStyle(Paint.Style.FILL);
canvas.drawRect(disRect, col);
if(y<canvas.getHeight()/2){
y+=1;
}
else{
y=0;
}
// if(x<canvas.getWidth()){
// x+=10;
// }
// else{
// x=0;
// }
for(int i=0; i<arr.length; i++){
for(int j=0; j<arr[i].length(); j++){
char result = arr[i].charAt(j);
// System.out.println(result);
canvas.drawText(String.valueOf(result), x, y+=0.5, txt);
//
}
}
invalidate();
}
Think of it this way:
That y+=0.5 sets the separation of the characters. It is the only thing that makes each character's position different. If it was just y, the characters would be on top of each other.
Why it affects animation speed
Each y+=0.5 changes y. So after drawing the characters y is lower than it was before.
How to fix this
First, you have to decide what y is supposed to be. You should rename it, so you remember what it is. For example it could become firstCharacterY.
Obviously, the first characters y should not change when drawing the characters, but should change each frame. To fix the drawing part, you can either set y = firstCharacterY - 0.5 before the loop or calculate y from i and j each iteration.
Related
I need to create a graph that is similar to a Baccarat trend like this
What could be the best approach? I am thinking of using RecyclerView with GridLayout but I have no idea how to plot it this way. Any library that support this kind of graph?
Try creating your own android View that can take some data and draw it
An example of your draw method could be
public void draw(Canvas canvas){
//draw grid
int spacing = 10; //costant cell size
//use (height/rows) and (width/cols) as spacing to have costant cols and rows instead
for(int y = 0; y<height; y+=spacing){
canvas.drawLine(0,y,width,y,paint);
}
for(int x = 0; x<width; x+=spacing){
canvas.drawLine(x, 0, x,height,paint);
}
//draw your data
}
XML is not the factor in this case. I'm overriding the canvas with the onDraw function and providing the entire screen as a canvas.
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.BLACK);
int gemID=0;
for(int c=0;c<5;c++){
for(int r=0;r<5;r++){
gemID= GemField[c][r];
canvas.drawBitmap(bmps.get(gemID),c,r,null);
}
}
Upon creating the canvas to draw on I create the matrix, and then I fill the matrix as seen in the following bits of code.
private void createGemField() {
Random rnd= new Random();
for(int col=0;col<5;col++){
for(int row=0;row<5;row++){
int gemNum = rnd.nextInt(4-0);
GemField[col][row]=gemNum;
}
}
}
private void drawGems(){
int gemID=0;
for(int col=0;col<5;col++){
for(int row=0;row<5;row++){
gemID=GemField[col][row];
canvas.drawBitmap(bmps.get(gemID),col,row,null);
}
}
}
Unfortunately the image I get is square in the top left of the screen with multiple objects that seem like they're scaled over each other. More like a snakes scale or shingles, the objects overlap but not completely. The further from the starting place holder in the matrix the less they overlap. Any idea why this may be happening?
canvas.drawBitmap(bmps.get(gemID),c,r,null);
Here, c and r are the x and y components of the point on the canvas where the bitmap is drawn. I assume your bitmaps are larger than 1px, so you should change this into:
canvas.drawBitmap(bmps.get(gemID), 50 * c, 50 * r, null); or something like this; between the bitmaps is now 50px space.
I have an isometric map which I draw to the canvas. When I try and move the map around, these black lines flicker in between some of the tiles making the whole thing look rather shoddy.
Here is the relevant code from my updating thread
public void run() {
Canvas c;
while (isRunning){
c = null;
try {
c = cellMap.getHolder().lockCanvas(null);
synchronized (cellMap.getHolder()) {
cellMap.onDraw(c);
}
} finally {
if( c != null){
cellMap.getHolder().unlockCanvasAndPost(c);
}
}
}
}
and from my CellMap class (which extends SurfaceView):
public void onDraw(Canvas canvas){
canvas.drawColor(Color.BLACK);
int x = 0;
int y = 0;
for(int i = 0; i < mapSize; i++){
for(int j = 0; j < mapSize; j++){
x = (i-j) * 30 + xOffset;
y = (i+j) * 15 + yOffset;
mapCells[i][j].draw(canvas, paint, x, y);
}
}
mapCells[][] is an array of objects which contain the Bitmap image that needs to be drawn. The draw() function is only 1 line canvas.drawBitmap(bitmapImage, x, y, null)
I have discovered that removing the line Canvas.draw(Color.black) gets rid of the flicker. However, when I move the map the canvas is not cleared so I still see the image from the previous frames. I'd imagine it is because it is taking too long to draw the bitmaps? but the map is only very small at the moment.
I found the problem. When moving the map, the offset values were being changed. This lead to sections of the map being drawn temporarily with different offset values - creating the tearing. duh!
I solved this by copying the xOffset and yOffset values at the start of the onDraw() method, and using those values for the update.
I am developing an app which draws more or less a two-dimensional matrix of values to a canvas. The values of this matrix are scaled to Alpha levels to illustrate intensity, and the coordinates for the matrix are simply extrapolated from row and column indexes. Below is my onDraw routine.
public void onDraw(Canvas canvas, float [][] spectrum, float nsegs,int seglen) {
//canvas.translate(0,0);
//alpha = 0;
int canHeight = canvas.getHeight();
int canWidth = canvas.getWidth();
//float[] array = generateData(512);
float [] spec = new float[seglen];
final float bw = (float)(canWidth-2)/nsegs;
final float bh = (float)(canHeight-2)/(float) seglen;
for (int i = 0;i<seglen;i++){
spec[i] = spectrum[i][index]; // One column at a time
}
float max = maxVal(spec);
float min = minVal(spec);
xcoor = index;
for (int n = 0; n < seglen; n++){
//Scale value to alpha (0-255)
alpha =(int)Math.round((((spec[n] - min)/max)*255.0));
ycoor = n;
paint.setAlpha(alpha);
canvas.drawPoint(xcoor,ycoor, paint);
}
index = (int) (index +1);
if (index == nsegs-1){
index = 0;
}
}
Here paint configuration is pre-defined as:
Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.WHITE);
paint.setStrokeWidth(2);
This program draws one pixel at a time, fills one column of pixels equal to the number of elements in a column of the matrix. Then it starts on the next column, where the previous column is still displayed and so forth. At this stage when all columns are full it stars from the first column again, drawing on top of previous elements.
The Problem: The tailing columns although already drawn appear to flicker and jump around, as does the Alpha. I have attempted to canvas.save() and canvas.restore() to capture the entire canvas and restore it after a column is printed. I have double checked all my row and column indexing and alpha vales to ensure the coordinates increment as per desired (and they do). This is very similar to the sample APIdemo DrawPoints.java, however there are three primary differences.
I am using DrawPoint not DrawPoints, and
I don't use "canvas.setColour" as it removes the tailing columns from the canvas.
This onDraw function is operating in a Thread which extends SurfaceView
Any idea's would be much appreciated, thank you for your time.
In the case above, I was using a SurfaceView instead of a View. Out of the Android dev docs
Note: On each pass you retrieve the Canvas from the SurfaceHolder, the previous state of the Canvas will be retained. In order to properly animate your graphics, you must re-paint the entire surface. For example, you can clear the previous state of the Canvas by filling in a color with drawColor() or setting a background image with drawBitmap(). Otherwise, you will see traces of the drawings you previously performed.
The Solution, re-draw the entire canvas each time to prevent the jitter.
I want to draw a signal waveform using the path.linTo method and a for loop as shown below.
public void drawSignal(Canvas c, PointF pos) // draws the signal onto the Canvas for each of the 12 channels
{
Paint paint = new Paint();
paint.setColor(Color.BLACK);
paint.setStyle(Style.STROKE);
Path path = new Path();
for (int i=0; i<ECGFilereader.numChannels; i++){
path.moveTo(wavePos[i].x, wavePos[i].y);
for (int chan = 0; chan<ECGFilereader.numChannels; chan++)
for (int m = 0; m < ECGFilereader.numSamples; m++){
path.lineTo(m+wavePos[i].x, signal[chan][m]+wavePos[i].y);
}
}
c.drawPath(path, paint);
However I would like to scale the graph so that each movement in the x-axis is only 1/5 of that of the y-axis, so that the length of the signal is effectively squashed horrizontally. Is it possible to do this by simply using floats somehow I do I need to actually create a larger canvas and scale it there?
Thanks in advance for any help.
err, either multiply the y-components by 5 or divide the x-components by 5 in both path.moveTo and path.lineTo?