Animation for the back button in a DialogFragment - java

I have a class that extends DialogFragment, and I would like to add animation when the user presses the back button from that fragment
public class myClass extends DialogFragment{
private void myAnimation(){
// code here for animation...
}
}
How can I call myAnimation() when the user presses the back button from this fragment?

There are many animation you can choose for here take a look below:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/linear_interpolator">
<translate
android:fromXDelta="0"
android:toXDelta="100%p"
android:duration="500"
android:repeatCount="1"
android:repeatMode="reverse"/> //File name is anim_translate.xml
</set>
final Animation animTranslate = AnimationUtils.loadAnimation(this, R.anim.anim_translate)
Button btnTranslate = (Button)findViewById(R.id.translate);
btnTranslate.setOnClickListener(new Button.OnClickListener(){
#Override
public void onClick(View view) {
view.startAnimation(animTranslate);
}});
Take a look at this site AndroidAnimation

You can add animations into FragmentTransaction by method setCustomAnimations (int enter, int exit, int popEnter, int popExit) which is used to show DialogFragment(DialogFragment.show(transaction, tag)
).And you also need to invoke the method addToBackStack(tag) to make popExit animation avaliable.
So when you clicked the back button,it will automatically play the animation you have assigned(popExit animation).
Check the setCustomAnimations method here

Related

How do I make the button the user pressed, shrink in size upon being pressed?

I am developing a mobile game, in the game, the user presses buttons before they shrink, in order to make the game 'fun,' the buttons shrink at a faster and faster rate, so when the user presses one button, another button pops up that shrinks faster. So far I have this code which handles the user input and shrinking of the button, however, once pressed there is no animation, it instantly snaps to the 'shrunk' size, I'm not sure how to go about fixing this issue.
button.setOnClickListener(new Button.OnClickListener(){
#Override
public void onClick(View arg0) {
ViewGroup.LayoutParams params = button.getLayoutParams();
Integer value = 120;
while(value >= 2) {
value = value - 1;
SystemClock.sleep(50);
params.width = value;
params.height = value;
button.setLayoutParams(params);
};
}
});
I added the SystemClock.sleep(50) line as I thought that is why it was snapping (i.e. it was so quick that I just didn't see the animation) but that is not the case as the app just hangs until the button's size is updated.
P.s. I am quite new when it comes to developing mobile apps.
Edit
Forget what I wrote in my original post. Please try the code below and let me know whether this helps you out.
final ValueAnimator valueAnimator = ValueAnimator.ofFloat(1.0f, 0.0f); //start and end value
valueAnimator.setDuration(2000); //you can replace 2000 with a variable you can change dynamically
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator animation) {
float animatedValue = (float) animation.getAnimatedValue();
button.setScaleX(animatedValue);
button.setScaleY(animatedValue);
}
});
valueAnimator.start();
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
valueAnimator.pause();
}
});
Original answer
I would follow the suggestion of 0X0nosugar.
In your Android file tree, under your res directory, add an Android Resource Directory (right-click on res folder > new) and call it "anim". Android Studio probably automatically treat as a folder which holds animation if you use that name.
Right-click again on the anim-folder > new > Animation resource file.
Name it what you want. In my example I have named it button_animator.
Your file tree will look like this:
Your button_animator.xml could look like this:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale
android:interpolator="#android:anim/accelerate_decelerate_interpolator"
android:fromXScale="1.0"
android:toXScale="0.1"
android:fromYScale="1.0"
android:toYScale="0.1"
android:pivotX="50%"
android:pivotY="50%"
android:fillAfter="false"
android:duration="500" />
</set>
You can tailor the end scale of the button using these lines:
android:toXScale="0.1"
and
android:toYScale="0.1"
Inside your code you can dynamically tailor your animation:
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Animation shrinkButton = AnimationUtils.loadAnimation(MainActivity.this, R.anim.button_animator); //reference the animator
shrinkButton.setDuration(5000); //dynamically set the duration of your animation
button.startAnimation(shrinkButton); //start the animation. Since it is inside an onclicklistener, the animation start on a button click event
shrinkButton.setAnimationListener(new Animation.AnimationListener() { //you could use an AnimationListener to do something on certain event, like at the end of the animation
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) { //you probably want to something onAnimationEnd, otherwise the button will snap back into its original size.
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
}
});
In the onAnimationEnd you have to decide what you want to do at the end of the animation. Just a couple of ideas:
#Override
public void onAnimationEnd(Animation animation) { //you probably want to something onAnimationEnd, otherwise the button will snap back into its original size.
button.setScaleX(0.1f); //same size as in toScale size in the animator xml
button.setScaleY(0.1f);
}
Or, if you want the button to become invisible:
#Override
public void onAnimationEnd(Animation animation) {
button.setVisibility(View.INVISIBLE);
}

Android launch screen

