Prmths
Prmths

Reputation: 2032

drawing and animating in android

first off, this is more of a question about animating than a specific problem coding. i need to fill in the broad strokes left by the research i've been doing.

what i'm trying to do:

the activity should load with only the a togglebutton visible. when the button is touched, a png will be animated to a certain position relative to the togglebutton. also, another button will slide in from off screen and slide off if/when the togglebutton is pressed again.

what i can't figure out:

i can draw an image, but only via xml. creating an imageview and setting the background programmatically does nothing.

when i draw from xml, i can't move the image when the togglebutton is pressed like i want to. when i call getPositionOnScreen() i get a null pointer, even though the complier can see i'm referring to the imageview described in both xml and in code.

i'm calling getPositionOnScreen because via xml, i have the image positioned behind the togglebutton so that it's not visible until the button has been pressed and the image starts moving. the idea is that with different screen sizes i won't know exactly where the view is until runtime. getPostionOnScreen allows me to get the coordinates of the imageview so i know where it has been positioned. when i have a start position, can tell it to "move up" on the screen from behind the togglebutton by simply adding to x or y until it's where i want.

this is the code to draw the image (inserted in the onCreate method).

image= (ImageView) new ImageView(this);
  image.setImageResource(R.drawable.pic); 

this is the code i'm using to animate. when the button is clicked, it calls this method on the view from the listener.

private void activate(){

  int loc[] = new int [2];
  image.getLocationOnScreen(loc);
  int fromXDelta = loc[0];
     int fromYDelta = loc[1];
  int toYDelta = fromYDelta;
     int toXDelta = fromXDelta - 30;

  TranslateAnimation translateAnimation = new TranslateAnimation
  (-fromXDelta, -toXDelta, -fromYDelta, -toYDelta);
     translateAnimation.setDuration(500);
     translateAnimation.setFillEnabled(true);

     image.startAnimation(translateAnimation);

 }

i'm well aware that this is horribly wrong and won't work. what i need to understand is why. any help would be very welcome.

Upvotes: 1

Views: 1591

Answers (1)

Octavian Helm
Octavian Helm

Reputation: 39605

Alright the first point. If you are creating a new ImageView object that way (by using new) you don't have to cast it to 'ImageViewmanually as it already is a fresh'n newImageView`.

Now to make you understand why your ImageView wasn't displayed when declaring it the way you initially tired (i.e. by creating a new object) because you most likely had the setContentView() methods parameter in your onCreate() method set to R.layout.main (your main.xml file containing your layout). Now that simply won't work as Android won't know what you are trying to do with the ImageView you've created as you never use it. Yo could either define a ViewGroup (LinearLayout, AbsoluteLayout, etc.) in Java by code and assign all your widgets (ImageView, ToggleButton, etc.) to them and then set it as the parameter of setContentView() to get them displayed or you can go the easier way and define all you need in your XML file containing your layout like I did.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <ToggleButton
        android:id="@+id/trigger"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textOn="Active"
        android:textOff="Stopped"
        android:checked="false"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"/>
    <ImageView
        android:id="@+id/image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/trigger"
        android:visibility="invisible"/>
</RelativeLayout>

Now in Java you just have to get the references (or pointers) to your widgets right so you can use them for all kinds of nasty stuff like animating them.

Here is my Java code.

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.view.animation.TranslateAnimation;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.Toast;
import android.widget.ToggleButton;

public class VeryCoolAnimation extends Activity {

    ImageView image = null;
    ToggleButton trigger = null;
    Context ctx = null;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        ctx = getApplicationContext();

        trigger = (ToggleButton) findViewById(R.id.trigger);
        image = (ImageView) findViewById(R.id.image);

        image.setImageResource(R.drawable.icon);

        trigger.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView,
                    boolean isChecked) {
                if(isChecked) {
                    animate();
                }
            }
        });
    }

    private void animate() {
        int loc[] = new int[2];
        image.getLocationOnScreen(loc);
        // Just used to print out the images position
        Toast.makeText(ctx, "Position on screen: x = " + loc[0] + " y = " + loc[1], 5000).show();
        int fromXDelta = loc[0];
        int fromYDelta = loc[1];
            int toYDelta = fromYDelta + 50;
        int toXDelta = fromXDelta + 80;

        TranslateAnimation translateAnimation = new TranslateAnimation(
                fromXDelta, toXDelta, fromYDelta, toYDelta);
        translateAnimation.setDuration(800);
        translateAnimation.setFillEnabled(true);

        image.startAnimation(translateAnimation);
        image.setVisibility(View.INVISIBLE);
    }
}

I'm not entirely sure that this is the effect you were aiming for but you can of course adjust it to suit your needs as you have a fully functional piece of code.

Good luck.

Upvotes: 1

Related Questions