I'm trying to draw different random values from an array, but linking them with lines, so it looks likes the values of a continue function. I have done it quite good with this app:
package android.nacho.Graphic2D;
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import java.util.Random;//included random
public class Graphic2D extends Activity{
DrawView drawView;
//private Button btnAsyncTask;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
int randomInt;
//note a single Random object is reused here
Random randomGenerator = new Random();
int Maxsize=800;
int[] randomNumbers= new int[Maxsize];
for (int idx = 1; idx < Maxsize-1; ++idx){
randomInt = randomGenerator.nextInt(100);
randomNumbers[idx]=randomInt;
System.out.println("Random number: "+randomInt);
}
drawView = new DrawView(Graphic2D.this, randomNumbers, Maxsize);
drawView.setBackgroundColor(Color.WHITE);
setContentView(drawView);
}
}
package android.nacho.Graphic2D;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.View;
public class DrawView extends View {
Paint paint = new Paint();
int[] values;
int Size, Offset;
public DrawView(Context context, int[] datainBytes, int size) {
super(context);
values=datainBytes;
Size=size;
paint.setColor(Color.BLACK);
}
#Override
public void onDraw(Canvas canvas) {
int cont2;
for(int cont=0; cont<Size-(1); cont++)
{
cont2=cont+1;
canvas.drawLine(cont, 500-(values[cont]) , cont+1, 500-(values[cont2]), paint);
}
}
}
The thing is, now I want to dram much more points, but in a dinamicall way so the new value is the one most at the right, the rest of the values move one pixel to the left and the one most of the left just don't appear. I was planning to this with a loop in the main Activity, so in each iteration the random values are all the same but the last one, and the others have move one position to the left in the array. The final effect should be something like a video.
But there is a problem, do App don't draw this dinamically, it just draw the last iteration of the loop. ¿Could anyone help me to solve this?
I was thinking in using AsyncTask for that, doing the points generation in the backgroun and sending the result to the update so draw in, but the script was a mess that didn't work, so I prefer to don't upload it.
Thank you very much for any suggestion.
Related
Follows is an SSCCE to understand animation timing, extracted from a much more complicated example. What this example when completed should do is create a circle and change its fill color between red and green every second. Right now it just draws a red circle and then nothing else. I've tried placing Runnable, Timer, Thread, and Handler code in various locations but it never seems to do anything. Another problem I've encountered in run() methods is the need for references to Canvas and the current color and the only way I've obtained them is by creating member data for them which, especially in the case of Canvas, seems like a bad idea. For what I'm ultimately doing, rotation and translation of graphic objects, SampleView and the accompanying Canvas seems to be almost certainly necessary so I want to leave SampleView in place. I think that's part of the problem, most examples of animation I've encountered place the timing code in an Activity but that won't work cleanly since the inner View's canvas must be used to update the color (unless I'm missing something).
Inside run methods I used variations on code like this.
if (color == Color.RED)
color = Color.GREEN;
else color = Color.RED;
canvas.drawOval(rectF, p);
hand.postDelayed(run, GET_DATA_INTERVAL);
Those references to color and canvas have been a pain.
package com.example.circles;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
private static class SampleView extends View {
public SampleView(Context context) {
super(context);
setFocusable(true);
p = new Paint();
}
Paint p;
int color;
RectF rectF = new RectF(0, 0, 50, 50);
#Override
protected void onDraw(Canvas canvas) {
p.setStyle(Paint.Style.FILL);
color = Color.RED;
p.setColor(color);
canvas.drawOval(rectF, p);
}
}
}
I'm stucked in this for almost a month. I have a perfect chart in my android code using 'afreechart', however, the library does not seem to have support for exporting the chart as an image yet (since it's based on 'jfreechart' and this one does the job).
I tried to get the view of the chart, convert it into canvas and save using the compress functions of the bitmap library, however everytime i try this i get a totally black image as a result. I tried this same method and it works for the other views of my code (simple views, like linearlayout and relativelayout).
After that i tried to create a routine to make a screenshot of the chart activity and close that activity after that. But I couldn't find a way to do that by code, the closest i got was with monkeyrunner.
So i gave up of this idea and tried to look for other libraries, such as 'kichart', 'achartengine', etc, but none of them seem to do the job for, i'm freaking out and i thought that exporting the chart to an image wouldn't be that hard... any ideas?
When i set a background color for the layout, the returned image is a full rectangle with the color of the background, so it's getting the layout, just not the chart.
My Code:
package com.kichart;
import java.io.File;
import java.io.FileOutputStream;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.LinearLayout;
public class Main extends Activity {
LinearLayout ll;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
float[] values = new float[] { 2.0f,1.5f, 2.5f, 1.0f , 3.0f };
String[] verlabels = new String[] { "great", "ok", "bad" };
String[] horlabels = new String[] { "today", "tomorrow", "next week", "next month" };
GraphView graphView = new GraphView(this, values, "GraphViewDemo",horlabels, verlabels, GraphView.BAR);
ll = new LinearLayout(this);
ll.addView(graphView);
Draw2d d = new Draw2d(this);
setContentView(d);
//setContentView(graphView);
}
public class Draw2d extends View {
public Draw2d(Context context) {
super(context);
setDrawingCacheEnabled(true);
}
#Override
protected void onDraw(Canvas c) {
ll.setBackgroundColor(Color.WHITE);
ll.measure(MeasureSpec.getSize(ll.getWidth()), MeasureSpec.getSize(ll.getHeight()));
ll.layout(400, 400, 400, 400);
ll.draw(c);
try {
getDrawingCache().compress(Bitmap.CompressFormat.PNG, 100, new FileOutputStream(new File("/mnt/sdcard/graph2.png")));
} catch (Exception e) {
Log.e("Error--------->", e.toString());
}
super.onDraw(c);
}
}
}
You can get a image bitmap from a view by doing:
Bitmap bitmap;
chart.setDrawingCacheEnabled(true);
bitmap = Bitmap.createBitmap(chart.getDrawingCache());
chart.setDrawingCacheEnabled(false);
if you can't call getDrawingCache on the chart, try to place it inside a layout like RelativeLayout or something like that. and call it on the layout.
After that you can save it as a image..
If the image is still black, you need to make sure the chart is created before getting the bitmap.
Hope this will help you
I have one activity in my Android App for now which is a RelativeLayout with a background color and onCreate I create a number of random colored circles and addViews on to the relativelayout based on the device screen width and height. Here are the code snippets.
MyActivity.java
package com.myapp.android;
import java.util.Random;
import android.app.Activity;
import android.os.Bundle;
import android.view.Display;
import android.widget.RelativeLayout;
public class MyActivity extends Activity {
/** Called when the activity is first created. */
Random randomGenerator = new Random();
String[] colors = { "#84B62C", "#6A28F2","#F3FA0A", "#DF1FE4", "#0000A0", "#28C9DB", "#E05323"};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
RelativeLayout main = (RelativeLayout) findViewById(R.id.main_myapp);
// Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
Display display = getWindowManager().getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();
int number_side = width / 100;
int number_down = height / 100;
for(int i = 0; i < (number_side * number_down) * 3; i++) {
main.addView(new Ball(this,randomGenerator.nextInt(width), randomGenerator.nextInt(height), 40 * (randomGenerator.nextInt(3)), colors[randomGenerator.nextInt(colors.length)], "BALL" + Integer.toString(i)));
}
}
}
This works great draws all the colored circles in random throughout the screen as I want it. Looks good. Here is the code for the Ball.java where the circles are drawn.
Ball.java
package com.myapp.android;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.MotionEvent;
import android.view.View;
import android.widget.RelativeLayout;
public class Ball extends View {
private final float x;
private final float y;
private final int r;
private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
public Ball(Context context, float x, float y, int r, String color, String tag) {
super(context);
mPaint.setColor(Color.parseColor(color));
this.x = x;
this.y = y;
this.r = r;
this.setTag(tag);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawCircle(x, y, r, mPaint);
}
}
What I am trying to do is let the user touch any one of the colored circle and drag it on the screen wherever they want to but I cannot get them to move. I have not posted any trial code here.
What would be the best way to detect the user touch (this can be onTouch or onLongClick) on any of the circles drawn on screen (one circle at a time especially the one that is touched by the user) and thereafter make the circle (which is essentially a view added to the main Relative Layout View group at run time) to follow the users touch drag action (ACTION_MOVE - my guess) until they release the drag (ACTION_UP - my guess).
I have read some tutorials on this topic but none has been really helpful or applicable to my use case. Also I wanted to ask you knowledgeable guys should I use the 2D Graphics Canvas or OpenGL API in my case so that the drag operation on the circles are very smooth and instantaneous. Feel free to run my simple code, it works fine until the balls are drawn on the screen.
In your implementation, you consider Ball as a View and there are many balls thus there are many Views.
If I were you, I'll consider the whole screen is ONE View and the balls are only sprites inside that View.
Say, I'll extend the View class or SurfaceView class and have a Collection as attribute to store all coordinates and sizes of balls. Inside onDraw(), it should loop through the collection and draw the balls on correct location with correct size.
I'm porting a game from JME to Android and I found an annoying problem. The next activity must draw a grid, and in fact it does. But the grid appear OK just in landscaping mode. When you put the phone vertical (in portrait mode) it appears strangely compressed.
The main code is the method used to draw a cells row, (getSquareRow)
Thanks in advance for any help.
Here is the code:
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
public class TraxActivity extends Activity {
InternalView myView;
private float shift, di;
private float n, minim, redux, side;
boolean first = true;
#Override
public void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
super.onCreate(savedInstanceState);
myView = new InternalView(this);
setContentView(myView);
}
private class InternalView extends View{
public InternalView(Context context){
super(context);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
n=5;
di=12;
int ancho = getWidth();
int alto = getHeight();
minim = Math.min(getWidth(), getHeight());
redux = minim*9/10;
shift = (getWidth() - redux)/2;
side = redux/n;
//background
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.BLUE);
canvas.drawPaint(paint);
//grid
for(int j=0; j < n; j++){
getSquareRow( canvas, j, paint);
}
}
public void getSquareRow(Canvas g, int row, Paint p){
p.setColor(Color.BLACK);
p.setStyle(Paint.Style.STROKE);
p.setStrokeWidth(10);
for(int i=0; i < n; i++){
g.drawRect(shift+i*side, shift+row*side, side, side, p );
}
}
}
}
Thanks guys, I'll be targeting the game just for landascaping mode. Althought I agree with alextsc but in this case looks like Android platform doesn't redraw accurately in portrait mode.
I can't to publish an image because I'm newbie posting here, but running this code you can check the anomaly and seems be related with the method drawRect.
I am using RelativeLayout to position views at precise locations on the screen. This works as expected when using a view that say, draws a rectangle. But when using Android views like EditText, they are drawn shorter than specified by about 8 units. Clicking outside of the drawn EditText (but within the parameters specified by RelativeLayout) will, in fact, hit the EditText.
Here is some code to illustrate what I mean:
package com.DrawDemo;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.RelativeLayout;
public class DrawDemo extends Activity
{
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
RelativeLayout l = new RelativeLayout(this);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(100,100);
lp.leftMargin = 50;
lp.topMargin = 50;
DemoView demoview = new DemoView(this);
l.addView(demoview, lp);
EditText editText = new EditText(this);
l.addView(editText, lp);
setContentView(l);
}
private class DemoView extends View
{
public DemoView(Context context)
{
super(context);
}
#Override protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.GREEN);
canvas.drawPaint(paint);
}
}
}
If you execute this, you will notice that the EditText is noticeably shorter than the rectangle. I've tried mucking with onMeasure, setMinimumXXX, and just about everything else I can think of. So far, the only thing that works with some level of success is to just add 8 or so pixels to the height (8 seems to work better than trying a percentage of the height).
Next task will be to step into the source but was wondering if somebody has already solved this.
Thanks.
It's just because of the actual EditText background image that's used. Buttons are the same way, for some reason Google decided to draw the 9-patch background images with some extra transparent padding pixels. Really, the only solution, if it's a problem, would be to draw your own 9-patch, or modify the existing Android 9-patch to remove the extra pixels.