I am building an Android application that opens different activities on start depending on firebase value. Right now I have an activity with just my logo that determines which activity to go to in its onCreate method. The problem is that I still get a white screen for half a second when launching my app because of the cold start. Is there a way to create a launch screen with my logo that will open a corresponding activity depending on returned firebase value and will replace the default white screen? Kinda like what WhatsApp or Instagram are doing these days. I know I can change window background in the styles.xml, but that's not ideal as it changes background everywhere and there will still be no way to determine which activity to open right on start
You need not change the background of all the windows. In order to show the splash screen instantaneously, consider using a custom theme just for the splash screen activity. Something like this:
Styles.xml
<style name="SplashTheme" parent="AppTheme">
<item name="android:windowBackground">#drawable/splash_drawable</item>
</style>
Splash Activity Screen layout
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/splashLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:screenOrientation="portrait"
android:theme="#style/SplashTheme">
<ProgressBar
android:id="#+id/splash_activity_progress"
style="#style/Widget.AppCompat.ProgressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:indeterminate="true"/>
</FrameLayout>
This will give you a Splash screen with a drawable(app logo). The progress bar let the user know that there are some background operations in progress.
To query the firebase you should use AsyncTask/Coroutine/Executor so that the operation is performed in background thread & the UI thread is not blocked. This is important to avoid ANRs.
Considering the fact that there is a possibility of AsyncTask getting deprecated, I suggest you consider wither Kotlin coroutines/Java executors framework instead of AsyncTasks.
Build a Splash screen that contains your logo.
It is very important to make firebase server (or any server) calls in the background.
Recommend you use AsyncTask with CallBack.
Base example:
The call back class:
public interface CallBack_TaskCompleted {
void taskIsCompleted(boolean success);
}
AsyncTask:
private static class DownloadDataAsync extends AsyncTask<String, Integer, String> {
CallBack_TaskCompleted callBack_taskCompleted;
String someData = "";
public DownloadDataAsync(String someData, CallBack_TaskCompleted callBack_taskCompleted) {
this.callBack_taskCompleted = callBack_taskCompleted;
this.someData = someData;
}
#Override
protected String doInBackground(String... params) {
// Some download staff
if (callBack_taskCompleted != null)
callBack_taskCompleted.taskIsCompleted();
return "Executed";
}
#Override
protected void onPostExecute(String result) {
MyUtils.logd("TAG", "onPostExecute");
}
#Override
protected void onPreExecute() {
MyUtils.logd("TAG", "onPreExecute");
}
#Override
protected void onProgressUpdate(Integer... values) {
MyUtils.logd("TAG", "onProgressUpdate" + values[0]);
}
}
In your activity:
DownloadDataAsync downloadDataAsync = new DownloadDataAsync("DATA", new CallBack_TaskCompleted() {
#Override
public void taskIsCompleted() {
// go to another activity
}
});

Android: Animations - how to determine the end of an xml file animation and start an AlphaAnim in java?

I have an animation(xml) file that sets an image view to appear like the credits of a movie:
<?xml version="1.0" encoding="utf-8"?>
<set
xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/linear_interpolator" >
<translate
android:duration="10000"
android:fromYDelta="100%p"
android:toYDelta="0%p" />
</set>
As you can see, the image stops "moving" when it gets full screen. This is ok.
My question is: how can I set a textView (hidden) visible when this IV reaches de end of the animation, so the text can be over the image?
The java code:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_final);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
mozart=(ImageView) findViewById(R.id.mozart);
Picasso.with(this).load(R.drawable.amadeus).fit().centerCrop().into(mozart);
read=(TextView) findViewById(R.id.read);
restart=(Button) findViewById(R.id.restart);
restart.setOnClickListener(this);
Animation moz= AnimationUtils.loadAnimation(this, R.anim.animation);
mozart.startAnimation(moz);
read.setVisibility(View.INVISIBLE);
read.setText("Text to appear with other alphaAnimation");
}
#Override
public void onClick(View view) {
if (view == restart) {
allaTurca.stop();
Intent a = new Intent(this, MainActivity.class);
startActivity(a);
this.finish();
}
}
}
Is it possible? I've tried several aproaches, but I cant't figure out how to tell the program when the image is ready to "receive" the text. Thaks for the help
FOR ANIMATION START REPEAT AND END
You have to add an animation listener to the animation like this
moz.setAnimationListener(new Animation.AnimationListener(){
#Override
public void onAnimationStart(Animation arg0) {
//Do Something on start
}
#Override
public void onAnimationRepeat(Animation arg0) {
}
#Override
public void onAnimationEnd(Animation arg0) {
}
});
When the animation starts it will first pass through the onStart( this is where u can initialize variables for animation) ...
then if you have repetition in your animation onAnimationRepeat will be called.
When the Animation is finished the onAnimationEnd will be called. ( This is the part you are interested in)
EDIT
As pointed out in the comments ... the better way of doing this is using AnimatorListenerAdapter .... thank you marmor
AnimatorListenerAdapter onEnd = new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator _a) {
DropZone.this.setTranslationY(getHeight() + 2);
DropZone.this.setAlpha(0f);
}
};
You can find examples here http://www.programcreek.com/java-api-examples/index.php?api=android.animation.AnimatorListenerAdapter

Android Animation with fillAfter set to true resets after clicking anywhere

