Android: Animation doesn't work - android

I am working o na Android app. This app has tutorial screens. In this tutorial user has to slide right and left to complete the tutorial. When it launches the app it shows first fragment called SwipeLeftFragment. When user swipes left it shows second fragment called SwipeRightFragment. When user swipes right it shows third fragment called CompletedTutorialFragment.
Currently It works fine but animation doesn't work.
Following is my code:
public class TutorialActivity extends FragmentActivity {
#Override
protected void onStart() {
super.onStart();
final swipeLeftFragment swipeLeftFragment = new SwipeLeftFragment();
addFragmentToBottom(swipeLeftFragment);
swipeLeftFragment.getView().setOnTouchListener(new OnSwipeListener(TutorialActivity.this) {
#Override
public void onSwipeRight() {
}
#Override
public void onSwipeLeft() {
TranslateAnimation animation = new TranslateAnimation(0, -swipeLeftFragment.getView().getWidth(), 0, 0);
animation.setDuration(5000);
swipeLeftFragment.getView().startAnimation(animation);
swipeLeftFragment.getView().setVisibility(View.GONE);
final SwipeRightFragment swipeRightFragment = new SwipeRightFragment();
addFragmentToBottom(swipeRightFragment);
swipeRightFragment.getView().setOnTouchListener(new OnSwipeListener(TutorialActivity.this) {
#Override
public void onSwipeRight() {
TranslateAnimation animation = new TranslateAnimation(0, +swipeRightFragment.getView().getWidth(), 0, 0);
animation.setDuration(5000);
swipeRightFragment.getView().startAnimation(animation);
swipeRightFragment.getView().setVisibility(View.GONE);
final CompletedTutorialFragment completedTutorialFragment = new CompletedTutorialFragment();
addFragmentToBottom(completedTutorialFragment);
startSignupActivity();
}
#Override
public void onSwipeLeft() {
}
});
}
});
}
private void startSignupActivity() {
Handler mHandler = new Handler();
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
startActivity(new Intent(TutorialActivity.this, SignUpActivity.class));
}
}, 2000L);
}
}
Can someone tell me whats wrong with my code?
this is the
OnTouchListener I am using

Related

How To Call this Animation in onCreate() in Android?

I am following this link for my animation Requirement.
https://medium.com/#ayushpguptaapg/how-to-add-shine-glare-effect-on-an-imageview-ab3e9e660307
This has done on button click listener. Which is working fine. But i want to do it without button click as this animation starts as the activity load.
I have searched alot, but didn't find any simple solution.
Can anybody tell me the simple solution.
Thanks in advance.
#ismail, i am using your this code, like this:
public class MainActivity extends AppCompatActivity{
Button shinebtn;
ImageView img,shine;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
img = findViewById(R.id.img);
shine = findViewById(R.id.shine);
shinebtn=findViewById(R.id.button);
doAnimation();
}
public void doAnimation(){
new Thread(new Runnable() {
public void run() {
final Animation animation = new TranslateAnimation(0, img.getWidth()+shine.getWidth(),0, 0);
animation.setDuration(1000);
animation.setFillAfter(false);
animation.setRepeatCount(Animation.INFINITE);
animation.setInterpolator(new AccelerateDecelerateInterpolator());
shine.post(new Runnable() {
public void run() {
shine.startAnimation(animation);
}
});
}
}).start();
}
}
just write the code after setting your elements in onCreate()
#Override
protected void onCreate(Bundle SavedInstanceState){
super.onCreate(SavedInstanceState);
setContentView(yor_layout_source);
....
....
}
#Override
public void onResume(){
super.onResume();
//do your animation code here
}
and here your animation function :
public void doAnimation(){
new Thread(new Runnable() {
public void run() {
Animation animation = new TranslateAnimation(0, img.getWidth()+shine.getWidth(),0, 0);
animation.setDuration(550);
animation.setFillAfter(false);
animation.setInterpolator(new AccelerateDecelerateInterpolator());
shine.post(new Runnable() {
public void run() {
shine.startAnimation(animation);
}
});
}
}).start();
}

