I'm going through the Sams Android Development book, and I put an animation code and a code to move it to the next screen. I tested it on my phone and the AVD and it's not working. Here's the code:
public class QuizSplashActivity extends QuizActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
TextView logo1 = (TextView) findViewById(R.id.TextViewTopTitle);
Animation fade1 = AnimationUtils.loadAnimation(this, R.anim.fade_in);
logo1.startAnimation(fade1);
TextView logo2 = (TextView) findViewById(R.id.BottomView1);
Animation fade3 = AnimationUtils.loadAnimation(this, R.anim.fade_in);
logo1.startAnimation(fade3);
Animation spinin= AnimationUtils.loadAnimation(this, R.anim.custom_anim);
LayoutAnimationController controller = new LayoutAnimationController(spinin);
TableLayout table = (TableLayout) findViewById(R.id.TableLayout01); {
for (int i = 0; i < table.getChildCount(); i++) {
TableRow row = (TableRow) table.getChildAt(i);
row.setLayoutAnimation(controller);
}
}
Animation fade2 = AnimationUtils.loadAnimation(this, R.anim.custom_anim);
fade2.setAnimationListener(new AnimationListener() {
public void onAnimationEnd(Animation animation){
startActivity(new Intent(QuizSplashActivity.this, QuizMenuActivity.class));
QuizSplashActivity.this.finish();
}
public void onAnimationStart(Animation a) { }
public void onAnimationRepeat(Animation a) { }
});
}
#Override
protected void onPause() {
super.onPause();
TextView logo1= (TextView) findViewById(R.id.TextViewTopTitle);
logo1.clearAnimation();
TextView logo2= (TextView) findViewById(R.id.BottomView1);
logo2.clearAnimation();
}
}
`
Please help, I want to move onto the next chapter.
Again, if I run this code, the animation doesn't run and the app doesn't move onto the next screen.
Thanks
First of all, onAnimationEnd of fade2 is where you start your next Activity but I don't see you using it anywhere.
I think you've got confused about which views you want to animate and which animations to use here:
TextView logo1 = (TextView) findViewById(R.id.TextViewTopTitle);
Animation fade1 = AnimationUtils.loadAnimation(this, R.anim.fade_in);
logo1.startAnimation(fade1); // <----- is this right?
TextView logo2 = (TextView) findViewById(R.id.BottomView1);
Animation fade3 = AnimationUtils.loadAnimation(this, R.anim.fade_in);
logo1.startAnimation(fade3); // <----- and this one?
Also, onAnimationEnd is not reliable. You can take a look at setRepeatCount() and setRepeatMode() and play around with those but there are multiple bugs with them and worse, those bugs vary between Android version.
Instead, you can use a delayed Runnable to do your "post animation" work:
new Handler().postDelayed(new Runnable() {
public void run() {
view.clearAnimation(); // <--- whichever view you are animating
startActivity(new Intent(QuizSplashActivity.this, QuizMenuActivity.class));
QuizSplashActivity.this.finish();
}
}, fade2.getDuration());
This runnable will be delayed for however long fade2 is set to animate for. When it fires, it clears the current animation and starts the activity.
Good luck!
Related
This is a demo app for animations that i am making. It's an application with simple image which should react on button click like rotate, zoom in, zoom out, fade in/out, etc, but instead it crashes, i can't possibly find what can be the problem, i have searched all over the internet for solutions, but with no luck, here is the code:
public class MainActivity extends AppCompatActivity implements
View.OnClickListener, Animation.AnimationListener {
#Override
public void onAnimationEnd(Animation animation) {
textStatus.setText("STOPPED");
}
#Override
public void onAnimationRepeat(Animation animation) {
}
#Override
public void onAnimationStart(Animation animation) {
textStatus.setText("RUNNING");
}
Animation animFadeIn;
Animation animFadeOut;
Animation animFadeInOut;
Animation animZoomIn;
Animation animZoomOut;
Animation animLeftRight;
Animation animRightLeft;
Animation animTopBottom;
Animation animBounce;
Animation animFlash;
Animation animRotateLeft;
Animation animRotateRight;
ImageView imageView;
TextView textStatus;
Button btnFadeIn;
Button btnFadeOut;
Button btnFadeInOut;
Button zoomIn;
Button zoomOut;
Button leftRight;
Button rightLeft;
Button topBottom;
Button bounce;
Button flash;
Button rotateLeft;
Button rotateRight;
SeekBar seekBarSpeed;
TextView textSeekerSpeed;
int seekSpeedProgress;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
loadAnimations();
loadUI();
}
private void loadAnimations() {
animFadeIn = AnimationUtils.loadAnimation(this,R.anim.fade_in);
animFadeIn.setAnimationListener(this);
animFadeOut = AnimationUtils.loadAnimation(this,R.anim.fade_out);
animFadeInOut = AnimationUtils.loadAnimation(this, R.anim.fade_in_out);
animZoomIn = AnimationUtils.loadAnimation(this,R.anim.zoom_in);
animZoomOut = AnimationUtils.loadAnimation(this,R.anim.zoom_out);
animLeftRight = AnimationUtils.loadAnimation(this,R.anim.left_right);
animRightLeft = AnimationUtils.loadAnimation(this, R.anim.right_left);
animTopBottom = AnimationUtils.loadAnimation(this, R.anim.top_bot);
animBounce = AnimationUtils.loadAnimation(this,R.anim.bounce);
animFlash = AnimationUtils.loadAnimation(this, R.anim.flash);
animRotateLeft = AnimationUtils.loadAnimation(this, R.anim.rotate_left);
animRotateRight = AnimationUtils.loadAnimation(this, R.anim.rotate_right);
}
private void loadUI() {
imageView = (ImageView) findViewById(R.id.imageView);
textSeekerSpeed = (TextView) findViewById(R.id.textStatus);
btnFadeIn = (Button) findViewById(R.id.btnFadeIn);
btnFadeOut = (Button) findViewById(R.id.btnFadeOut);
btnFadeInOut = (Button) findViewById(R.id.btnFadeInOut);
zoomIn = (Button) findViewById(R.id.btnZoomIn);
zoomOut = (Button) findViewById(R.id.btnZoomOut);
leftRight = (Button) findViewById(R.id.btnLeftRight);
rightLeft = (Button) findViewById(R.id.btnRightLeft);
topBottom = (Button) findViewById(R.id.btnTopBottom);
bounce = (Button) findViewById(R.id.btnBounce);
flash = (Button) findViewById(R.id.btnFlash);
rotateLeft = (Button) findViewById(R.id.btnRotateLeft);
rotateRight = (Button) findViewById(R.id.btnRotateRight);
zoomIn.setOnClickListener(this);
zoomOut.setOnClickListener(this);
leftRight.setOnClickListener(this);
rightLeft.setOnClickListener(this);
topBottom.setOnClickListener(this);
bounce.setOnClickListener(this);
flash.setOnClickListener(this);
rotateLeft.setOnClickListener(this);
rotateRight.setOnClickListener(this);
seekBarSpeed = (SeekBar) findViewById(R.id.seekBarSpeed);
textSeekerSpeed = (TextView) findViewById(R.id.textSeekerSpeed);
seekBarSpeed.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int value, boolean fromUser) {
seekSpeedProgress = value;
textSeekerSpeed.setText("" +seekSpeedProgress + "of" +seekBarSpeed.getMax());
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
#Override
public void onClick(View v) {
switch(v.getId()) {
case R.id.btnFadeIn:
animFadeIn.setDuration(seekSpeedProgress);
animFadeIn.setAnimationListener(this);
imageView.startAnimation(animFadeIn);
break;
case R.id.btnFadeOut:
animFadeOut.setDuration(seekSpeedProgress);
animFadeOut.setAnimationListener(this);
imageView.startAnimation(animFadeOut);
break;
case R.id.btnFadeInOut:
animFadeInOut.setDuration(seekSpeedProgress);
animFadeInOut.setAnimationListener(this);
imageView.startAnimation(animFadeInOut);
break;
case R.id.btnZoomIn:
animZoomIn.setDuration(seekSpeedProgress);
animZoomIn.setAnimationListener(this);
imageView.startAnimation(animZoomIn);
break;
case R.id.btnZoomOut:
animZoomOut.setDuration(seekSpeedProgress);
animZoomOut.setAnimationListener(this);
imageView.startAnimation(animZoomOut);
break;
case R.id.btnLeftRight:
animLeftRight.setDuration(seekSpeedProgress);
animLeftRight.setAnimationListener(this);
imageView.startAnimation(animLeftRight);
break;
case R.id.btnRightLeft:
animRightLeft.setDuration(seekSpeedProgress);
animRightLeft.setAnimationListener(this);
imageView.startAnimation(animRightLeft);
break;
case R.id.btnBounce:
animBounce.setDuration(seekSpeedProgress/10);
animBounce.setAnimationListener(this);
imageView.startAnimation(animBounce);
break;
case R.id.btnFlash:
animFlash.setDuration(seekSpeedProgress/10);
animFlash.setAnimationListener(this);
imageView.startAnimation(animFlash);
break;
case R.id.btnRotateLeft:
animRotateLeft.setDuration(seekSpeedProgress);
animRotateLeft.setAnimationListener(this);
imageView.startAnimation(animRotateLeft);
break;
case R.id.btnRotateRight:
animRotateRight.setDuration(seekSpeedProgress);
animRotateRight.setAnimationListener(this);
imageView.startAnimation(animRotateRight);
break;
}
}
}
Here is the crashlog:
2020-12-09 22:48:57.075 8696-8696/com.example.animationdemo E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.animationdemo, PID: 8696
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
at com.example.animationdemo.MainActivity.onAnimationStart(MainActivity.java:31)
at android.view.animation.Animation.dispatchAnimationStart(Animation.java:999)
at android.view.animation.AnimationSet.getTransformation(AnimationSet.java:392)
at android.view.animation.Animation.getTransformation(Animation.java:1030)
at android.view.View.applyLegacyAnimation(View.java:21166)
at android.view.View.draw(View.java:21288)
at android.view.ViewGroup.drawChild(ViewGroup.java:4446)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4205)
at androidx.constraintlayout.widget.ConstraintLayout.dispatchDraw(ConstraintLayout.java:1975)
at android.view.View.updateDisplayListIfDirty(View.java:20474)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4428)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4401)
at android.view.View.updateDisplayListIfDirty(View.java:20441)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4428)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4401)
at android.view.View.updateDisplayListIfDirty(View.java:20441)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4428)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4401)
at android.view.View.updateDisplayListIfDirty(View.java:20441)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4428)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4401)
at android.view.View.updateDisplayListIfDirty(View.java:20441)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4428)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4401)
at android.view.View.updateDisplayListIfDirty(View.java:20441)
at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:584)
at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:590)
at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:668)
at android.view.ViewRootImpl.draw(ViewRootImpl.java:3840)
at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:3648)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2954)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1857)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:8089)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1057)
at android.view.Choreographer.doCallbacks(Choreographer.java:875)
at android.view.Choreographer.doFrame(Choreographer.java:776)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1042)
at android.os.Handler.handleCallback(Handler.java:888)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:213)
at android.app.ActivityThread.main(ActivityThread.java:8178)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1101)
The problem is that you are try to access the setText method of textStatus view when you have not initialised it.
From your code, you didn't initialize it any where. I believe
textSeekerSpeed = (TextView) findViewById(R.id.textStatus);
supposed to be where you initialize textStatus.
try replacing
textSeekerSpeed = (TextView) findViewById(R.id.textStatus);
with
textStatus = (TextView) findViewById(R.id.textStatus);
then set textSeekerSpeed with its corresponding TextView. it should solve your problem
Change
textSeekerSpeed = (TextView) findViewById(R.id.textStatus);
to
textStatus = (TextView) findViewById(R.id.textStatus);
You textStatus was never mapped so it was always null and caused a crash.
I want to make a slideshow of numbers starting from 0 to 9 in pictures. When i click next button , show the picture of 1 and play sound as 'one' and so on.I want previous button to properly work.. like when I click previous button then go to previous pic and play sound which is related to that pic.
public class Numbers extends Activity {
int i = 1;
private ImageView iv;
Button next;
Button previous;
MediaPlayer ourSong;
private int currentImage = 0;
public int currentAudio = 0;
int[] images = { R.drawable.p1, R.drawable.p2, R.drawable.p3,
R.drawable.p4, R.drawable.p5, R.drawable.p6, R.drawable.p7,
R.drawable.p8, R.drawable.p9, R.drawable.p10};
int[] audios = { R.raw.a1, R.raw.a2, R.raw.a3, R.raw.a4, R.raw.a5,
R.raw.a6, R.raw.a7, R.raw.a8, R.raw.a9, R.raw.a10};
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.nextpre);
iv = (ImageView) findViewById(R.id.ivn);
next = (Button) findViewById(R.id.buttonn);
previous = (Button) findViewById(R.id.buttonp);
// Just set one Click listener for the image
next.setOnClickListener(iButtonChangeImageListener);
previous.setOnClickListener(gButtonChangeImageListener);
}
View.OnClickListener iButtonChangeImageListener = new View.OnClickListener() {
public void onClick(View v) {
try {
// Increase Counter to move to next Image
currentImage++;
currentImage = currentImage % images.length;
iv.setImageResource(images[currentImage]);
ourSong = MediaPlayer.create(Numbers.this,
audios[currentAudio+1]);
ourSong.start();
currentAudio++;
} catch (Exception e) {
}
}
};
View.OnClickListener gButtonChangeImageListener = new View.OnClickListener() {
public void onClick(View v) {
try {
// Decrease Counter to move to previous Image
currentImage--;
currentImage = (currentImage + images.length) % images.length;
iv.setImageResource(images[currentImage]);
MediaPlayer.create(Numbers.this, audios[currentAudio]);
ourSong.start();
currentAudio--;
} catch (Exception e) {
}
}
};
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
ourSong.release();
finish();
}
#Override
protected void onStart() {
super.onStart();
ourSong = MediaPlayer.create(Numbers.this,
audios[0]);
ourSong.start();
}
}
Hmm if you're trying to make a slide show, you might want to look into view pagers they look like this:
View pagers are highly customizable, You can add buttons and images and pretty much almost anything a fragment can hold on each screen. Not sure what your skill level is but ill tell you whats involved in getting this to work.
Create a layout with a view pager in it.
Create a class that extends the FragmentPagerAdapter
Override getItem() method in the adapter (this is where you define your different "screens"
Create a class that extends fragment for each screen you want to show your users.
Doing it this way in order to switch screens u just have to call setCurrentItem to change pages (when user clicks next or prev)
--edit--
Apparently theres also a something called an ImageSwitcher.
They look like this:
This is actually better for your case since you only want images. It looks a lot easier to implement than a view pager. This describes how to implement it: http://www.tutorialspoint.com/android/android_imageswitcher.htm
what I am trying to do is to call on one of three sounds on this button click. The sounds are in a preference screen. On the button click it is also supposed to display an animation. What is currently happening is I will click on the button and everything will work perfectly, but then I stop the animation and sound the second time I click the button. When I click the button again to start back up the animation and sound I cant hear the sound, but the animation still works. I honestly have no idea whats wrong. Here's my code...
public void buttonClick() {
imgView = (ImageView) findViewById(R.id.imageView);
button = (Button) findViewById(R.id.button);
blade = (ImageView)findViewById(R.id.imageView4);
final Animation animRotate = AnimationUtils.loadAnimation(this, R.anim.rotate);
1stSound = MediaPlayer.create(this, R.raw.file.mp3);
2ndSound = MediaPlayer.create(this, R.raw.file.mp3);
3rdSOund = MediaPlayer.create(this, R.raw.file.mp3);
button.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
SharedPreferences getPrefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
boolean option1 = getPrefs.getBoolean("alternate", false);
boolean option2 = getPrefs.getBoolean("white", false);
boolean option3 = getPrefs.getBoolean("standard",false);
if (blade.getAnimation() == null) {
// no animation, start it
if (option1 == true){
1stSound.start();
blade.startAnimation(animRotate);
} else if (option2 == true){
3rdSound.start();
blade.startAnimation(animRotate);
} else if (option3 == true) {
2ndFan.start();
blade.startAnimation(animRotate);
}
} else {
//animation is showing, stop it
blade.clearAnimation();
3rdSound.stop();
2ndSound.stop();
1stSound.stop();
}
current_image_index++;
current_image_index = current_image_index % images.length;
imgView.setImageResource(images[current_image_index]);
imgView.invalidate();
}
}
);
}
Take a look at the MediaPlayer state diagram. After calling stop() you'll need to also call prepare() (or prepareAsync()) to be able to play it again.
In short, do this:
3rdSound.stop();
3rdSound.prepareAsync();
2ndSound.stop();
2ndSound.prepareAsync();
1stSound.stop();
1stSound.prepareAsync();
This is actually a memory training app, with matrix of squares wich flips to their other side and than back to first side. And user need to click on squares that flipped. You know what I mean?
Something like that.
What I need is that sizes of the matrix would change dynamically. If user have been passed one level of complexity (matrix size is 4x4 for example), then matrix size would grow (5x5 for example), and if not then matrix size would get smaller (3x3 for example). I hope that's clear, and if not - sorry, English is not my native language =)
So if I would do it from code this would not be a problem. I would use ViewFlipper with some transition animation and create TableView with sizes that I want with inflater or something like that (or directly from code without using xml at all). And then adding it to ViewFlipper from code.
But somehow I don't like that idea.
Then next idea come into my mind. To do ViewFlipper with all possible tableviews in it and then just showNext(); or showPrevious(); depending on what user have done. But in this case XML would be of very great size.
So maybe someone knows the another way to do it?
i suggest you to look view-pager-example,
using viewflipper showNext(); or showPrevious(); you had to download all data at the same time, but using fragmen, you can load only specific data assoiated with fragment.
you can change the view on every fragment like below
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new DetailFragment();
case 1:
return new ImageFragment(R.drawable.ic_launcher);
case 2:
return new ImageFragment(R.drawable.thumb);
default:
return null;
}
}
[EDIT - For checking view in listener]
public class LoginExampleImplements extends Activity implements OnClickListener {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
btn1.setOnClickListener(this);
btn2.setOnClickListener(this);
btn3.setOnClickListener(this);
btn4.setOnClickListener(this);
}
#Override
public void onClick(View v) {
if(v==btn1) {
} else if(v==btn2) {
} else if(v==btn3) {
} else if(v==btn4) {
}
}
}
[EDIT 2]
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
LinearLayout1 = (LinearLayout) findViewById(R.id.LinearLayout1);
for (int i = 0; i < 30; i++) {
button = new Button(getApplicationContext());
button.setId(i);
button.setOnClickListener(this);
LinearLayout1.addView(button);
}
}
#Override
public void onClick(View v) {
Button b = (Button)v;
b.getId()
// check clikedId
}
[EDIT 3]
public class MainActivity extends Activity implements OnClickListener{
ImageView img;
LinearLayout LinearLayout1;
LinearLayout.LayoutParams layoutParams;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LinearLayout1 = (LinearLayout) findViewById(R.id.ln1);
layoutParams = new LinearLayout.LayoutParams(100, 100);
for (int i = 0; i < 30; i++) {
img = new ImageView(getApplicationContext());
img.setId(i);
img.setTag(i);
layoutParams.setMargins(10, 10, 10, 10);
img.setLayoutParams(layoutParams);
img.setBackgroundColor(Color.RED);
img.setPadding(10, 10, 10, 10);
img.setOnClickListener(this);
LinearLayout1.addView(img);
}
}
#Override
public void onClick(View v) {
ImageView b = (ImageView)v;
b.setBackgroundColor(Color.BLUE);
b.setImageLevel(Integer.valueOf(String.valueOf(b.getTag())));
}
}
I have a basic animation of a button after it is pressed currently in my application. After the button finishes animating, I can no longer click on it. It doesn't even press with an orange highlight.
Any help?
Here's my code:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
animation = new AnimationSet(true);
animation.setFillAfter(true);
Animation translate = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 5.0f);
translate.setDuration(500);
animation.addAnimation(translate);
LayoutAnimationController controller = new LayoutAnimationController(animation, 0.25f);
generate = (Button)findViewById(R.id.Button01);
generate.setOnClickListener(new View.OnClickListener(){
public void onClick(View v){
keyFromTop();
}
});
}
public void keyFromTop(){
generate.setAnimation(animation);
}
Animations affect only the drawing of widgets, which means after the animation is done, your button is still at its previous location. You need to manually update the layout parameters of your button if you want to move it to the new location. Also, your AnimationSet and your AnimationController are useless.
If you want to be able to click the button after the animation is complete, you have to manually move the component.
Here's an example of a translate animation applied to a button:
public class Test2XAnimation extends Activity {
private RelativeLayout buttonContainer;
private Button button;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (Button) this.findViewById(R.id.button1);
buttonContainer = (RelativeLayout) button.getParent();
}
public void startTapped(View view) {
animateButton(200, 100);
}
public void buttonTapped(View view) {
Toast.makeText(this, "tap", Toast.LENGTH_SHORT).show();
}
private RelativeLayout.LayoutParams params;
private CharSequence title;
private void animateButton(final int translateX, final int translateY) {
TranslateAnimation translate = new TranslateAnimation(0, translateX, 0,
translateY);
translate.setDuration(1500);
translate.setAnimationListener(new AnimationListener() {
public void onAnimationEnd(Animation animation) {
buttonContainer.removeView(button);
button = new Button(Test2XAnimation.this);
button.setText(title);
button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
buttonTapped(button);
}
});
params.leftMargin = translateX + params.leftMargin;
params.topMargin = translateY + params.topMargin;
params.rightMargin = 0 + params.rightMargin;
params.bottomMargin = 0 + params.bottomMargin;
button.setLayoutParams(params);
buttonContainer.addView(button);
}
public void onAnimationRepeat(Animation animation) {
}
public void onAnimationStart(Animation animation) {
params = (RelativeLayout.LayoutParams) button.getLayoutParams();
title = button.getText();
}
});
button.startAnimation(translate);
}
}
The method startTapped() is triggered when a user clicks a button in the UI. The other button moves by (200,100). At the end, I remove the old one and create a new one, thenaI add it to the parent view. You can see that buttonTapped() is called after the animation.
A suggestion: you can use NineOldAndroids project if you want to support both the new and the old way of animating a component, then you can check the OS version and run this code only on Gingerbread and lower versions.
I really struggled with shuffling layout params to make the "real" button match up to its animated location. I finally succeeded by using this approach. I extended ImageButton and overrode getHitRect:
#Override
public void getHitRect(Rect outRect) {
Rect curr = new Rect();
super.getHitRect(curr);
outRect.bottom = curr.bottom + 75;
outRect.top = curr.top + 75;
outRect.left = curr.left;
outRect.right = curr.right;
}
Then, I could use this button in the troublesome view:
<com.sample.YPlus75ImageButton a:id="#+id/....
It's worth noting that all of this changes for 3.0.