Using an Android Drawable as an AndEngine HUD - android

I'm trying to create an AndEngine HUD that will sit on top of a TMXTiledMap (bear with me, I'm very new to AndEngine). To keep things simple at first, I have a simple rectangle created via Android drawables. The idea is that this will sit at the bottom center of the screen and never move, even as the map underneath it is moved in various directions. For now, all I want to do is get that rectangle to show up. Later on I'll add other functionality to the rectangle.
My drawable is created like this:
?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<corners
android:radius="7dp" />
<gradient
android:startColor="#343434"
android:endColor="#17171717"
android:angle="270"
android:useLevel="false"
android:type="linear" />
<padding
android:left="10dp"
android:top="10dp"
android:right="10dp"
android:bottom="10dp" />
</shape>
And I have it pulled into a layout like this:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/container"
android:layout_width="300dip"
android:layout_height="100dip"
android:orientation="horizontal"
android:layout_marginLeft="20dp"
android:background="#drawable/menu_bkgrnd" >
</LinearLayout>
And then finally, here is where I try to pull it in as a HUD:
rect = new HUD();
ITouchArea container = (ITouchArea) findViewById(R.id.container);
this.rect.registerTouchArea(container);
rect.attachChild((IEntity) container);
As you can see, I'm doing a lot of casting to satisfy AndEngine, but when I run this, the map is totally screwed up. Am I going about this correctly? Is my casting incorrect? (or maybe both!).
Thanks for any help.
EDIT:
Based on the code that Jong and 正宗白布鞋 suggested below, I've adjusted my Java code as follows:
this.atlas = new BitmapTextureAtlas(null, 256, 256, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
this.atlas.load();
ITextureRegion drawable = BitmapTextureAtlasTextureRegionFactory.createFromResource(atlas, getApplicationContext(), R.drawable.myDrawable, 0, 0);
rect.attachChild(new Sprite(0, 0, drawable, this.getVertexBufferObjectManager()));
At this point, I'm still just trying to get this to appear on the screen. I'll adjust size and location later.
Everything compiles and runs without error, however my screen is just a total mess.
As you can see, I had to make a couple of small adjustments to the constructor arguments to get AndEngine to accept my instantiations. Not sure if I'm doing this correctly.
The other issue that I see in this code is that it appears to me that this code is just going to place an inactive shape on my screen. I know that in my original post, I said that my immediate goal is to make this rectangle show up, but I think that it has to show up as a registered touch area since it will ultimately be something with controls on it that need to respond to user commands. Sorry if I overly minimized what I am trying to do.
I'm still not getting this. Anybody have any suggestions? Thanks again!

You can't cast LinearLayout to ITouchArea, ITouchArea is an interface implemented by AndEngine classes only.
Like 正宗白布鞋 suggested, you should use the createFromResource method of BitmapTextureAtlasTextureRegionFactory.
You can use this code:
BitmapTextureAtlas atlas = new BitmapTextureAtlas(sizeX, sizeY, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
TextureRegion drawable = BitmapTextureAtlasTextureRegionFactory.createFromResource(atlas, getApplicationContext(), R.drawable.drawableId, 0, 0);
rect.attachChild(new Sprite(x, y, drawable));
EDIT:
If you want your sprite to respond to touch events, you can register it as a touch area in your rect HUD.
Sprite sprite = new Sprite(x, y, drawable, getVertexBufferObjectManager()) {
#Override
public boolean onAreaTouched(final TouchEvent pTouchEvent, final float pX, final float pY) {
//Do what you want here
}
}
rect.registerTouchArea(sprite);
rect.attachChild(sprite);

I had the same problem several days ago, and I couldn't find a proper answer. So now that I've gathered information from different sources, here is how I dealt with this.
AFAIK, it appears that the method createFromResource(atlas, getApplicationContext(), R.drawable.drawableId, 0, 0) from BitmapTextureAtlasTextureRegionFactory cannot deal with XML drawable (such as <shape>...</shape>).
Indeed, when I was only displaying a colored rectangle, everything was fine - and I think with a PNG file too -, but when I tried to create a Sprite from my XML drawable, I always got a NullBitmapException when the drawing happened.
Steps I took:
Convert drawable resource to Drawable
Convert Drawable to Bitmap (Source here)
Convert Bitmap to TextureRegion (This is where I used this)
Create a Sprite from the TextureRegion (or two for selected/unselected, like here)
Attach the Sprite to the game's HUD
So, with code:
Convert drawable resource TextureRegion
/**
* Takes a drawable, and converts it to a TextureRegion.
* #param context
* #param resId the drawable ID
* #param textureSizeX width for our TextureRegion
* #param textureSizeY height for our TextureRegion
* #return a TextureRegion from the drawable
*/
public static TextureRegion textureRegionFromDrawable(BaseGameActivity context, int resId, int textureSizeX, int textureSizeY) {
Drawable drawable = context.getResources().getDrawable(resId);
Bitmap bitmap = drawableToBitmap(drawable);
BitmapTextureAtlasTextureSource source = new BitmapTextureAtlasTextureSource(bitmap);
BitmapTextureAtlas textureAtlas = new BitmapTextureAtlas(context.getTextureManager(), textureSizeX, textureSizeY);
textureAtlas.addTextureAtlasSource(source, 0, 0);
textureAtlas.load();
TextureRegion textureRegion = (TextureRegion) TextureRegionFactory.createFromSource(textureAtlas, source, 0, 0);
return textureRegion;
}
// Drawable to Bitmap
public static Bitmap drawableToBitmap(Drawable drawable) {
if (drawable instanceof BitmapDrawable) {
return ((BitmapDrawable) drawable).getBitmap();
}
Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
}
The utility intermediary class
public class BitmapTextureAtlasTextureSource extends BaseTextureAtlasSource implements IBitmapTextureAtlasSource {
private final int[] mColors;
public BitmapTextureAtlasTextureSource(Bitmap pBitmap) {
super(0, 0, pBitmap.getWidth(), pBitmap.getHeight());
mColors = new int[mTextureWidth * mTextureHeight];
for (int y = 0; y < mTextureHeight; ++y) {
for (int x = 0; x < mTextureWidth; ++x) {
mColors[x + y * mTextureWidth] = pBitmap.getPixel(x, y);
}
}
}
#Override
public Bitmap onLoadBitmap(Config pBitmapConfig) {
return Bitmap.createBitmap(mColors, mTextureWidth, mTextureHeight, Bitmap.Config.ARGB_8888);
}
#Override
public IBitmapTextureAtlasSource deepCopy() {
return new BitmapTextureAtlasTextureSource(Bitmap.createBitmap(mColors, mTextureWidth, mTextureHeight, Bitmap.Config.ARGB_8888));
}
#Override
public Bitmap onLoadBitmap(Config pBitmapConfig, boolean pMutable) {
// TODO Auto-generated method stub
return null;
}
}
Create two Sprite from the TextureRegions (I wanted 2 states for my button: selected/unselected), and attach them to the HUD
int textureSizeX = 512, textureSizeY = 512;
TextureRegion textureDefault = AndEngineUtils.textureRegionFromDrawable(activity, R.drawable.custom_menu_button, textureSizeX, textureSizeY);
TextureRegion textureSelected = AndEngineUtils.textureRegionFromDrawable(activity, R.drawable.custom_menu_button_selected, textureSizeX, textureSizeY);
mGameHUD = new HUD();
// 2 sprites for selected and unselected
final Sprite buttonUnselected, buttonSelected ;
buttonSelected = new Sprite(0, 0, textureSelected, activity.getVertexBufferObjectManager());
buttonSelected.setVisible(false);
buttonUnselected = new Sprite(0, 0, textureDefault, activity.getVertexBufferObjectManager()) {
#Override
public boolean onAreaTouched(TouchEvent pSceneTouchEvent, float pTouchAreaLocalX, float pTouchAreaLocalY) {
switch (pSceneTouchEvent.getAction()) {
case TouchEvent.ACTION_DOWN:
// Change button
buttonSelected.setVisible(true);
this.setVisible(false);
break;
case TouchEvent.ACTION_UP:
// reset button
this.setVisible(true);
buttonSelected.setVisible(false);
break;
default:
break;
}
return super.onAreaTouched(pSceneTouchEvent, pTouchAreaLocalX, pTouchAreaLocalY);
}
};
mGameHUD.attachChild(buttonSelected);
mGameHUD.attachChild(buttonUnselected);
mGameHUD.registerTouchArea(buttonUnselected);
camera.setHUD(mGameHUD);
We can also make use of scene.setOnAreaTouchListener(touchListener) in order for an "unwanted" sliding gesture - until outside of the button - to take effet to reset the button color (see this thread).
I have just begun using AndEngine and I am not yet familiar with best practices, so feel free to correct me.

Related

Android TransitionDrawable not fading

I have an ImageView and I am trying to fade from one image to the next using this code:
Drawable bgs[] = new Drawable[2];
public void redraw(int[][] grid) {
bgs[0] = bgs[1];
bgs[1] = new GameDrawable(grid, prefs.colors);
if (bgs[0] == null) {
gameField.setImageDrawable(bgs[1]);
} else {
TransitionDrawable crossfader = new TransitionDrawable(bgs);
crossfader.setCrossFadeEnabled(true);
gameField.setImageDrawable(crossfader);
crossfader.startTransition(500);
}
}
gameField is correctly referenced as an ImageView.
gameDrawable simply extends Drawable and draws the grid.
On each move and action the new GameDrawable is being rendered correctly but there is no fading whatsoever. The new image is simply displayed instantaneously. I have tried lengthening the transition time and swapping the order of the drawables with no effect.
Any help on is appreciated.
Update: I have now set my transition to something ridiculously long like 500000. The first drawable shows for a few seconds and then suddenly the second drawable appears. So still no transition.
Update 2:
I think my Drawable might be implemented incorrectly, so I have attached the code.
public class GameDrawable extends Drawable {
private Paint paint = new Paint();
private float blockWidth = 1;
private int[][] myGrid;
private int myColor;
private List<Point> myPoints;
public GameDrawable(int[][] grid) {
super();
this.myGrid = grid;
this.myColor = colors[yourColor];
paint.setStrokeWidth(1);
paint.setStyle(Paint.Style.FILL);
paint.setAlpha(0);
this.myPoints = yourPoints;
}
#Override
public void draw(Canvas canvas) {
float height = getBounds().height();
float width = getBounds().width();
blockWidth = width / myGrid.length;
if (height / myGrid.length < blockWidth) {
blockWidth = height / myGrid.length;
}
for (int x = 0; x < myGrid.length; x++) {
for (int y = 0; y < myGrid[x].length; y++) {
paint.setColor(colors[myGrid[x][y]]);
canvas.drawRect(x * blockWidth, y * blockWidth, (x+1)*blockWidth, (y+1)*blockWidth, paint);
}
}
}
#Override
public void setAlpha(int alpha) {
paint.setAlpha(alpha);
invalidateSelf();
}
#Override
public void setColorFilter(ColorFilter cf) {
paint.setColorFilter(cf);
invalidateSelf();
}
#Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
}
Looking at your code, I see a problem at the line
bgs[0] = bgs[1];
bgs[1] has not yet been defined before this line and so bgs[0] is null for the first method call. Because of this, (bgs[0] == null) is true, and so the later defined bgs[1] is directly set to the gameField ImageView.
Use corrected code below.
Drawable bgs[] = new Drawable[2];
Drawable firstDrawable = getResources().getDrawable(R.drawable.transparent);
public void redraw(int[][] grid) {
bgs[0] = firstDrawable;
bgs[1] = new GameDrawable(grid, prefs.colors);
firstDrawable = bgs[1];
TransitionDrawable crossfader = new TransitionDrawable(bgs);
crossfader.setCrossFadeEnabled(true);
gameField.setImageDrawable(crossfader);
crossfader.startTransition(500);
}
Note that TransitionDrawable does not work properly when the Drawable sizes are different. So you may need to resize firstDrawable beforehand.
EXTRA: I would avoid setCrossFadeEnabled(true) since the whole TransitionDrawable becomes translucent during the transition, revealing the background. Sometimes, this creates a "blinking" effect and destroys the smoothness of the transition.
EDIT: Looking at your custom Drawable implementation, I think the problem lies in the line
canvas.drawColor(Color.WHITE);
in the draw() method.
I looked at TransitionDrawable.java source and found that setAlpha is called on the drawables to get the cross fade effect. However, your canvas has a solid white color and setAlpha() only affects the paint. Hope this is your answer.
EDIT 2: The actual problem, as pointed out by Michael, was that TransitionDrawable's setAlpha() calls on the Drawables were rendered ineffective due to paint.setColor() in the GameDrawable's draw() method overriding the paint's alpha value set by the TransitionDrawable.

Advanced view animation in Android

I'm developing an app for Android with beautiful, but hard-to-implement design with tons of custom animations. Now I need to implement animation for button, it must be dynamic glance animation that affects both button border and its text, and must move from left to right. Here is an example of such animation in iOS app.
So I hope you catched the main idea. I tried to use Property Animation, but it's not what I really need. Also I found many custom libraries and tried a lot of examples from SDK, but there are nothing similar.
So if you know how it can be do, answer me.
I get the pre-rendered animation with a sequence of PNG files and then use the AnimationDrawable to display it.
try this wrapper class:
class FL extends FrameLayout implements ValueAnimator.AnimatorUpdateListener {
private static final int W = 200;
private final LinearGradient gradient;
private final Paint paint;
private float x;
public FL(View child) {
super(child.getContext());
addView(child);
int[] colors = {0, 0xaaffffff, 0};
gradient = new LinearGradient(0, 0, W, 0, colors, null, Shader.TileMode.CLAMP);
paint = new Paint();
paint.setShader(gradient);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP));
x = -W;
}
#Override
protected void dispatchDraw(Canvas canvas) {
canvas.saveLayer(null, null, 0);
super.dispatchDraw(canvas);
canvas.translate(x, 0);
float h = getHeight();
canvas.rotate(20, W / 2, h / 2);
canvas.drawRect(0, -h, W, 2 * h, paint);
canvas.restore();
}
#Override
public void onAnimationUpdate(ValueAnimator animation) {
x = (int) animation.getAnimatedValue();
invalidate();
}
public void startMagic() {
ValueAnimator a = ValueAnimator.ofInt(-W, getWidth());
a.addUpdateListener(this);
a.setDuration(1000).setInterpolator(new AccelerateDecelerateInterpolator());
a.start();
}
}
round_frame.xml is:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="20dp" />
<stroke android:color="#a00" android:width="4dp" />
</shape>
and test it with the following in onCreate:
Button b = new Button(this);
final FL fl = new FL(b);
b.setTextSize(28);
b.setTextColor(0xffaa0000);
b.setText("click me to see the magic");
b.setBackgroundResource(R.drawable.round_frame);
View.OnClickListener listener = new View.OnClickListener() {
#Override
public void onClick(View v) {
fl.startMagic();
}
};
b.setOnClickListener(listener);
addContentView(fl, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
NOTE: if you want it to use it in the Button only, you don't have a FL wrapper: you can extend Button class and override drawing methods as i did in FL wrapper class
I finished my custom implementation of this.
The result so far :
This is obtained by transferring an animated gradient Shader on the static TextView
You can get the source code on the following Gist : ShinnyTextView
The current version does not support XML customization, but you can adapt the values in the code.
If you are using this, you might want to have a more precise control on when to pause/restart the animation to avoid the ani

Scaling Bitmaps Without Throwing Quality

I have created an app that actually uses flood fill algorithm to fill colors in bitmaps. I have created some bitmaps (200x200) but I don't know the exact size of bitmap that I should create, I want bitmaps to cover full screen and when I scale bitmaps, they become blur and flood fill doesn't work on them. I saw an app that used GridView to show images and click on image started new activity with image covering full screen. How can I achieve this. Attached is CustomImage that I've use to show bitmap. Any help will be appreciated.
EDITED: I know that GridView doesn't scale up image to full screen, it use another image. That app behaves same for different screen size, those image fill screen of any size without effecting the quality.
public class CustomImage extends View {
public CustomImage(Context context) {
super(context);
} // end constructor
public CustomImage(Context context, int resource_id) {
super(context);
mPaint = new Paint();
mPaint.setColor(Color.WHITE);
mPoint = new Point();
mProgressIndicator = (ProgressIndicator) context;
mBitmap = BitmapFactory.decodeResource(getResources(), resource_id)
.copy(Bitmap.Config.ARGB_8888, true);
} // end constructor
#Override
protected void onDraw(Canvas canvas) {
// draw image
canvas.drawBitmap(mBitmap, 0, 0, mPaint);
} // end onDraw
#Override
public boolean onTouchEvent(MotionEvent event) {
int bWidth = mBitmap.getWidth();
int bHeight = mBitmap.getHeight();
mPoint.x = (int) event.getX();
mPoint.y = (int) event.getY();
mPoint.x = (mPoint.x > bWidth) ? (bWidth - 5) : mPoint.x;
mPoint.y = (mPoint.y > bHeight) ? (bHeight - 5) : mPoint.y;
switch (event.getAction()) {
// called when screen clicked i.e New touch started
case MotionEvent.ACTION_DOWN:
mProgressIndicator.updateProgress(0);
new Filler(mBitmap, mPoint, mPaint.getColor(), mBitmap.getPixel(
mPoint.x, mPoint.y), this).execute();
invalidate();
} // end Case
return true;
} // end onTouchEvent
public void setColor(int color) {
mPaint.setColor(color);
} // end setColor
} // end Class
The GridView you have seen might be using two versions of the same image. One as a big image and another as a scaled down thumbnail image for the grid.

Android: Making Bitmaps Disappear When Touched

As is, 100 pink circles (same bitmap) appear scattered randomly over the phone screen (as is supposed to). When I tap one of the circles, that circle should disappear (change to the background color). I think I have a fundamental misunderstanding of Android and View in general.I think I have a couple obvious errors (that are not so obvious to me, but I've been staring at it so long that I figured I needed some help). Currently, the screen shows the random circles but nothing more. Touching the screen does nothing. Any better ideas to make the circles disappear? It recently reorganized all the bitmaps when you touched it, but I did something recently, and it stopped. The bitmap is 30px by 30px.
public class DrawV extends View {
private Bitmap bit_dot;
private int width;
private int height;
public int[] width_array = new int[100];
public int[] height_array = new int[100];
private View dotV = (View)findViewById(R.id.bigdocpic);//bitmap
Random rand = new Random();
public DrawV(Context context) {
super(context);
bit_dot = BitmapFactory.decodeResource(getResources(), R.drawable.dot_catch);
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
width = metrics.widthPixels;
height = metrics.heightPixels;
}
#Override
//draws 100 randomly placed similar bitmaps
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int height_dimension;
int width_dimension;
for (int i = 0; i < 100; i++){
height_dimension = rand.nextInt(height) + 1;
width_dimension = rand.nextInt(width) + 1;
canvas.drawBitmap(bit_dot, width_dimension, height_dimension, null);
width_array[i] = width_dimension;//
height_array[i] = height_dimension;//
}
}
#Override
public boolean onTouchEvent(MotionEvent event){
Paint p = new Paint();
p.setColor(Color.WHITE);
Path path = new Path();
Canvas c = new Canvas();
for (int i = 0; i < 100; i++){
if ((event.getX() == width_array[i]) && (event.getY() == height_array[i]))
c.drawCircle(width_array[i], height_array[i], 15, p);
}
invalidate();
return false;//false or true?
}
//set visibility of bitmap to invisible
public boolean onTouch(View v, MotionEvent event) {
dotV.setVisibility(View.INVISIBLE);
invalidate();
return false;//false or true? not understanding
}}
Help?
Your onTouchEvent isn't really doing anything important as-is, and you don't have the concept of a circle object.
onDraw should really be drawing these circles from an array/list created earlier - say a List<MyCircles> or MyCircles[]. On touch, you could iterate through all of your circles until you find one that is closest, remove that circle from the array or list, then invalidate.
The reason nothing is happening at all is even though you're drawing those circles again in onTouchEvent, you're redrawing everything yet again in onDraw (invalidate() calls draw/onDraw).
Ideally, create your list of circles in your initializer, draw them in onDraw, and update them in onTouch (That is, delete). There may be a simpler way to do this but this is, at the very least, a more proper approach.

Moving "Cloud" - Radial Gradient moving with finger

First Q. I have working code to make this move elsewhere in the file -- that's not the question. The question is how do I create a Radial Gradient that can be moved (below API 16).
Preempting snark, I've spent a lot of time here:
http://developer.android.com/reference/android/graphics/drawable/GradientDrawable.html
With GradientDrawable (below), there doesn't seem to be a way to set the colors without also setting a non-radial orientation.
public class CustomView extends View {
int width = (sWidth/8); // sWidth defined elsewhere as width of screen
int height = (sWidth/8);
GradientDrawable gradient;
int[] colors = {0x60ffffff,0x000000};
public CustomView(Context context) {
super(context);
gradient = new GradientDrawable(GradientDrawable.Orientation.BL_TR,colors);
}
protected void onDraw(Canvas canvas) {
if(x != 0 && y != 0){ // OnTouch calls invalidate on this view for movement
gradient.mutate();
gradient.setShape(GradientDrawable.RADIAL_GRADIENT);
// This just makes it disappear:
// setGradientType (GradientDrawable.RADIAL_GRADIENT);
gradient.setBounds(x-width/2, y-height/2, x + width, y + height);
gradient.draw(canvas);
}
}
}
There is also this:
http://developer.android.com/reference/android/graphics/RadialGradient.html
But there seems to be no way to move that gradient. Can you maybe put the radial gradient on a transparent circle of some kind that can then be moved? I'm at a loss. My thanks in advance.
Edit:
Step 1, define an oval shape in your drawable folder. This one is "cloud.xml":
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval" >
<gradient
android:centerX="0.5"
android:centerY="0.5"
android:endColor="#00000000"
android:gradientRadius="30"
android:startColor="#f0ffffff"
android:type="radial" />
<size
android:width="60dp"
android:height="60dp" />
</shape>
The radius, width and height will likely need to be changed dynamically. So put whatever. The color scheme above will give a slightly transparent color to fully transparent. Cloud effect.
Step 2, the constructor of your custom view:
// actually before the constructor this, of course:
GradientDrawable circle;
// now the constructor:
circle = (GradientDrawable) context.getResources().getDrawable(R.drawable.cloud);
Step 3, the onDraw method:
// x & y being coordinates updated from onTouch method,
// circleRad being some constant dependent on screen dp
if(x != 0 && y != 0){
circle.setGradientRadius(circleRad);
circle.setBounds(x-circleRad, y-circleRad,
x+circleRad, y+circleRad);
circle.draw(canvas);
}
------------- Original, Less Process Efficient Solution Preserved Below -----------
Wait a couple weeks and you can answer your own questions. Turns out it was RadialGradient the whole time.
public class CustomView extends View implements OnTouchListener {
Shader radialGradientShader;
Paint paint;
private int circleDiam;
private int x = 0;
private int y = 0;
private int lastScreenColor;
public CustomView(Context context, int circleDiam) {
super(context);
this.circleDiam = circleDiam;
paint = new Paint();
}
protected void onDraw(Canvas canvas) {
if(x != 0 && y != 0){
paint.setStyle(Paint.Style.FILL);
paint.setAntiAlias(true);
radialGradientShader = new
RadialGradient(x, y, circleDiam,
0xf0ffffff,0x00000000,Shader.TileMode.MIRROR);
paint.setShader(radialGradientShader);
canvas.drawCircle(x, y, circleDiam, paint);
}
}
public boolean onTouch(View v, MotionEvent event) {
x = (int)event.getX();
y = (int)event.getY();
if(event.getAction() == MotionEvent.ACTION_DOWN
&& event.getAction() == MotionEvent.ACTION_MOVE){
invalidate();
return true;
}
else{
x = 0;
y = 0;
invalidate();
return false;
}
}
}
A fluffy cloud!
The only problem with this solution is that Eclipse gets mad when you instantiate an object in the onDraw method. However, if you try to instantiate it in the constructor things get ugly fast.
Extra points for a solution that avoids said problem.

Categories

Resources