Android: Handler and Timer inside a RecyclerView is not working properly

In a chatting window I have a feature like self destructing message after a duration. For which I have a class which shows burning animation after the duration. While sending text the handler and timer I used in the below class is working fine for 2-3 times then some animation discrepancy is found like the fire isn't starting in exact location.
Apart from that while sending a file from file chooser fragment when it returns to the recyclerview of the chatwindow nothing happens until I touch the screen and scroll it a bit. While debugging I noticed that the first time when bindview is called after sending a file the handler and timer is not executing properly. Instead if I navigate back and enter the chatwindow again it's working perfectly. It burns the filemessage perfectly then.
The burner class:
public class Burner {
private static final TaggedLogger logger = new TaggedLogger("Burner");
public static void burnMessage(final TextMessageViewHolder holder, final BurnerListener listener) {
final int DURATION = 3000;
if (!holder.isBurning) {
final Handler handler = new Handler(Looper.getMainLooper());
final Animator.AnimatorListener animatorListener = new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animator) {
logger.log("onAnimationStart");
}
#Override
public void onAnimationEnd(Animator animator) {
listener.onBurnFinished();
}
#Override
public void onAnimationCancel(Animator animator) {
}
#Override
public void onAnimationRepeat(Animator animator) {
}
};
holder.isBurning = true;
holder.fireAnimationHolder.setVisibility(View.VISIBLE);
holder.fireAnimationHolder.measure(0, 0);
Activity activity = (Activity) ChatProperties.getChatWindowContext();
if (activity != null) {
final ParticleSystem particleSystem = new ParticleSystem(activity, 48, R.drawable.fire_2, DURATION)
.setSpeedByComponentsRange(-0.025f, 0.0f, -0.06f, -0.08f)
.setAcceleration(0.00003f, 0)
.setInitialRotationRange(30, 45)
.addModifier(new AlphaModifier(255, 0, 200, 1000))
.addModifier(new ScaleModifier(0.5f, 2f, 0, 1000));
holder.fireAnimationHolder.post(new Runnable() {
#Override
public void run() {
holder.fireAnimationHolder.measure(0,0);
int fireAnimationHolderWidth = holder.fireAnimationHolder.getWidth();
// logger.log("fireAnimationHolderWidth = " + fireAnimationHolderWidth);
particleSystem.emit(holder.fireSource, 12);
holder.fireSource.animate().translationXBy(fireAnimationHolderWidth).setStartDelay(500).setDuration(DURATION).setListener(animatorListener).start();
holder.fireSourceController.setPivotX(0);
holder.fireSourceController.animate().alpha(1f).scaleX(1f).setDuration(DURATION).start();
}
});
new Timer().scheduleAtFixedRate(new TimerTask() {
int elapsedTime = 0;
#Override
public void run() {
elapsedTime += 300;
if (elapsedTime >= DURATION) {
handler.post(new Runnable() {
#Override
public void run() {
particleSystem.cancel();
}
});
this.cancel();
} else {
handler.post(new Runnable() {
#Override
public void run() {
particleSystem.updateEmitPoint(holder.fireSource, Gravity.CENTER);
}
});
}
}
}, 100, 300);
}
}
}
This burnMessage method is called from the bindview of the TextMessageViewholder's bindview method and FilemessageViewHolder extends TextMessageViewHoler class.
In TextMessageViewHolder's bindview method this function is called if it's a self destructing message:
private void handleMessageBurning(final Message message) {
if (message.imBurnTime > 0 && BurnMessageHelper.animatedBurnMessageEntryMap.containsKey(message.callerId)) {
Log.e("BurnThread","message to be burned");
Burner.burnMessage(this, new BurnerListener() {
#Override
public void onBurnFinished() {
if (ChatProperties.isGroupChat) {
DataHelper.getInstance().deleteGroupMessage(Target.target, message.callerId);
} else {
DataHelper.getInstance().deleteMessage(Target.target, message.callerId);
}
BurnMessageHelper.animatedBurnMessageEntryMap.remove(message.callerId);
isBurning = false;
}
});
} else {
fireAnimationHolder.setVisibility(View.GONE);
}
}
What is happening here? Does the thread of the timer can't run in main thread here due to some reason? Please help. Thanks.
N.B. I tried this in Marshmallow, Nougat and Oreo.

