android - animating a shape - java

After creating a shape i don't know how to set up an animation. The circle I create is in the center of the screen and should move to the right margin. Can someone explain how to animate it?
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Bitmap bg = Bitmap.createBitmap(480, 800, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas (bg);
paint.setAntiAlias(true);
canvas.drawCircle(canvas.getWidth()/2, (float) (canvas.getHeight()/1.8), 13, paint);

You can do a simple view animation by creating an xml with animation requirements. Apply the animation on OnViewCreated() method to the required object.
Check view animation here: https://developer.android.com/guide/topics/graphics/view-animation.html
Example: if you want to animate nfcTerminal object, then just create nfc_terminal_bounce.xml with translate and alpha properties.
Sample code:
nfcTerminal.startAnimation(AnimationUtils.loadAnimation(getContext(), R.anim.nfc_terminal_bounce));

Related

Android Canvas not rendering Framelayout

I'm trying to draw a FrameLayout onto a canvas, but I can't get it to work. Drawing an ImageView works fine, so I'm not sure what I'm missing.
Here's an example of one way I'm trying to draw a FrameLayout:
#Override
protected void onDraw(Canvas canvas) {
Context activity = this.getContext();
FrameLayout.LayoutParams cellParams = new FrameLayout.LayoutParams(100, 100);
ImageView cloud = new ImageView(activity);
cloud.setLayoutParams(cellParams);
cloud.setImageResource(R.drawable.transparent_cloud_large);
FrameLayout gameTile = new FrameLayout(activity);
gameTile.addView(cloud);
gameTile.layout(100, 200, 200, 300);
gameTile.draw(canvas);
}
I'm also trying it without setting LayoutParams for the ImageView, and instead using: cloud.layout(0, 0, 100, 100);, but neither way works.
Here's my code for the ImageView, which does work.
#Override
protected void onDraw(Canvas canvas) {
Context activity = this.getContext();
ImageView image = new ImageView(activity);
image.setImageResource(R.drawable.transparent_cloud_large);
image.layout(100, 100, 200, 200);
image.draw(canvas);
}
Do I need to override the FrameLayout's draw method in some way? Why doesn't it work out of the box?
I see that the javadocs say "The view must have already done a full layout before this function is called." Maybe that's my problem? How do I "do a full layout" on a FrameLayout?
I got it to work. It was missing a call to measure. This is what I'm using in the end:
GameTile gameTile = square.getGameTile();
gameTile.measure((int)tilePixels, (int)tilePixels);
gameTile.layout(0, 0, 0, 0);
canvas.save();
canvas.translate(coor.getX() * tilePixels, coor.getY() * tilePixels);
gameTile.draw(canvas);
canvas.restore();
GameTile is a subclass of FrameLayout. The save, translate, and restore methods are used to position the FrameLayout on the canvas.

Creating transparent circle cutout in a View in Android

I'm trying to create a translucent help overlay to be displayed over my activity's main screen when the user first opens the app. I would like to highlight a button contained in the main layout (and inflated using setContentView), by "cutting out" a section of the overlay which corresponds to the position of the button, and make the cutout transparent.
The overlay is a programmatically-created view (which extends RelativeLayout) which is added to my activity's main FrameLayout, like this:
private void addHelpOverlay(){
HelpOverlay help = new HelpOverlay(this);
help.setBackgroundColor(Color.parseColor("#BB222222"));
mainLayer.addView(help);
}
public class HelpOverlay extends RelativeLayout{
public HelpOverlay(Context context){
super(context);
}
#Override
public void dispatchDraw(Canvas canvas){
canvas.drawColor(Color.parseColor("#BB222222"));
Paint mPaint = new Paint();
mPaint.setColor(0xFFFFFF);
mPaint.setAlpha(0);
mPaint.setAntiAlias(true);
canvas.drawCircle(buttonX, buttonY, 100, mPaint);
super.dispatchDraw(canvas);
}
}
The above code doesn't actually show anything, just the translucent layout with no circle cutout. I assume this is because it's just drawing a transparent circle over top of the translucent layout. I'm really struggling to accomplish this, any suggestions would be appreciated!
Try adding PorterDuff to your paint object . which will make the specific area to transparent
Paint mPaint = new Paint();
mPaint.setColor(0xFFFFFF);
mPaint.setAlpha(0);
mPaint.setAntiAlias(true);
mPaint.setColor(Color.TRANSPARENT);
mPaint.setXfermode(new PorterDuffXfermode(
PorterDuff.Mode.CLEAR));
canvas.drawCircle(buttonX, buttonY, 100, mPaint);
If you get a picth black in the circle area, that must be due to graphic rendering problem , you can enable it using below code right before you declare paint object .
if (android.os.Build.VERSION.SDK_INT >= 11) {
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
I guess this should fix your issue

Drawing Mulitple Views with Paths (Android)

I've been having a lot of issues drawing multiple paths in the same relative layout. What happens is that all my paths are drawn on the same spot they were originally drawn. Instead I want to shrink each drawn path/canvas and have them displayed side by side on the page.
My code to draw the paths looks like
for (int x=0; x < paths.size(); x++){
DrawView dw = new CustomView(this);
dw.path = paths.get(x);
dw.paint = paints.get(x);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
if (x == 0){
} else {
params.addRule(RelativeLayout.BELOW, x-1);
}
dw.setId(x);
layout.addView(dw, params);
}
I followed other suggestions for TextViews to add an custom layout parameter to display each TextView below each other but this does not appear to work for dynamically drawn paths.
Note: CustomView is a class that extends View and overwrites the onDraw method to draw out my paths.
EDIT:
If it helps my custom class looks like
public class CustomView extends View {
public Path path;
public Paint paint = new Paint();
public CustomView(Context context){
super(context);
paint.setAntiAlias(true);
paint.setColor(Color.BLACK);
paint.setStyle(Paint.Style.STROKE);
}
#Override
protected void onDraw(Canvas canvas){
canvas.drawPath(path, paint);
}
}
Is it necessary for you to use a RelativeLayout? If it is not too binding, consider having a LinearLayout which either replaces the RelativeLayout, or is contained within the RelativeLayout. Then you can add all the CustomViews to this LinearLayout, setting the weight field in LinearLayout.LayoutParams to 1.
Alternatively, consider manually setting each CustomView's height to getHeight()/(paths.size()) instead of RelativeLayout.LayoutParams.WRAP_CONTENT.

Allow user to draw on Canvas

I am trying set up a kids app where the can draw on a canvas.
I have a layout which has an ImageView and looks something like this:
The Green background with the letter is the imageview, where the canvas should overlay and allow user to draw on. Also I want to allow the user to change the color stroke by pressing on the color globe.
How can I go on with it?
This answer here might help you with allowing the user the canvas: https://stackoverflow.com/a/7401699/2698582.
To allow the user to draw in different colors, you can use a color picker such as this one: https://code.google.com/p/android-color-picker/, or you can google for a different one.
If you define a new point class and change a bit of this example code, you'll be able to add this color change:
private class ColoredPoint {
public int x, y, color = Color.BLACK;
}
public class DrawView extends View implements OnTouchListener {
List<ColoredPoint> points = new ArrayList<ColoredPoint>();
Paint paint = new Paint();
int currentColor = Color.BLACK;
public DrawView(Context context) {
super(context);
setFocusable(true);
setFocusableInTouchMode(true);
this.setOnTouchListener(this);
paint.setColor(currentColor);
}
#Override
public void onDraw(Canvas canvas) {
for (ColoredPoint point : points) {
paint.setColor(point.color);
canvas.drawCircle(point.x, point.y, 2, paint);
}
}
public boolean onTouch(View view, MotionEvent event) {
ColoredPoint point = new ColoredPoint();
point.color = currentColor;
point.x = event.getX();
point.y = event.getY();
points.add(point);
invalidate();
return true;
}
}
Finally, depending on your selected color picker, this code will vary. Basically, you'll add a touch listener to your color globe to show the color popup. Supposing that the popup has an "OK" button, you'll add a button listener to that button. When it is pressed, change the variable "currentColor" to the selected color.
As mentioned in that example post, you can also implement this using Lines. You might consider using a GestureDetector instead. This tutorial should help explain exactly how the GestureDetector works: http://developer.android.com/training/gestures/detector.html.
Take linearlayout and transfer imageview into linearlayout background color. Add your custom view into this linearlayout, and override ondraw method to that view class.
something like this:
<LinearLayout
background:#drawable/foo">
<com.packagename.customview
android:width="match_parent"
android:height="value">
>
</com.packagename.customview>
</LinearLayout>
create customview class and implement drawing part into it.
For the color picker, just use this link: https://code.google.com/p/android-color-picker/

Android zoom canvas in and out on surface view with multiple bit maps drawn with onDraw()

I have a canvas / surfaceview that I am drawing multiple bitmaps so that the user is able to drag around and position anywhere on the canvas. I am looking for a method to create a zoom in and out button that toggles a 50% zoom scale of the canvas when selected.
My app draws multiple bitmaps to the canvas using the onDraw() method.
I have a function now that scales each individual bitmap when the zoom button is toggled but the problem with this is getting the bitmaps to line up relative to each other after the scale. I currently have them scaled off their ending x/y position but by reducing the size 50% the items that were once near each other are no longer that way when zoomed out. I am hoping there is a solution that allows me to accomplish this with the entire canvas at once.
If I need to share some code please let me know.
SurfaceView class where all the drawing happens
public class BuildView extends SurfaceView implements SurfaceHolder.Callback {
then non-scaling drawing happens as canvas.drawBitmap(myBitmap,x,y,null);
Here is my oncreate method, note that BuildView gameView; is initating my surfaceview class;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Set full screen view
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
requestWindowFeature(Window.FEATURE_NO_TITLE);
FrameLayout Game = new FrameLayout(this);
LinearLayout GameWidgets = new LinearLayout (this);
gameview = new BuildView(this, null);
//create buttons to lay over the surfaceview
Button AddItemButton = new Button(this);
//Button ZoomInButton = new Button(this);
zoomButton = new Button(this);
TextView MyText = new TextView(this);
AddItemButton.setWidth(250);
AddItemButton.setText("Add Item");
AddItemButton.setId(1);
AddItemButton.setOnClickListener(addItemHandler);
MyText.setText("test");
zoomButton.setWidth(250);
zoomButton.setText("Zoom Out");
zoomButton.setId(2);
zoomButton.setOnClickListener(zoomHandler);
// adding views to the main Game framelayout view * note the view "gameview" is the surface view that everything happens on
GameWidgets.addView(AddItemButton);
GameWidgets.addView(zoomButton);
Game.addView(gameview);
Game.addView(GameWidgets);
int w=getWindowManager().getDefaultDisplay().getWidth()-25;
int h=getWindowManager().getDefaultDisplay().getHeight()-25;
gameview.wid = w; //set width and height in view
gameview.hei = h;
gameview.setWidthHeight(w, h);
setContentView(Game); //trying this out
gameview.updateImage(0, 0); //force bg change
Log.i("views", "Added Game View");
//setContentView(v);
}
since it has been requested here is how I am currently scaling the bitmaps, note that I am looking for another method of scaling the entire canvas. Here is the specifics of my onDraw() method but the full method has more logic in regards to item placement and before scaling I check a boolean flag if the user has selected to scale but i figured you wouldn't want to sift through that much code so I am just putting the pertinent stuff here.
protected void onDraw(Canvas canvas) {
float scaleHeight = getScaled(myBitmap.getHeight());
float scaleWidth = getScaled(myBitmap.getWidth());
scaler.postTranslate(-myBitmap.getWidth() / 4, -itemBit.getHeight() / 4); // Centers image
scaler.postScale(scaleWidth, scaleHeight);
Log.e("onDraw", "item not placed - scaler.postTranslate being called");
scaler.postTranslate(itemX+myBitmap.getWidth()/2, itemY+myBitmap.getHeight()/2);
canvas.drawBitmap(myBitmap, scaler, null);
}
here is my getScaled function;
float getScaled(int orig) {
//return a scaled version
int newScale = orig /2;
float scaled = ((float) newScale) / orig;
return scaled;
}

Categories

Resources