I have a fragment that slides in when it is added and slides off the screen to the right when it is removed. However, only the sliding in animation is working, and when I set the visibility of the fragment to gone, it vanishes without sliding. This is also my first post here so please let me know if I'm not doing something right, thanks!
Activity code
protected void onCreate(Bundle savedInstanceState) {
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.setCustomAnimations(R.animator.slide_in, R.animator.slide_out_right);
Bundle bundle = new Bundle();
MyFragment myFrag = new MyFragment();
myFrag.setArguments(bundle);
ft.add(R.id.challenger_preview_fragment_container, myFrag, "MyFragment");
ft.commit();
}
Fragment code
public void removeFragment() {
getView().setVisibility(View.GONE);
}
Animation XML
slide_in
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<objectAnimator
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500"
android:propertyName="x"
android:valueFrom="1000"
android:valueTo="0"
android:valueType="floatType" />
</set>
slide_out_right
<?xml version="1.0" encoding="utf-8" ?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:interpolator/accelerate_decelerate"
android:valueFrom="-1280"
android:valueTo="0"
android:valueType="floatType"
android:propertyName="X"
android:duration="2000" />
</set>
Try the below code, in below create an animation object to slide out right and set the duration. Later create a listener to know when the animation is ending so that you can hide your view.
The problem in your above code is that you are hiding the view before the animation is ending.
Animation animation = AnimationUtils.loadAnimation(getActivity(),R.animator.slide_out_right);
animation.setDuration(800);
animation.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationEnd(Animation animation) {
try {
getView().setVisibility(View.GONE);
} catch (Exception e) {
e.printStackTrace();
}
}
});
//Start the animation.
getView().startAnimation(animation);
You are setting visibility getView().setVisibility(View.GONE);
So the fragment cannot come back again its GONE
Try getView().setVisibility(View.INVISIBLE);
And when it comes back make it visible again as getView().setVisibility(View.VISIBLE);
Related
I'm applying transition set for entering fragment and for exiting i want to apply slide out animation, how can i do that, here is my code:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
productDetailFragment.setSharedElementEnterTransition(new DetailsTransition());
productDetailFragment.setEnterTransition(new Fade());
productDetailFragment.setExitTransition(new Slide(Gravity.RIGHT));
}
((MainActivity)context).getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragment, productDetailFragment)
.addSharedElement(viewHolder.iv, "kittenImage")
.addToBackStack(null)
.commit();
Please check below code for custom animation apply to fragment transitions:
getSupportFragmentManager()
.beginTransaction()
.setCustomAnimations( R.anim.slide_up, 0, 0, R.anim.slide_down)
.show( m_topFragment )
.commit();
slide_up.xml
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator
xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/accelerate_decelerate_interpolator"
android:propertyName="translationY"
android:valueType="floatType"
android:valueFrom="1280"
android:valueTo="0"
android:duration="#android:integer/config_mediumAnimTime"/>
slide_down.xml
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator
xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/accelerate_decelerate_interpolator"
android:propertyName="translationY"
android:valueType="floatType"
android:valueFrom="0"
android:valueTo="1280"
android:duration="#android:integer/config_mediumAnimTime"/>
Above i am showing you slide_up and down transition but you can use left-right and any custom objectAnimator to show animations into your fragment transition time and hope it helps you.
try something like this.! may this work fine for you.!
Fragment Transaction Example
Using Slide Example
FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
Fade exitFade = new Fade();
exitFade.setDuration(FADE_DEFAULT_TIME);
previousFragment.setExitTransition(exitFade);
or
Transition slideTransition = new Slide(Gravity.BOTTOM);
Transition fadeTransition = new Fade();
TransitionSet set = new TransitionSet();
set.addTransition(slideTransition);
set.addTransition(fadeTransition);
Call Fragment :
FragmentManager fragmentManager = getSupportFragmentManager();
boolean fragmentPopped = fragmentManager.popBackStackImmediate("OtpFragment", 0);
Fragment fragment = null;
Bundle b = new Bundle();
if (!fragmentPopped && fragmentManager.findFragmentByTag("OtpFragment") == null) {
fragment = new OtpFragment();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.setCustomAnimations(R.anim.enter_from_right, R.anim.exit_from_left);
transaction.replace(R.id.frame_container, fragment, "OtpFragment")
.addToBackStack("OtpFragment")
.commit();
}
Create anim directory inside res folder :
now create two separate files for enter/exit animation : i.e. R.anim.enter_from_right and R.anim.exit_from_left
Enter Slide Animation :
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<translate
android:fromXDelta="100%" android:toXDelta="0%"
android:fromYDelta="0%" android:toYDelta="0%"
android:duration="300" />
</set>
Exit Side animation :
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<translate
android:fromXDelta="0%" android:toXDelta="-100%"
android:fromYDelta="0%" android:toYDelta="0%"
android:duration="300"/>
</set>
i have 5 to 6 activities in my application I have added left to right and right to left animation on activity start and on finish activity but its not working properly when I click for new activity its working fine it start from right to left but when i press back button its also start from right to left. but when I press hardware back button its work from left to right. here is my code
right to left animation
leftin.xml
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:fromXDelta="100%p"
android:toXDelta="0"
android:duration="500"/>
leftout.xml
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:fromXDelta="0"
android:toXDelta="-100%p"
android:duration="500"/>
rightin.xml
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:fromXDelta="-100%p"
android:toXDelta="0"
android:duration="500"/>
rightout.xml
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:fromXDelta="0"
android:toXDelta="100%p"
android:duration="500"/>
here is code oncreate activity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sub__category);
overridePendingTransition(R.anim.left_in, R.anim.left_out);
}
and here is code of my_back button
btn_back.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent myint = new Intent(Sub_Category_Activity.this,Home.class);
startActivity(myint);
overridePendingTransition(R.anim.right_in, R.anim.right_out);
finish();
}
});
and here is code of my onbackpress override method.
#Override
public void onBackPressed() {
super.onBackPressed();
Intent myint = new Intent(Sub_Category_Activity.this,Home.class);
startActivity(myint);
overridePendingTransition(R.anim.right_in, R.anim.right_out);
finish();
}
here I am facing problem is that when I press hardware back button its work fine but when i press back button of my UI it not start from left to right but start new activity form right to left
Use this code:
overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_left);
Slide in right xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false" >
<translate android:duration="800" android:fromXDelta="100%" android:toXDelta="0%" />
<alpha android:duration="800" android:fromAlpha="0.0" android:toAlpha="1.0" />
</set>
Slide out left xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false" >
<translate android:duration="800" android:fromXDelta="0%" android:toXDelta="-100%"/>
<alpha android:duration="800" android:fromAlpha="1.0" android:toAlpha="0.0" />
</set>
write overridePendingTransition(R.anim.right_in, R.anim.right_out);
after finish(); method.
I don't think you need to invoke overridependingtransitions() method in onCreate().
hi here is how i achieved this animation. i know my thinking of achieving this is not professional way but finally i achieved it by my way.
here is i have activity A,B,C so on activity B i check that is it clicked from Activity A or C and according to that i used if condition and implement animation some way like below code
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
pref = getSharedPreferences("MyPrefs", Context.MODE_PRIVATE);
editor = pref.edit();
String fromhome =pref.getString("from_home_list_adapter","");
if(fromhome.equals("yes"))
{
editor.putString("from_home_list_adapter","no");
editor.commit();
overridePendingTransition(R.anim.left_in, R.anim.left_out);
}
again i say this is not professional way to handle animation but its works
Please guide how to set Objectanimator dimension dynamically from device width.
Fragment replace code with animation
Fragment f = ... //defined elsewhere
FragmentManager fm1 = getFragmentManager()
FragmentTransaction ft1 = fm1.beginTransaction();
ft1.setCustomAnimations(R.animator.slide_in_left,
R.animator.slide_out_right);
ft1.replace(R.id.content_layout, f)
.addToBackStack(null)
.commit();
slide_in_left.xml
<?xml version="1.0" encoding="utf-8"?>
<set>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:propertyName="x"
android:valueType="floatType"
android:valueFrom="-800"
android:valueTo="0"
android:duration="500" />
</set>
how I am supposed to set the "valueFrom", and "valueTo" value based on device width,Please guide me it is possible to achieve this method or suggest some other ideas.
I need some help. em adding fragment to activity this way. problem is on each call of openFragment it create fragment and add. which is obvious. Question: what modification i do, so it can add fragment only once. on the next call with same fragment tag it will do nothing.
case: press button first time it add fragment and shows. i press again same button it response nothing.
public static void openFragment(Activity activity, Fragment fragment) {
FragmentManager fragmentManager = ((ActionBarActivity) activity)
.getSupportFragmentManager();
FragmentTransaction ftx = fragmentManager.beginTransaction();
ftx.addToBackStack(fragment.getClass().getSimpleName());
ftx.setCustomAnimations(R.anim.slide_in_right,
R.anim.slide_out_left, R.anim.slide_in_left,
R.anim.slide_out_right);
ftx.add(R.id.main_content, fragment);
ftx.commit();
}
Here's the solution, It will only allow you to add fragment once in stack otherwise it will pop-out the very same fragment from stack.
public static void openFragment(Activity activity, Fragment fragment) {
String fragmentTag = fragment.getClass().getName();
FragmentManager fragmentManager= ((ActionBarActivity) activity)
.getSupportFragmentManager();
boolean fragmentPopped = fragmentManager
.popBackStackImmediate(fragmentTag , 0);
if (!fragmentPopped && fragmentManager.findFragmentByTag(fragmentTag) == null) {
FragmentTransaction ftx = fragmentManager.beginTransaction();
ftx.addToBackStack(fragment.getClass().getSimpleName());
ftx.setCustomAnimations(R.anim.slide_in_right,
R.anim.slide_out_left, R.anim.slide_in_left,
R.anim.slide_out_right);
ftx.add(R.id.main_content, fragment);
ftx.commit();
}
}
slide_in_right
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="true">
<translate android:fromXDelta="100%"
android:toXDelta="0%" android:fromYDelta="0%"
android:toYDelta="0%" android:duration="200">
</translate>
</set>
slide_out_right
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<translate android:fromXDelta="0%" android:toXDelta="100%"
android:fromYDelta="0%" android:toYDelta="0%"
android:duration="200">
</translate>
</set>
slide_in_left
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="true">
<translate android:fromXDelta="-100%"
android:toXDelta="0%" android:fromYDelta="0%"
android:toYDelta="0%" android:duration="200">
</translate>
</set>
slide_out_left
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="true">
<translate android:fromXDelta="0%"
android:toXDelta="-100%" android:fromYDelta="0%"
android:toYDelta="0%" android:duration="200">
</translate>
</set>
And this is how you call this function:
openFragment(activity, new MyFragment());
Use FragmentTransaction.replace() instead of FragmentTransaction.add():
This is essentially the same as calling remove(Fragment) for all currently added fragments that were added with the same containerViewId and then add(int, Fragment, String) with the same arguments given here.
The first call to FragmentTransaction.replace() will simply add the fragment as there were no fragments to remove.
check if fragment is already added or not by using this method:
if(!Fragment.isAdded()){
//add fragment
}
Depending on your needs, there are multiple ways to approach this:
Disable or remove the button after it's clicked once.
As #hidro suggested, use replace() instead of add() when calling the FragmentTransaction.
Keep a List of string that will contain the class name of each fragment as it is added to the UI.
E.g.
List<String> fragments = new ArrayList<String>();
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
FragmentTransaction ftx = fragmentManager.beginTransaction();
ftx.add(R.id.main_content, fragment);
ftx.commit();
fragments.add(fragment.getClass().toString());
}
});
Before adding the fragment using FragmenTransaction.commit() check if its class exists in the list and if it does, don't add it.
Again, these 3 approaches work but which one will pick will depend on your app.
To add a fragment only once,
You need to check every time before adding the fragment to backstack,
that if previously it is already added or not. If it is added already,
then you should pop that entry and add another entry.
So, you can do this using :
boolean fragmentPopped = manager.popBackStackImmediate (backStateName, 0);
If fragmentPopped is true then there was a fragment added to backstack and itt is popped and you can add your fragment now to backstack. It is safe to call :
ftx.addToBackStack(fragment.getClass().getSimpleName());
If fragmentPopped is false then there was not any fragment added in backstack
Very nice information you can get : here
You can use show() method of fragment transaction
FragmentManager fragmentManager = ((ActionBarActivity) activity)
.getSupportFragmentManager();
FragmentTransaction ftx = fragmentManager.beginTransaction();
ftx.setCustomAnimations(R.anim.slide_in_right,
R.anim.slide_out_left, R.anim.slide_in_left,
R.anim.slide_out_right);
if(!fragment.isAdded())
{
//add fragment;
ftx.add(R.id.main_content, fragment).comit();
}
else
{
ftx.show(fragment).comit();
}
Updated
I've check some tutorials for animate transaction between fragments. I've used this method for animation and it works:
fragmentTransaction.setCustomAnimations(android.R.anim.slide_in_left,
android.R.anim.slide_out_right);
But I want to invert this animation: old fragment slide out to the left, and new fragment slide in to the right, but no value of R.anim file seems to be useful for my scope.
How can I do it?
UPDATE For Android v19+ see this link via #Sandra
You can create your own animations. Place animation XML files in res > anim
enter_from_left.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<translate
android:fromXDelta="-100%p" android:toXDelta="0%"
android:fromYDelta="0%" android:toYDelta="0%"
android:duration="#android:integer/config_mediumAnimTime"/>
</set>
enter_from_right.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<translate
android:fromXDelta="100%p" android:toXDelta="0%"
android:fromYDelta="0%" android:toYDelta="0%"
android:duration="#android:integer/config_mediumAnimTime" />
</set>
exit_to_left.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<translate
android:fromXDelta="0%" android:toXDelta="-100%p"
android:fromYDelta="0%" android:toYDelta="0%"
android:duration="#android:integer/config_mediumAnimTime"/>
</set>
exit_to_right.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<translate
android:fromXDelta="0%" android:toXDelta="100%p"
android:fromYDelta="0%" android:toYDelta="0%"
android:duration="#android:integer/config_mediumAnimTime" />
</set>
you can change the duration to short animation time
android:duration="#android:integer/config_shortAnimTime"
or long animation time
android:duration="#android:integer/config_longAnimTime"
USAGE
(note that the order in which you call methods on the transaction matters. Add the animation before you call .replace, .commit):
FragmentTransaction transaction = supportFragmentManager.beginTransaction();
transaction.setCustomAnimations(R.anim.enter_from_right, R.anim.exit_to_left, R.anim.enter_from_left, R.anim.exit_to_right);
transaction.replace(R.id.content_frame, fragment);
transaction.addToBackStack(null);
transaction.commit();
There is three way to transaction animation in fragment.
Transitions
So need to use one of the built-in Transitions, use the setTranstion()
method:
getSupportFragmentManager()
.beginTransaction()
.setTransition( FragmentTransaction.TRANSIT_FRAGMENT_OPEN )
.show( m_topFragment )
.commit()
Custom Animations
You can also customize the animation by using the setCustomAnimations() method:
getSupportFragmentManager()
.beginTransaction()
.setCustomAnimations( R.anim.slide_up, 0, 0, R.anim.slide_down)
.show( m_topFragment )
.commit()
slide_up.xml
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator
xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/accelerate_decelerate_interpolator"
android:propertyName="translationY"
android:valueType="floatType"
android:valueFrom="1280"
android:valueTo="0"
android:duration="#android:integer/config_mediumAnimTime"/>
slide_down.xml
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator
xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/accelerate_decelerate_interpolator"
android:propertyName="translationY"
android:valueType="floatType"
android:valueFrom="0"
android:valueTo="1280"
android:duration="#android:integer/config_mediumAnimTime"/>
Multiple Animations
Finally, It's also possible to kick-off multiple fragment animations
in a single transaction. This allows for a pretty cool effect where
one fragment is sliding up and the other slides down at the same time:
getSupportFragmentManager()
.beginTransaction()
.setCustomAnimations( R.anim.abc_slide_in_top, R.anim.abc_slide_out_top ) // Top Fragment Animation
.show( m_topFragment )
.setCustomAnimations( R.anim.abc_slide_in_bottom, R.anim.abc_slide_out_bottom ) // Bottom Fragment Animation
.show( m_bottomFragment )
.commit()
To more detail you can visit URL
Note:- You can check animation according to your requirement because above may be have issue.
slide_in_down.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="#android:integer/config_longAnimTime"
android:fromYDelta="0%p"
android:toYDelta="100%p" />
</set>
slide_in_up.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="#android:integer/config_longAnimTime"
android:fromYDelta="100%p"
android:toYDelta="0%p" />
</set>
slide_out_down.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="#android:integer/config_longAnimTime"
android:fromYDelta="-100%"
android:toYDelta="0"
/>
</set>
slide_out_up.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="#android:integer/config_longAnimTime"
android:fromYDelta="0%p"
android:toYDelta="-100%p"
/>
</set>
direction = down
activity.getSupportFragmentManager()
.beginTransaction()
.setCustomAnimations(R.anim.slide_out_down, R.anim.slide_in_down)
.replace(R.id.container, new CardFrontFragment())
.commit();
direction = up
activity.getSupportFragmentManager()
.beginTransaction()
.setCustomAnimations(R.anim.slide_in_up, R.anim.slide_out_up)
.replace(R.id.container, new CardFrontFragment())
.commit();
I have same issue, i used simple solution
1)create sliding_out_right.xml in anim folder
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="0" android:toXDelta="-50%p"
android:duration="#android:integer/config_mediumAnimTime"/>
<alpha android:fromAlpha="1.0" android:toAlpha="0.0"
android:duration="#android:integer/config_mediumAnimTime" />
</set>
2) create sliding_in_left.xml in anim folder
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="50%p" android:toXDelta="0"
android:duration="#android:integer/config_mediumAnimTime"/>
<alpha android:fromAlpha="0.0" android:toAlpha="1.0"
android:duration="#android:integer/config_mediumAnimTime" />
</set>
3) simply using fragment transaction setCustomeAnimations() with two custom xml and two default xml for animation as follows :-
fragmentTransaction.setCustomAnimations(R.anim.sliding_in_left, R.anim.sliding_out_right, android.R.anim.slide_in_left, android.R.anim.slide_out_right );
This is another solution which I use:
public class CustomAnimator {
private static final String TAG = "com.example.CustomAnimator";
private static Stack<AnimationEntry> animation_stack = new Stack<>();
public static final int DIRECTION_LEFT = 1;
public static final int DIRECTION_RIGHT = -1;
public static final int DIRECTION_UP = 2;
public static final int DIRECTION_DOWN = -2;
static class AnimationEntry {
View in;
View out;
int direction;
long duration;
}
public static boolean hasHistory() {
return !animation_stack.empty();
}
public static void reversePrevious() {
if (!animation_stack.empty()) {
AnimationEntry entry = animation_stack.pop();
slide(entry.out, entry.in, -entry.direction, entry.duration, false);
}
}
public static void clearHistory() {
animation_stack.clear();
}
public static void slide(final View in, View out, final int direction, long duration) {
slide(in, out, direction, duration, true);
}
private static void slide(final View in, final View out, final int direction, final long duration, final boolean save) {
ViewGroup in_parent = (ViewGroup) in.getParent();
ViewGroup out_parent = (ViewGroup) out.getParent();
if (!in_parent.equals(out_parent)) {
return;
}
int parent_width = in_parent.getWidth();
int parent_height = in_parent.getHeight();
ObjectAnimator slide_out;
ObjectAnimator slide_in;
switch (direction) {
case DIRECTION_LEFT:
default:
slide_in = ObjectAnimator.ofFloat(in, "translationX", parent_width, 0);
slide_out = ObjectAnimator.ofFloat(out, "translationX", 0, -out.getWidth());
break;
case DIRECTION_RIGHT:
slide_in = ObjectAnimator.ofFloat(in, "translationX", -out.getWidth(), 0);
slide_out = ObjectAnimator.ofFloat(out, "translationX", 0, parent_width);
break;
case DIRECTION_UP:
slide_in = ObjectAnimator.ofFloat(in, "translationY", parent_height, 0);
slide_out = ObjectAnimator.ofFloat(out, "translationY", 0, -out.getHeight());
break;
case DIRECTION_DOWN:
slide_in = ObjectAnimator.ofFloat(in, "translationY", -out.getHeight(), 0);
slide_out = ObjectAnimator.ofFloat(out, "translationY", 0, parent_height);
break;
}
AnimatorSet animations = new AnimatorSet();
animations.setDuration(duration);
animations.playTogether(slide_in, slide_out);
animations.addListener(new Animator.AnimatorListener() {
#Override
public void onAnimationCancel(Animator arg0) {
}
#Override
public void onAnimationEnd(Animator arg0) {
out.setVisibility(View.INVISIBLE);
if (save) {
AnimationEntry ae = new AnimationEntry();
ae.in = in;
ae.out = out;
ae.direction = direction;
ae.duration = duration;
animation_stack.push(ae);
}
}
#Override
public void onAnimationRepeat(Animator arg0) {
}
#Override
public void onAnimationStart(Animator arg0) {
in.setVisibility(View.VISIBLE);
}
});
animations.start();
}
}
The usage of class. Let's say you have two fragments (list and details fragments)as shown below
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/ui_container"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<FrameLayout
android:id="#+id/list_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<FrameLayout
android:id="#+id/details_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone" />
</FrameLayout>
Usage
View details_container = findViewById(R.id.details_container);
View list_container = findViewById(R.id.list_container);
// You can select the direction left/right/up/down and the duration
CustomAnimator.slide(list_container, details_container,CustomAnimator.DIRECTION_LEFT, 400);
You can use the function CustomAnimator.reversePrevious();to get the previous view when the user pressed back.
Have the same problem with white screen during transition from one fragment to another. Have navigation and animations set in action in navigation.xml.
Background in all fragments the same but white blank screen. So i set navOptions in fragment during executing transition
//Transition options
val options = navOptions {
anim {
enter = R.anim.slide_in_right
exit = R.anim.slide_out_left
popEnter = R.anim.slide_in_left
popExit = R.anim.slide_out_right
}
}
.......................
this.findNavController().navigate(SampleFragmentDirections.actionSampleFragmentToChartFragment(it),
options)
It worked for me. No white screen between transistion. Magic )
For me the only way I was able to get rid of the white background on the animation is if I changed to a DialogFragment instead of a Fragment and added the following code:
Created the following styles:
<style name="WindowSlideInAndOutAnimation">
<item name="android:windowEnterAnimation">#anim/slide_in_bottom</item>
<item name="android:windowExitAnimation">#anim/slide_out_top</item>
</style>
<style name="AppFullScreenDialogTransparentTitleBar" parent="Theme.MaterialComponents.Light.Dialog">
<item name="android:windowBackground">#android:color/transparent</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowIsFloating">false</item>
<item name="colorPrimaryDark">#android:color/transparent</item>
</style>
Then reference these styles in the dialog fragment as such:
override fun getTheme() = R.style.AppFullScreenDialogTransparentTitleBar
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
dialog?.window?.setWindowAnimations(R.style.WindowSlideInAndOutAnimation)
//rest of code on view created here
}
Then I just navigate to the fragment as normal via the navigation component (also note to change the type in the navigation xml file for the fragment to be dialog)