how to check if an application is killed during an animation in android

i have to make an application in which it starts with an animation and if we click the back button then it should return back to application manager.But what i have made in it if u click back button during that animation then it goes to application manager but after a second or two the first page(the one after this animation comes up).
Can anyone help??
This is the animation..
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.load);
im = (ImageView) findViewById(R.id.load_icon);
rotate = AnimationUtils.loadAnimation(getApplicationContext(),
R.anim.load_page);
rotate.setInterpolator(new LinearInterpolator());
im.startAnimation(rotate);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Intent nextPageIntent = new Intent(getApplicationContext(),
P1.class);
startActivity(nextPageIntent);
}
}, 3000);
}
The first page opens because you have added
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Intent nextPageIntent = new Intent(getApplicationContext(),
P1.class);
startActivity(nextPageIntent);
}
}, 3000);
This launches the activity.For knowing if the animation has stopped use AnimationListener. More details here about animation listener
Android, How to set animation listener for view group?
You just added animation to one image view thats all, you do not doing anything with animation. The problem is, you started one thread to start activity P1 after 3 seconds. That thread only starting P1 activity. Try this and try to avoid killProcess(),
public class LauncherActivity extends Activity {
private Handler mHandler;
private Runnable mRunnable;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_launcher);
mHandler = new Handler();
mRunnable = new Runnable() {
#Override
public void run() {
Intent nextPageIntent = new Intent(getApplicationContext(),
XmlParserActivity.class);
startActivity(nextPageIntent);
}
};
mHandler.postDelayed(mRunnable, 3000);
}
/* #Override
public void onBackPressed() {
super.onBackPressed();
mHandler.removeCallbacks(mRunnable);
}*/
#Override
protected void onDestroy() {
super.onDestroy();
mHandler.removeCallbacks(mRunnable);
}
}
public void onBackPressed() {
android.os.Process.killProcess(android.os.Process.myPid());
}
This is the answer

Class to display flash screen

