Android Fragment Animation

Good day to all. I want to devote this post to the topic of fragments for Android. There are already translations on Habré and some articles that mention how to start working with fragments for Android. For example, the article Fragments API in Android 3.0 . It contains a description of what fragments are and in which version of Android they are available, so those who have not yet reached it can, if they wish, get acquainted, I will not retell this in my post. Therefore, I will immediately get down to business.


Beginning of work


I will only say briefly that fragments are components of the user UI that can be used with the Activity class to display user data, but their life cycle does not depend on it. The functionality endowed with the fragments has a wider functionality for working with them than the Activity, so their use for developers is of no small importance if they want their application to have a more modern user interface by current standards.

Now let's move on to the essence of the post. In my opinion, fragments of the Google developers were endowed with excellent support for the animation displaying the fragment itself. This will be discussed further. I was looking for posts on this topic in Habr, but I did not find anything, so now I will share my knowledge.

Create a project


Let's create a small project. I created a project for my Samsung Nexus S, I have Android 4.1.2 version there, I actually used it (Api Level 16). I called the project itself FragmentsAnimationTest.

For demonstration, we will need the main activity and its layout, a couple of fragments, each with its own layout and a couple of xml-files for the animation itself, which I will discuss later.

The application will look like this: one of the fragments will be displayed on the screen, switching between them will be carried out using a regular button, and, accordingly, the switching of fragments will be accompanied by animation effects.

First, place the elements of the main activity in the activity_main.xml file:


It can be seen from the code that the main layout is used - RelativeLayout, which is quite convenient when working with fragments, two standard FrameLayout elements are placed in it - in fact, it will be a container for fragments and a button by which we will switch fragments between each other. So far, everything should be extremely simple.

Further we will be engaged in our fragments. Let's create markups for them and the classes themselves:
fragment1.xml


fragment2.xml


For both fragments, the code is almost the same, they differ only in the text that will be displayed in the fragment itself for its identification and the background color so that the animation can be clearly seen.

Fragment1.java
public class Fragment1 extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
                                Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_1, null);
    }
}


Fragment2.java
public class Fragment2 extends Fragment{
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
                                Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_2, null);
    }
}


In classes, everything should also be clear if you are familiar with the theme of fragments. They simply indicate which layout will be used when displaying a specific fragment and that’s it.

Now let's get to the tastiest. Let's work with the main activity class, here is its code:
public class MainActivity extends Activity {
    private Fragment fragment2;
    private Fragment fragment1;
    private FragmentTransaction ft;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.activity_main);
	fragment1 = new Fragment1();
	fragment2 = new Fragment2();
	ft = getFragmentManager().beginTransaction();
	ft.setCustomAnimations(R.animator.slide_in_left, R.animator.slide_in_right);
//	ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
	ft.replace(R.id.fragCont, fragment1);
	ft.addToBackStack(null);
	ft.commit();
	Button btn = (Button) findViewById(R.id.btn);
	btn.setOnClickListener(new OnClickListener() {
	    @Override
	    public void onClick(View v) {
		ft = getFragmentManager().beginTransaction();
		ft.setCustomAnimations(R.animator.slide_in_left, R.animator.slide_in_right);
//		ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
		if(fragment1.isVisible()){
		    ft.replace(R.id.fragCont, fragment2);
		}else{
		    ft.replace(R.id.fragCont, fragment1);
		}
		ft.commit();
	    }
	});
    }
}


Let's analyze what exactly is happening in our activity. First, both fragments are created, which, as already mentioned, will alternately change each other. Next, specify the line ft = getFragmentManager (). BeginTransaction () we get the FragmentTransaction, with which we can interact with our fragments, but this is all in the article that I mentioned earlier. Before moving on to parsing the following code, I will make a small digression.

There are two ways to create animations to display fragments:
  • The first way is to connect a standard animation using the setTransition (int transit) method. There are several predefined animations in the FragmentTransaction class.
  • The second method is exactly what interests us in this topic, the implementation of custom animation. Implemented using the setCustomAnimations () method.

Now back to the analysis of our code. Let's look at the next line ft.setCustomAnimations (R.animator.slide_in_left, R.animator.slide_in_right), here the animation is connected to all fragments that will be processed before the transaction is completed, to the line ft.commit (). What exactly is happening? Two parameters are passed to setCustomAnimations. The first parameter describes the animation to display the fragment that appears, and the second describes the animation for the fragment that changes, i.e. removed from the device screen. It is important to mention that this method should be called before fragments appear, otherwise, the animation will not be applied.

A couple of stock comments is to try to play with the described animation, just uncomment them and comment on the previous line - ft.setCustomAnimations (R.animator.slide_in_left, R.animator.slide_in_right), in both cases, although this not necessary.

Let's take the activation code to the end and move on to creating the animation itself.

After installing the animation, the fragment is shown, added to the stack and the transaction is completed to display all the changes. Then we initialize our button and attach to it a listener for the button click event, inside of which there is a code for changing fragments, at the click of a button we start the transaction, connect the animation and change the fragment to the one that is currently shown. The code is simple, so no deep explanation is required.

Create animation


Let's move on to the main part of our topic. Learn to create the animation itself. The way you create the animation here is a little different from how we used to do it in earlier versions of Android. The implementation is as follows. To start, you need to create the animator folder in the application resources folder, it will look like this - res / animator /. Here we should put xml files that will describe how the animation should be played. Put them there:
slide_in_left.xml


and slide_in_right.xml


Now we will analyze them in detail. Elements of the visual effects themselves are described in the objectAnimator tag, each such tag speaks of a description of a new animation effect. Now let's look at the attributes themselves. The first attribute in the slide_in_left.xml file is an interpolator, it has several values, you can learn more about them from the documentation of Property Animation. Interpolator is responsible for displaying our fragment in a certain way for a certain time. Next, we have the propertyName attribute, it indicates which particular property of the fragment we will change during the animation, in our example, y is the first, and valueType indicates what type of parameter we have. In the book Pro Android 4, this situation is argued by the fact that if you look at the setX () method in the View class, it becomes clear that it takes on a value of type float, with the setY () method, this is also the case, hence the value of floatType.

Next are the not unimportant attributes valueFrom and valueTo, they indicate from what value to which value to change the value specified in propertyName, in our first case it is y. If the valueFrom parameter is not specified, then the value is taken equal to the current one. In our case, valueFrom is -1280, which means that the movement of the fragment along the y axis will start with the value -1280, this value was chosen because it is outside the screen of the device and the movement will occur until the y value becomes equal 0 for the upper left corner of our fragment for 1500 milliseconds. And finally, the duration - attribute indicates exactly how long our animated effect will last in milliseconds.

And the last nuance that I want to describe. Looking at any of the animation description files, you can notice the set tag, which contains all the animation effects, it serves to combine effects or separate them. The slide_in_right.xml file uses the ordering attribute in the set tag, in our case it has a value of together, which means playing effects at the same time, in contrast to it there is a sequentially value that requires sequential display of effects in the animation, which is very convenient in some cases.

Actually that's all. The slide_in_right.xml file contains an example of how you can use other properties for animation, such as an alpha channel. I hope this article is useful to those who care about how its application will look.

As you yourself understand, dear habrayuzery, screenshots will not be able to display the result of work.

The literature and sources that were used when writing the post were mentioned during the article itself.

Also popular now: