Hi have a problem with Animation, actually i want to fade my ImageView while it's changing it resource.
It's not working, i can change the resource but without any animation.
private void checkX() {
// TODO Auto-generated method stub
switch (x) {
case (1): {
startingAnimation();
xImg.setImageResource(R.drawable.test_uno);
endingAnimation();
break;
}
case (2): {
startingAnimation();
xImg.setImageResource(R.drawable.test_due);
endingAnimation();
break;
}
case (3): {
startingAnimation();
xImg.setImageResource(R.drawable.test_tre);
endingAnimation();
break;
}
case (4): {
startingAnimation();
xImg.setImageResource(R.drawable.test_quattro);
endingAnimation();
break;
}
case (5): {
x = 1;
checkX();
break;
}
case (0): {
x = 4;
checkX();
break;
}
}
}
private void endingAnimation() {
// TODO Auto-generated method stub
ObjectAnimator animation2 = ObjectAnimator.ofFloat(xImg, "alpha", 255);
animation2.setDuration(1000);
animation2.start();
}
private void startingAnimation() {
// TODO Auto-generated method stub
ObjectAnimator animation = ObjectAnimator.ofFloat(xImg, "alpha", 0);
animation.setDuration(1000);
animation.start();
}
checkX is called each time i press a button(that add or subtract 1 to X).
How i can make both animations and ImageView resource change?
Try changing the image source when the animation's onAnimationEnd is called. For example:
animation.addListener(new AnimatorListener() {
#Override
public void onAnimationStart(Animator animation) { }
#Override
public void onAnimationRepeat(Animator animation) { }
#Override
public void onAnimationEnd(Animator animation) {
// change your ImageView's source here
}
#Override
public void onAnimationCancel(Animator animation) { }
});
Apply fade out animation on your ImageView and set animationListener to it. on animation end change your views resource and set fade in animation on it
For fade in animation
Animation fadeIn = new AlphaAnimation(0, 1);
fadeIn.setInterpolator(new DecelerateInterpolator());
fadeIn.setDuration(1000);
final AnimationSet animation = new AnimationSet(false);
animation.addAnimation(fadeIn);
For fade out animation
Animation fadeOut = new AlphaAnimation(1, 0);
fadeOut.setInterpolator(new AccelerateInterpolator());
fadeOut.setDuration(300);
final AnimationSet animation = new AnimationSet(false);
animation.addAnimation(fadeOut);
Thats how you implement listner on animation
fadeout.setAnimationListener(new Animation.AnimationListener(){
#Override
public void onAnimationStart(Animation arg0) {
}
#Override
public void onAnimationRepeat(Animation arg0) {
}
#Override
public void onAnimationEnd(Animation arg0) {
//change resource of Imageview here
}
});
Related
So this is my spin the bottle animation:
public static final Random RANDOM = new Random();
private int lastAngle = -1;
private ImageView bottle;
private void spinTheBottle() {
int angle = RANDOM.nextInt(3600 - 360) + 360;
float pivotX = bottle.getWidth() / 2;
float pivotY = bottle.getHeight() / 2;
final Animation animRotate = new RotateAnimation(lastAngle == -1 ? 0 : lastAngle, angle, pivotX, pivotY);
lastAngle = angle;
animRotate.setDuration(1500);
animRotate.setFillAfter(true);
bottle.startAnimation(animRotate);
}
How can I detect when the animation is done? I tried adding Animator.AnimatorListener, but that does not execute at all:
Animator.AnimatorListener listener = new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animation) {
Toast.makeText(FlasketutenActivity.this, "onAnimationStart", Toast.LENGTH_SHORT).show();
}
#Override
public void onAnimationEnd(Animator animation) {
Toast.makeText(FlasketutenActivity.this, "onAnimationEnd", Toast.LENGTH_SHORT).show();
}
#Override
public void onAnimationCancel(Animator animation) {
Toast.makeText(FlasketutenActivity.this, "onAnimationCancel", Toast.LENGTH_SHORT).show();
}
#Override
public void onAnimationRepeat(Animator animation) {
Toast.makeText(FlasketutenActivity.this, "onAnimationRepeat", Toast.LENGTH_SHORT).show();
}
};
Any tips?
It looks like you're creating the listener, but not assigning it to your animation. Try calling setAnimationListener on your animation object like this:
animRotate.setAnimationListener(new Animation.AnimationListener() {
//Listener methods
});
The first.Keep the ImageView witch and height above of zero at time
rotateAnimation.setDuration(1500);
rotateAnimation.setFillAfter(true);
rotateAnimation.setFillEnabled(true);
rotateAnimation.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
Log.d(TAG, "onAnimationStart: ");
}
#Override
public void onAnimationEnd(Animation animation) {
Log.d(TAG, "onAnimationEnd: ");
}
#Override
public void onAnimationRepeat(Animation animation) {
Log.d(TAG, "onAnimationRepeat: ");
}
});
view.startAnimation(rotateAnimation);
it is working in my project.
But I use the animation always in xmls,it is Easy to operate and relatively by code.
Animation and Animator is not a same things.
That's all.
Assign your listener that you have created to the animation
animRotate.setAnimationListener(listener);
So I have been working with ExoPlayer for streaming content in MP4 Dash File Format, and everything works fine, until I decide to change the Seekbar to a new position. On changing the Seekbar to a new position, the audio plays absolutely fine, but the video is stuck at a frame like a picture. Not sure why it's happening. Any help would be greatly helpful.
Edit:
PlayerView ep;
SimpleExoPlayer player;
boolean secondTouch=false;
boolean isPlaying=false;
boolean isLandscape=false;
long lastTimeTouched;
//ON SCREEN CONTROLS
LinearLayout mcContainer;
ImageButton ivPlay;
ImageButton ivSize;
TextView totalDuration;
RelativeLayout buffer;
SeekBar progress;
int totalTime;
Runnable runnable;
LinearLayout commentsContainer;
Intent i;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);
getSupportActionBar().hide();
i=getIntent();
setContentView(R.layout.activity_video);
details=findViewById(R.id.textView11);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);
isLandscape=getResources().getConfiguration().orientation==Configuration.ORIENTATION_LANDSCAPE;
ep=findViewById(R.id.videoViewPlay);
ivSize=findViewById(R.id.imageButton2);
player = new SimpleExoPlayer.Builder(this).build();
ep.setPlayer(player);
mcContainer=findViewById(R.id.mcContainer);
ivPlay=findViewById(R.id.buttonPlay);
totalDuration=findViewById(R.id.textViewTotalDuration);
buffer=findViewById(R.id.bufferContainer);
progress=findViewById(R.id.seekBarProgress);
ivPlay.setOnClickListener(v -> {
if(isPlaying)
{
player.setPlayWhenReady(false);
isPlaying=false;
ivPlay.setBackgroundResource(android.R.drawable.ic_media_play);
}
else
{
player.setPlayWhenReady(true);
isPlaying=true;
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
ivPlay.setBackgroundResource(android.R.drawable.ic_media_pause);
}
});
ep.setOnClickListener(v -> {
ViewGroup.LayoutParams params = mcContainer.getLayoutParams();
params.height = Tools.convertDpToPx(this,48);
mcContainer.setLayoutParams(params);
lastTimeTouched=System.currentTimeMillis();
if(secondTouch==true){
params = mcContainer.getLayoutParams();
params.height = 0;
mcContainer.setLayoutParams(params);
}
secondTouch=!secondTouch;
});
progress.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if(fromUser) {
player.setPlayWhenReady(false);
player.seekTo(progress * 1000);
player.setPlayWhenReady(true);
}
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
DefaultBandwidthMeter bandwidthMeterA = new DefaultBandwidthMeter();
DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(this, Util.getUserAgent(this, "eTuitionPro"), bandwidthMeterA);// This is the MediaSource representing the media to be played.
String media=Uri.parse(Tools.baseAddress+"VIDEO/"+i.getStringExtra("ModuleID")+"/index.php").buildUpon().appendQueryParameter("token", Tools.token).build().toString();//NEEDS CHANGE
MediaSource videoSource =new DashMediaSource.Factory(dataSourceFactory).createMediaSource(Uri.parse(media));// Prepare the player with the source.
player.prepare(videoSource);
Handler handler = new Handler();
runnable = () -> {
progress.setProgress(((int)(player.getCurrentPosition()/1000)));
if(((int)(player.getCurrentPosition()/1000))==progress.getMax())
{
player.setPlayWhenReady(false);
isPlaying=false;
ivPlay.setBackgroundResource(android.R.drawable.ic_media_play);
progress.setProgress(0);
}
else
handler.postDelayed(runnable, 1000);
};
player.addListener(new Player.EventListener() {
#Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
switch(playbackState)
{
case ExoPlayer.STATE_READY:
totalTime = (int)(player.getDuration()/1000);
progress.setMax(totalTime);
totalDuration.setText(msToString(player.getDuration()));
buffer.setVisibility(View.INVISIBLE);
handler.postDelayed(runnable, 0);
break;
case ExoPlayer.STATE_BUFFERING:
buffer.setVisibility(View.VISIBLE);
break;
}
}
#Override
public void onPlayerError(ExoPlaybackException error) {
}
});
...
In the above program I tried to make a custom Control Player UI for the ExoPlayer. Not sure if I did anything wrong, if there is a better way to do this, I will honoured to know more.
What I want to do is simple. I want to have a looping background, so that it looks like the ground is moving. Here is how I am trying to do it however, it looks like both images are being dispatched at same time.
public void moveGround(){
startingXPosition =1500.0f;
endingXPosition = -1500.0f;
startingYPosition =0.0f;
endingYPosition =0.0f;
ImageView ground = (ImageView)findViewById(R.id.ground);
TranslateAnimation groundAnimation = new TranslateAnimation(startingXPosition,endingXPosition,startingYPosition,endingYPosition);
groundAnimation.setDuration(1500);
groundAnimation.setRepeatCount(Animation.INFINITE);
ground.startAnimation(groundAnimation);
if(ground.getLeft()<=0) {
float startingXPosition2 = 1500.0f;
float endingXPosition2 = -1500.0f;
float startingYPosition2 = 0.0f;
float endingYPosition2 = 0.0f;
ImageView ground2 = (ImageView) findViewById(R.id.ground2);
TranslateAnimation groundAnimation2 = new TranslateAnimation(startingXPosition2, endingXPosition2, startingYPosition2, endingYPosition2);
groundAnimation2.setDuration(1500);
groundAnimation2.setRepeatCount(Animation.INFINITE);
ground2.startAnimation(groundAnimation2);
}
}
try
yourAnimation.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
// do what you want
}
#Override
public void onAnimationRepeat(Animation animation) {
// do what you want
}
});
I have implemented an Android listview with flip checkboxes (GMail style) as shown here: http://techiedreams.com/gmail-like-flip-animated-multi-selection-list-view-with-action-mode/
The problem I have (even in the source code example): If there are multiple items I click/check in a fast sequence, the previous animation stops and will be restared. In other words, the previous animation does not finish and is interrupted by the second one.
Simple download the source code and try it on your own. In comparisson to gmail all animations, no matter how fast I'm clicking, are performed from the start to the end.
I can't find the piece of code in the demo source code to change this behaviour.
Any hints?
Thanks in advance :)
This is the closest I could get to Gmail's flip animation:
In the getView() method (I'm using contextual action mode):
holder.check.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mActionMode == null) {
checked = new SparseBooleanArray(alllists.size());
mActionMode = ((Activity) getActivity()).startActionMode(mActionModeCallback);
animateRow(position);
checked.put(position, true);
mActionMode.setTitle("1");
mActionMode.getMenu().getItem(0).setVisible(true);
} else {
animateRow(position);
if (checked.get(position)) {
checked.put(position, false);
if (checked.indexOfValue(true) < 0) {
mActionMode.finish();
} else {
mActionMode.setTitle(String.valueOf(getCheckedCount()));
}
} else {
checked.put(position, true);
mActionMode.setTitle(String.valueOf(getCheckedCount()));
}
}
}
}
);
Then the animateRow() method:
private void animateRow(final int position) {
if (position >= listView.getFirstVisiblePosition() && position <= listView.getLastVisiblePosition()) {
Log.i("animateRow", String.valueOf(position));
ScaleAnimation anim = new ScaleAnimation(1, 0, 1, 1, Animation.RELATIVE_TO_SELF, 0.5f, 0, 0);
anim.setDuration(150);
anim.setRepeatCount(1);
anim.setRepeatMode(Animation.REVERSE);
viewa = listView.getChildAt(position - listView.getFirstVisiblePosition());
final Button chkButton = (Button) viewa.findViewById(R.id.logo);
if (checked.get(position)) {
anim.setAnimationListener(
new AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
Log.i("anim" + position, "Start");
}
#Override
public void onAnimationRepeat(Animation animation) {
Log.i("anim" + position, "Repeat" + animation.getRepeatCount());
viewa.setBackgroundResource(R.color.row_background);
chkButton.setBackgroundResource(R.color.button_background);
chkButton.setText(String.valueOf(alllists.get(position).itemsCount));
}
#Override
public void onAnimationEnd(Animation animation) {
Log.i("anim" + position, "END");
}
}
);
chkButton.startAnimation(anim);
} else {
anim.setAnimationListener(
new AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
Log.i("anim" + position, "Start");
}
#Override
public void onAnimationRepeat(Animation animation) {
viewa.setBackgroundResource(R.color.checked_row_background);
chkButton.setBackgroundResource(R.color.checked_button_background);
chkButton.setText("✓");
}
#Override
public void onAnimationEnd(Animation animation) {
Log.i("anim" + position, "END");
}
}
);
chkButton.startAnimation(anim);
}
}
}
I hope it helps.. :)
Now you can forget that method to flip a view, since I've developed a new library FlipView fully customizable, this is exactly what you want. You will be able to swap any kind of views and layouts with any kind of animation you desire.
Please have a look.
In my SMS app, I have a dialog that opens when the user clicks on an attached image to expand it.
Everything worked fine until I decided to add animations. This dialog has 3 buttons (one close ImageButton in the top right corner and two buttons in a bottom bar of the dialog). When the user clicks on the image, the buttons anime out/in. This all works fine except the buttons are still clickable even after they're hidden.
Before Animations:
After Animations:
My code for the dialog below:
// Declare these here to increase scope. (Listeners)
private static boolean ContainerChanged;
private static boolean ActionsHidden;
private static boolean AnimStarted;
private static boolean closeAnimFinished;
private static boolean barAnimFinished;
private void showExpandedImageDialog(Uri imgUri)
{
// Initialize Dialog
final Dialog dialog = new Dialog(ActivitySend.this, R.style.FullHeightDialog);
dialog.setContentView(R.layout.dialog_attachment_image_send);
// Initialize Views
final RelativeLayout Container = (RelativeLayout) dialog.findViewById(R.id.Container);
final LinearLayout actions = (LinearLayout) dialog.findViewById(R.id.Actions);
final ImageButton btnClose = (ImageButton) dialog.findViewById(R.id.btnClose);
Button btnReplace = (Button) dialog.findViewById(R.id.btnReplace);
Button btnRemove = (Button) dialog.findViewById(R.id.btnRemove);
ImageView image = (ImageView) dialog.findViewById(R.id.Image);
// Load Image & Make Zoomable
PhotoViewAttacher mAttacher = new PhotoViewAttacher(image);
image.setImageURI(imgUri);
mAttacher.update();
// Get animations ready
final Animation fiCloseAnim = AnimationUtils.loadAnimation(ActivitySend.this, R.anim.fade_in);
fiCloseAnim.setFillEnabled(true);
fiCloseAnim.setFillAfter(true);
final Animation foCloseAnim = AnimationUtils.loadAnimation(ActivitySend.this, R.anim.fade_out);
foCloseAnim.setFillEnabled(true);
foCloseAnim.setFillAfter(true);
final Animation dBarAnim = AnimationUtils.loadAnimation(ActivitySend.this, R.anim.slide_down);
dBarAnim.setFillEnabled(true);
dBarAnim.setFillAfter(true);
final Animation uBarAnim = AnimationUtils.loadAnimation(ActivitySend.this, R.anim.slide_up);
uBarAnim.setFillEnabled(true);
uBarAnim.setFillAfter(true);
// Reset static variables
ActionsHidden = false;
AnimStarted = false;
closeAnimFinished = false;
barAnimFinished = false;
// Initialize listeners
AnimationListener closeAnimListener = new AnimationListener()
{
#Override
public void onAnimationEnd(Animation animation)
{
closeAnimFinished = true;
if (closeAnimFinished && barAnimFinished)
{
AnimStarted = false;
closeAnimFinished = false;
barAnimFinished = false;
if (ActionsHidden)
{
actions.setVisibility(View.VISIBLE);
btnClose.setVisibility(View.VISIBLE);
}
else
{
actions.setVisibility(View.GONE);
btnClose.setVisibility(View.GONE);
}
ActionsHidden = !ActionsHidden;
}
}
#Override
public void onAnimationRepeat(Animation animation)
{
// Nothing
}
#Override
public void onAnimationStart(Animation animation)
{
AnimStarted = true;
}
};
AnimationListener barAnimListener = new AnimationListener()
{
#Override
public void onAnimationEnd(Animation animation)
{
barAnimFinished = true;
if (closeAnimFinished && barAnimFinished)
{
AnimStarted = false;
closeAnimFinished = false;
barAnimFinished = false;
if (ActionsHidden)
{
actions.setVisibility(View.VISIBLE);
btnClose.setVisibility(View.VISIBLE);
}
else
{
actions.setVisibility(View.GONE);
btnClose.setVisibility(View.GONE);
}
ActionsHidden = !ActionsHidden;
}
}
#Override
public void onAnimationRepeat(Animation animation)
{
// Nothing
}
#Override
public void onAnimationStart(Animation animation)
{
AnimStarted = true;
}
};
// Set listeners
fiCloseAnim.setAnimationListener(closeAnimListener);
foCloseAnim.setAnimationListener(closeAnimListener);
dBarAnim.setAnimationListener(barAnimListener);
uBarAnim.setAnimationListener(barAnimListener);
// Actions Appear/Disappear onTap (Animate)
mAttacher.setOnPhotoTapListener(new OnPhotoTapListener()
{
#Override
public void onPhotoTap(View view, float x, float y)
{
if (!AnimStarted && ActionsHidden)
{
actions.startAnimation(uBarAnim);
btnClose.startAnimation(fiCloseAnim);
}
else if (!AnimStarted)
{
actions.startAnimation(dBarAnim);
btnClose.startAnimation(foCloseAnim);
}
}
});
// Make dialog square
ContainerChanged = false;
ViewTreeObserver vto = Container.getViewTreeObserver();
vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener()
{
public boolean onPreDraw()
{
// Set boolean to save processing power
if (!ContainerChanged)
{
int width = Container.getMeasuredWidth();
Container.getLayoutParams().height = width;
ContainerChanged = true;
}
return true;
}
});
// Set button listeners
btnClose.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
dialog.dismiss();
}
});
btnReplace.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
// TODO Auto-generated method stub
}
});
btnRemove.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
// TODO Auto-generated method stub
}
});
// Show dialog
dialog.show();
}
Everything works perfectly if I remove the animations and only use view.setVisibility(View.GONE) but I really like the animations...
Any ideas on what I could do to fix this?
I could probably use view.setClickable(false); but I'm sure there's a better solution than that.
You can do it like this:
Let your activity implement AnimationListener. Then there will be an overridden method public void onAnimationEnd(Animation arg0), write setClickable(false) or setEnabled(false) in this method for all three of your buttons, enable them again when you are starting your animation....hope you got me..