I would like to create a "Flash" class to display a white flash screen (200ms) as easily as a toast, like this:
Flash.create(context).show();
This layer should appear instantly then gradually disappear (alpha transition)
It must not catch events
It must adapt to the screen rotation
It can be created from any activity
I looked for a solution via WindowManager but I am having some difficulties.
What solution do you recommend?
There are some issues with that, as you'll have to pass the Activity and not just a Context into the "Flash" screen. Therefore the handling of screen rotation will be tricky.
I've created and open-sourced a small library called Crouton that can help you.
Currently it still struggles with the issue of orientation changes while a Crouton is being displayed.
So I give my own solution if it can help anybody...
(I changed the call to flash method since my first post)
public class Flasher {
private final static int DURATION_OFFSET = 300;
private final static int DURATION_FADEIN = 50;
private final static int DURATION_FADEOUT = 200;
private Animation fadein;
private Animation fadeout;
private RelativeLayout flash;
private RelativeLayout view;
private Toast toast;
private int count;
public Flasher(Context context) {
fadein = new AlphaAnimation(0, 1);
fadein.setStartOffset(DURATION_OFFSET);
fadein.setDuration(DURATION_FADEIN);
fadein.setAnimationListener(new AnimationListener() {
#Override public void onAnimationStart(Animation anim) {}
#Override public void onAnimationRepeat(Animation anim) {}
#Override public void onAnimationEnd(Animation anim) {
flash.startAnimation(fadeout);
}
});
fadeout = new AlphaAnimation(1, 0);
fadeout.setDuration(DURATION_FADEOUT);
fadeout.setAnimationListener(new AnimationListener() {
#Override public void onAnimationStart(Animation anim) {}
#Override public void onAnimationRepeat(Animation anim) {}
#Override public void onAnimationEnd(Animation anim) {
if(count > 1) {
flash(count - 1);
} else {
cancel();
}
}
});
LayoutParams params = new LayoutParams(-1, -1);
flash = new RelativeLayout(context);
flash.setLayoutParams(params);
flash.setBackgroundColor(0xffffffff);
flash.setVisibility(View.INVISIBLE);
view = new RelativeLayout(context);
view.setLayoutParams(params);
view.addView(flash);
toast = new Toast(context);
toast.setView(view);
toast.setGravity(Gravity.FILL, 0, 0);
}
public final void flash(int count) {
toast.show();
this.count = count;
flash.startAnimation(fadein);
}
public final void cancel() {
toast.cancel();
}
}
MainActivity for test it:
public class MainActivity extends Activity {
private static Flasher flasher;
#Override
public void onCreate(Bundle state) {
super.onCreate(state);
View layout = getLayoutInflater().inflate(R.layout.activity_main, null);
setContentView(layout);
if(flasher == null) {
flasher = new Flasher(this);
}
layout.setOnClickListener(new OnClickListener() {
#Override public void onClick(View v) {
flasher.flash(1);
}
});
}
#Override protected void onDestroy() {
if(isFinishing()) {
flasher = null;
}
super.onDestroy();
}
}
Thank you to Keyboardsurfer for the help!
Edit: a constraint is not satisfied:
The Toast does not dispatch the touch event:
flasher.flash(10);
MainActivity is not touchable during flashes effect
If anybody have a solution to resolve the problem...
After searching for many hours, it seems impossible to delegate events from one window to another. So the final functional solution I've found is to extend an activity so that it achieves this flash effect. For those who are interested in it, here's my subclass:
public class FlmActivity extends Activity {
private final static int DURATION_FADEIN = 50;
private final static int DURATION_FADEOUT = 200;
private final static int DURATION_INTERVAL = 200;
private View view;
private AnimationSet anim;
private int count;
public FlmActivity() {
super();
}
#Override protected void onPostCreate(Bundle state) {
super.onPostCreate(state);
view = new View(this) {{
setBackgroundColor(0xffffffff);
setVisibility(View.INVISIBLE);
}};
anim = new AnimationSet(false) {{
addAnimation(new AlphaAnimation(0, 1) {{
setDuration(DURATION_FADEIN);
}});
addAnimation(new AlphaAnimation(1, 0) {{
setStartOffset(DURATION_FADEIN);
setDuration(DURATION_FADEOUT);
}});
addAnimation(new Animation() {{
setStartOffset(DURATION_FADEIN + DURATION_FADEOUT);
setDuration(DURATION_INTERVAL);
setAnimationListener(new AnimationListener() {
#Override public void onAnimationStart(Animation anim) {}
#Override public void onAnimationRepeat(Animation anim) {}
#Override public void onAnimationEnd(Animation anim) {
flash(count - 1);
}
});
}});
}};
addContentView(view, getWindow().getAttributes());
}
#Override protected void onDestroy() {
((ViewGroup) view.getParent()).removeView(view);
super.onDestroy();
}
public final void flash(int count) {
if((this.count = count) > 0) {
view.startAnimation(anim);
}
}
}
Code to call flash effect in an extended activity:
flash(10);
With this implementation, the events pass through the layer

OnClickListener not firing until onResume()

