I have two fragments (A, B), among which I can swap; what I wanted to achieve was a slide up / down animation between them every time I swapped them.
I tried using two object animator like this:
//slide up
<objectAnimator
android:interpolator="#android:interpolator/linear"
android:propertyName="translationY"
android:valueType="intType"
android:valueFrom="1920"
android:valueTo="0"
android:duration="1000" />
//Slide down
<objectAnimator
android:interpolator="#android:interpolator/linear"
android:propertyName="translationY"
android:valueType="intType"
android:valueFrom="0"
android:valueTo="1920"
android:duration="1000" />
but it didn't work because the two fragment were overlapping.
So how can I do that animation?
Fragment A:
class FragmentA : Fragment(){
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
buttonA.setOnClickListener {
activity.supportFragmentManager.beginTransaction()
.setCustomAnimations(R.animator.slide_dowm, R.animator.slide_up)
.replace(R.id.container, FragmentB()).commit()
}
}
}
Fragment B:
class FragmentB : Fragment(){
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
buttonB.setOnClickListener {
activity.supportFragmentManager.beginTransaction()
.setCustomAnimations(R.animator.slide_up, R.animator.slide_down)
.replace(R.id.container, FragmentB()).commit()
}
}
}
Google released the new Navigation UI library
So, now we can do the same fragment transitions from a your_named_navigation.xml resource (main > res > navigation > your_named_navigation.xml),
this an snippet code of my implementation:
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
app:startDestination="#+id/first_fragment">
<fragment
android:id="#+id/first_fragment"
android:name="com.yourpackage.FirstFragment"
android:label="#string/title_first"
tools:layout="#layout/fragment_first">
<action
android:id="#+id/second_fragment_action"
app:destination="#id/second_fragment"
app:enterAnim="#anim/slide_in_right"
app:exitAnim="#anim/slide_out_left"
app:popEnterAnim="#anim/slide_in_left"
app:popExitAnim="#anim/slide_out_right" />
</fragment>
<fragment
android:id="#+id/second_fragment"
android:name="com.yourpackage.SecondFragment"
android:label="#string/title_second"
tools:layout="#layout/fragment_second">
<action ...next fragment/>
</fragment>
</navigation>
it also helps to handle clicks on back button and up button,
so, after have NavigationUi implementation in our proyect, we can call from our firstFragment instance the Navigation.findNavController method
myButton.setOnClickListener(View.OnClickListener {
//This opens our second fragment creating a stack of fragments
Navigation.findNavController(it).navigate(R.id.second_fragment_action)
})
The next Google's Codelab helped me, maybe can help you, greetings
animator/slide_in_left.xml
<?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>
animator/slide_out_right.xml
<?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="0"
android:valueTo="-1000"
android:valueType="floatType" />
</set>
Class Subcategory
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
// return super.onCreateView(inflater, container, savedInstanceState);
View view = (ViewGroup) inflater.inflate(R.layout.product_frame, null);
getFragmentManager().beginTransaction()
.replace(R.id.sub_header, new Sub_Header()).commit();
getFragmentManager()
.beginTransaction()
.setCustomAnimations(R.animator.slide_in_left,
R.animator.slide_out_right, 0, 0)
.replace(R.id.product_frame, new Sub_Catagory_Grid()).commit();
view.getWidth();
return view;
}
Some links
Fragment transaction animation: slide in and slide out
How to apply a fade-in/fade-out animation when replacing a fragment
I want to change direction of an image in android animation.My fragment is
public class IconAnimation extends Fragment implements OnClickListener {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
final View v = inflater.inflate(R.layout.icon_animation, container,false);
return v;
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId())
{
case R.id.comedy:
Animation animation1 AnimationUtils.loadAnimation(getActivity(),
R.anim.slide);
ImageView image= (ImageView)v.findViewById(R.id.image);
image.startAnimation(animation1);
break;
}
}
}
and My animation XML is
<?xml version="1.0" encoding="utf-8"?>
<set
xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/linear_interpolator"
android:fillAfter="true">
<translate
android:fromXDelta="0%p"
android:toXDelta="150%p"
android:duration="800"
/>
Its output is something like this:Output
But I want something like this:expected outout
final TranslateAnimation animationt1 = new TranslateAnimation(fromXoffset, toXOffset, fromYoffset,toYoffset);
animationt1.setDuration(300);
animationt1.setFillAfter(true);
animationt1.setAnimationListener(this);
yourView.startAnimation(animation1);
You can do it also by XML :
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true"
android:interpolator="#android:anim/linear_interpolator" >
<!-- Use startOffset to give delay between animations -->
<!-- Move -->
<translate
android:duration="800"
android:fillAfter="true"
android:fromXDelta="0%p"
android:startOffset="700"
android:toXDelta="50%p" />
<translate
android:duration="800"
android:fillAfter="true"
android:fromYDelta="0%p"
android:startOffset="800"
android:toYDelta="-10%p" />
<translate
android:duration="800"
android:fillAfter="true"
android:fromXDelta="0%p"
android:startOffset="1300"
android:toXDelta="75%p" />
I am trying to add animated text(something like"Developed by .....") to Home page of my App.
But i couldn't show it completely.every time its length equals to shows only the width of the device. How can I solve this issue.My coding are as follows.
In my Home Activity
public class HomeActivity extends AppCompatActivity implements Animation.AnimationListener {
Animation animation;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
TextView txtAnimation=(TextView)findViewById(R.id.txtAnimation);
animation= AnimationUtils.loadAnimation(HomeActivity.this,R.anim.move);
String string="Developed by ................";
// set animation listener
animation.setAnimationListener(this);
txtAnimation.startAnimation(animation);
}
My move.XML
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/linear_interpolator"
android:fillAfter="true">
<translate
android:fromXDelta="100%"
android:toXDelta="-100%"
android:repeatMode="restart"
android:duration="8000"
android:repeatCount="infinite"/>
<!--android:toXDelta="0%p"-->
</set>
I tried by using setMaxWidth,setEmsbut not worked.
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)
I have different screen to work in an android application.
I'm using ViewFlipper for this.
I decided to used different class for different view children
public main extends Activity{
{
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sign_in);
ViewFlipper viewFlipper = (ViewFlipper) findViewById(R.id.viewFlipper);
HomeScreen s = new HomeScreen(getApplicationContext(), getCurrentFocus(), viewFlipper);
}
}
and this the Homescreen class is :-
public class HomeScreen {
private Button signIn;
private Button createAccount;
private View v;
private Context context;
private ViewFlipper viewflipper;
public HomeScreen(Context context,View v,ViewFlipper viewflipper ) {
this.v=v;
this.context = context;
this.viewflipper = viewflipper;
signIn = (Button) v.findViewById(R.id.button_sign_in_homeScreen);
createAccount = (Button)v.findViewById(R.id.button_createAccount_homeScreen);
signIn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
viewflipper.setDisplayedChild(1);
}
});
}
but is shows run exception
java.lang.RuntimeException: Unable to start activity ComponentInfo
Can anyone please help me
is getCurrentFocus() is the correct way to get the view?
What i try to implement is
I need to use different class for defining, listening the controls of each child of view flipper
In the above example HomeScreen is one of my the child screen of view flipper
But the line v.findViewById is showing error i think that getCurrentFocus() is not the correct way to sent the view
I don't know weather i'm moving in the correct way? When i define and listen all the controls of all children of viewflipper in the Class where i define that viewflpper, that class become very big. That made me to think so..
Thanks...
U can perfrom animation using Intent to:
Step1: create anim folder under res directory in ur project.
Step2: create an slideleft.xml file
Step3: type the following code in that file
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/accelerate_interpolator">
<translate android:fromXDelta="100%p" android:toXDelta="0"
android:duration="400" />
</set>
step 4: similarly create slideright.xml
step5: use the above code, but change the following
<translate android:fromXDelta="-100%p" android:toXDelta="0"
android:duration="400" />
step 6:
target.startAnimation(AnimationUtils.loadAnimation(HomeScreen.this, R.anim.slide_left));
perfroming fadein operation, just add the following code in fadein.xml file
<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/accelerate_interpolator"
android:fromAlpha="0.0" android:toAlpha="1.0"
android:duration="300" />
similarly for fade out too
<?xml version="1.0" encoding="UTF-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/accelerate_interpolator"
android:fromAlpha="1.0" android:toAlpha="0.0"
android:duration="300" />