In my Android project, I have a Button which is supposed to "animate out" after being clicked (and stay hidden). The effect is implemented as an AnimationSet defined in anim resources, which I'm loading using AnimationUtils. To freeze the animation on its last frame, I'm using setFillAfter(true).
private Button button;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_temp);
button = (Button) findViewById(R.id.button);
button.setOnClickListener(this);
}
#Override
public void onClick(View v) {
if (v != button) return;
this.runOnUiThread(new Runnable() {
#Override
public void run() {
Animation animation = AnimationUtils.loadAnimation(button.getContext(), R.anim.out_to_back);
animation.setFillAfter(true);
button.startAnimation(animation);
}
});
}
The animation resource itself is defined as follows:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false"
android:fillAfter="true"
android:duration="400">
<alpha
android:fromAlpha="1.0"
android:toAlpha="0.0" />
<scale
android:fromXScale="1"
android:toXScale="0"
android:fromYScale="1"
android:toYScale="0"
android:pivotX="50%"
android:pivotY="50%" />
</set>
After being clicked, the button animates as expected. The problem is, however, that the animation resets when I click anywhere else. A simple demo:
Is this a bug, or am I missing something really obvious? Thanks for any ideas!
Additional information
it doesn't matter whether I set fillAfter in code, in the XML resource, or both
when setting it in XML, it doesn't matter whether I apply it on the <set> element, or on both of the individual "components" <alpha> and <scale>
the preview was captured on an emulator running API 16
this does not happen on API 22
PS: I'm aware I'm better off using Animator, not the Animation APIs (unless I need to target pre-Honeycomb, which I don't)
I'm probably gonna switch to Animator anyway and see if this behavior persists. But I'm curious what's going on here anyway!
One thing you can try right away is to set the android:fillEnabled="true" attribute in your animation xml along with fillAfter. I'm not sure if that will help, but I know that's worked for some scenarios.
If that doesn't work, your other option is to set an AnimationListener for your animation, and then set your button's visibility to GONE once the animation has completed. This will make it so once the fade out happens, the button will be removed from the View until you choose to bring it back again. It would look something like this:
Animation animation = AnimationUtils.loadAnimation(button.getContext(), R.anim.out_to_back);
animation.setFillAfter(true);
animation.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
button.setVisibility(View.GONE);
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
button.startAnimation(animation);
It may complain that your button variable is not final. You should be able to fix that by simply assigning the View that comes in through your onClick method to a local final variable, like final View buttonView = v;

Starting activity on mouse click makes animation slow

So I am developing Android application in which I have a Home screen and another screen with the content of the app. On home screen I have a button which navigates the user to the content's screen (actually it is image view but used as a button).
When clicked this button should start animation of itself being clicked and then start the activity of the content screen.
But it actually works pretty bad and slow, when I click the button the animation starts but it slows down (lags). I tried changing the event from click to tap and lots of other possible solutions but none worked.
I tried commenting "startActivity" method and this fixed it, the animation was running smoothly. Obviously I need the startActivity method, so what is the best approach here, how can I fix this. Can putting startActivity in different thread work, I'm not sure how to do this if so as well
This is my code:
((Button)findViewById(R.id.btnPlay)).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(final View v) {
//shake.reset();
findViewById(R.id.btnPlay).startAnimation(shake);
shake.setAnimationListener(new Animation.AnimationListener() {
Intent i;
#Override
public void onAnimationStart(Animation animation) {
i = new Intent(v.getContext(), GameActivity.class);
startActivity(i);
}
#Override
public void onAnimationEnd(Animation animation) {
((Button) findViewById(R.id.btnPlay)).setVisibility(View.INVISIBLE);
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
}
});
shake is an animation loaded from custom xml file. I have the same animation in the content screen and it runs smoothly, of course there is no startActivity there. Here is the code:
<set xmlns:android="http://schemas.android.com/apk/res/android">
<rotate
android:duration="70"
android:fromDegrees="-5"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="5"
android:repeatMode="reverse"
android:interpolator="#android:anim/linear_interpolator"
android:toDegrees="5" />
<translate
android:fromXDelta="-10"
android:toXDelta="10"
android:repeatCount="5"
android:repeatMode="reverse"
android:interpolator="#android:anim/linear_interpolator"
android:duration="70" />
Move these lines of code in onAnimationEnd()
i = new Intent(v.getContext(), GameActivity.class);
startActivity(i);
UPDATE
I've just tried this code and it works well for me:
Animation animation = AnimationUtils.loadAnimation(MyApplication.getAppContext(), R.anim.shake);
public void onClick(View v) {
if (v.getId() == R.id.btnPlay) {
animation.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
Intent intent = new Intent(getActivity(), ArticleActivity.class);
startActivity(intent);
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
v.startAnimation(animation);
}
}
If the activity starts when the animation of the button starts, there could be too many things (like: button animation, execution of activity lifecycle methods including the lifecycle methods of the fragments, the animation used for transition between activities) which are executed on the main thread => the button animation could get stuck (the animation won't be smooth).

Categories

Resources