I've got an activity in which several Views animate. The animations are triggered when a RelativeLayout containing a few images is clicked. It's set up in onCreate() like this:
mContainer.setOnClickListener(new ContainerClicked());
And the ContainerClicked() class looks like this:
private class ContainerClicked implements OnClickListener {
#Override
public void onClick(View arg0) {
Log.i(TAG, "TEST!");
mSomeButton.setOnClickListener(null);
mSomeButton.setEnabled(false);
mAnotherButton.setOnClickListener(null);
mAnotherButton.setEnabled(false);
mYetAnotherButton.setOnClickListener(null);
mYetAnotherButton.setEnabled(false);
mContainer.setOnClickListener(null);
if (mLogo.getVisibility() == View.VISIBLE)
new AnimateToParty().execute();
else
new AnimateFromParty().execute();
}
}
This works, and animates everything just how I want it.
AnimateToParty() looks like this:
private class AnimateToParty extends AsyncTask<Void, Integer, Void> {
#Override
protected void onProgressUpdate(final Integer... values) {
final View theView = findViewById(values[0]);
if (!(values[0] == mBackgroundImage.getId() || values[0] == mContainer
.getId())) {
final Animation animation = AnimationUtils.loadAnimation(
DashboardActivity.this, values[1]);
animation.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationStart(Animation arg0) {
}
#Override
public void onAnimationRepeat(Animation arg0) {
}
#Override
public void onAnimationEnd(Animation arg0) {
theView.setVisibility(View.INVISIBLE);
}
});
theView.startAnimation(animation);
} else if (values[0] == mBackgroundImage.getId()) {
TransitionDrawable transition = (TransitionDrawable) theView
.getBackground();
transition.startTransition(getResources().getInteger(
android.R.integer.config_mediumAnimTime));
} else {
TranslateAnimation animation = new TranslateAnimation(0, 0, 0,
TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
-60, getResources().getDisplayMetrics()));
animation.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationStart(Animation arg0) {
}
#Override
public void onAnimationRepeat(Animation arg0) {
}
#Override
public void onAnimationEnd(Animation arg0) {
LayoutParams lp = (LayoutParams) mContainer
.getLayoutParams();
lp.bottomMargin = 0;
RelativeLayout parent = (RelativeLayout) mContainer
.getParent();
mSomeButton.setVisibility(View.GONE);
mAnotherButton.setVisibility(View.GONE);
mYetAnotherButton.setVisibility(View.GONE);
mLogo.setVisibility(View.GONE);
// mContainer.setLayoutParams(lp);
// This caused a visible flicker, so I went with the solution below.
parent.removeView(mContainer);
parent.addView(mContainer, lp);
}
});
animation.setDuration(1000);
mContainer.startAnimation(animation);
}
}
#Override
protected Void doInBackground(Void... arg0) {
try {
publishProgress(mContainer.getId());
publishProgress(mLogo.getId(), R.anim.slide_out_up);
Thread.sleep(100);
publishProgress(mSomeButton.getId(), R.anim.slide_out_left);
Thread.sleep(110);
publishProgress(mAnotherButton.getId(), R.anim.slide_out_left);
Thread.sleep(120);
publishProgress(mYetAnotherButton.getId(), R.anim.slide_out_left);
Thread.sleep(130);
publishProgress(mBackgroundImage.getId());
Thread.sleep(550);
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
mContainer.setOnClickListener(new LighterClicked());
}
}
The class above animates some buttons and the logo out of the way, and then reveals the container. In order to keep it there, I change it's layoutparams. Just changing them produces a visible flicker where the container jumps 60 dip up for about one frame (the animation doesn't seem to be quite finished), before settling where I want it. I read somewhere to remove it from its parent and put it back in, and this does not produce the same flicker. However, now the rebinding of the onclicklistener does not work!
I've tried just about everything, and I just now noticed that every click that didn't "go through" fires if I press the home button and open the application again.
Is there a better way to avoid the "flicker"? A better way to do the animations? (I'm quite new at animating views) Why do the click-events fire when I reopen the application?
To avoid the flicker you are seeing, you have to call clearAnimation() at the start of onAnimationEnd
#Override
public void onAnimationEnd(Animation arg0) {
theView.clearAnimation()
...
}

Categories

Resources