Android Animation 2: View Animation
As stated in the previous blog "Android Animation: Drawable Animation", android Animation is mainly divided into three parts. The previous blog has explained the usage of Drawable Animation, that is, displaying images frame by frame, it is often used to dynamically display a progress animation, which is the most frequently used scenario. Next, we will introduce View Animation step by step in this article.
View Animation is also the Tweened Animation that we usually call in many books (someone translates it into a supplementary Animation ). View Animation is divided into four categories: AlphaAnimation, RotateAnimation, ScaleAnimation, and TranslateAnimation, which correspond to four types of changes: transparency, rotation, size, and displacement.
The effects of View Animation are determined by four factors: 1) Initial State; 2) end state; 3) duration; 4) Interpolator. Therefore, to define a View Animation, you only need to define the above four factors. The system automatically calculates how the intermediate process changes. The first three factors are easy to understand. The fourth factor is Interpolator, which is quite suitable for translation without knowing how to translate this word. Many books have very strange translations. Interpolator is the speed change of the animation process. For example, you move a button from the left side of the screen to the right side of the screen. It can speed up or slow down, which is the role of Interpolator. The specific usage method is as follows: Let's start with a simple one.
Like Drawable Animation, you can define a View Animation in code or XML format. Let's first write a simple example to move, rotate, zoom in, and darken a helloworld string using code implementation and XML file implementation. First use code.
Create a project: ViewAnimationDemo and create a layout file: animationjavacode. xml, as shown below:
ViewAnimationDemo eslayoutanimationjavacode. xml
The Activity corresponding to the XML layout file is as follows:
ViewAnimationDemo/src/com/CSDN/viewanimationdemo/AnimCodeActivity. java
Public class AnimCodeActivity extends Activity {private TextView translation; private TextView rotate; private TextView scale; private TextView alpha; private Button button; @ Override protected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); requestWindowFeature (Window. FEATURE_NO_TITLE); setContentView (R. layout. animationjavacode); translation = (TextView) findViewById (R. id. translation); rotate = (TextView) findViewById (R. id. rotate); scale = (TextView) findViewById (R. id. scale); alpha = (TextView) findViewById (R. id. alpha); button = (Button) findViewById (R. id. fire); button. setOnClickListener (new OnClickListener () {@ Overridepublic void onClick (View v) {// TODO Auto-generated method stub // 1 & 2: Determine the start status, final status: TranslateAnimation tAnim = new TranslateAnimation (0,400, 0, 0); // horizontal displacement of 400 units RotateAnimation rAnima = new RotateAnimation (0, 70 ); // clockwise rotation of 70 degrees ScaleAnimation sAnima = new ScaleAnimation (0, 5, 0, 5); // horizontal enlargement of 5 times, vertical enlargement of 5 times AlphaAnimation aAnima = new AlphaAnimation (1.0f, 0.0f); // change from full transparency to full transparency // 3: determine the duration of tAnim. setDuration (2000); rAnima. setDuration (2000); sAnima. setDuration (2000); aAnima. setDuration (2000); // 4: Confirm InterpolatortAnim. setInterpolator (new AccelerateDecelerateInterpolator (); // start the animation translation. startAnimation (tAnim); rotate. startAnimation (rAnima); scale. startAnimation (sAnima); alpha. startAnimation (aAnima );}});}}
It is not hard to see from the code that the starting and ending statuses of the animation are determined first, and then the duration is set through setDuration (2000). If no duration is set here, the default value is 30mx, invisible to the naked eye. Finally, we set an Interpolator. The effect here is that the animation is slowed down first and then slowed down. The default status is constant. That's right. The basic use of Interpolator is so easy. The above code is as follows:
Next we will explain how to use xml to define animations. According to the introduction on the android official website, the xml file format of View Animation is defined as follows:
...
This file can have only one root node, which can be ,, , , , Where, A node can contain sub-nodes. ,, , , And so on.
The two tag attributes to be explained above are android: interpolator and android: Embedded interpolator. The former represents the interpolator you are using, either the built-in or custom. The latter indicates whether to share the Interpolator with the subnode. The attributes of other sub-tags are easy to understand and can be understood basically by the attribute name. Apart from two of them, android: feature Tx and android: feature ty, we know that feature means axis, therefore, these two attributes define the Axis Position of the animation change. The default value is the upper left corner. when both of them are assigned 50%, the axis of the change is in the center.
Next, let's write a specific example, as shown in the following figure. Generally, we place the xml file for animation definition under the res/anim directory. First, we create an anim folder and then create an xml file, as shown below:
ViewAnimationDemo/res/anim/myanim. xml
The preceding example is as follows:
In the code above, there is a unique root node. It has two subnodes And And then the sub-nodes Has two subnodes And . I will explain some of the tag attributes that I have never seen before.
Andoird: fillAfter: In the previous example, after the animation ends, helloworld returns to the original state. By setting fillAfter to true, the animation ends. However, as mentioned in the previous blog "one of Android animations: Drawable Animation", the Animation effect of View Animation is drawn, but this component is not actually moved. We will continue to discuss this issue later. Now you only need to know that after you set fillAfter to true, the animation will remain in the end state, most of which are applied to the continuous animation design.
StartOffset: This attribute defines how long the animation starts to be postponed. With this attribute setting, we can design some animations that occur in order. Of course, apart from the last animation, set fillAfter to true for other animations.
Interpolator: here we use the built-in interpolator.
Next, we will define a layout file. The layout file has only one image and one button. by clicking the button to trigger the image for animation, the layout file is relatively simple and is not listed here. How can I start an animation in the activity code corresponding to the layout file? The Code is as follows:
ViewAnimationDemo/src/com/CSDN/viewanimationdemo/AnimaXmlActivity. java
public class AnimaXmlActivity extends Activity {private Button btn;private ImageView img;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);requestWindowFeature(Window.FEATURE_NO_TITLE);setContentView(R.layout.activity_anima_xml);btn = (Button)findViewById(R.id.xml_btn);img = (ImageView)findViewById(R.id.xmlAnimImg);btn.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubAnimation anim = AnimationUtils.loadAnimation(AnimaXmlActivity.this, R.anim.myanim);img.startAnimation(anim);}});}}
The above code is easy to understand. We generally use AnimationUtils to read animations defined in xml files.
By now, the basic knowledge of View Animation has been covered. Next, let's write a practical example to implement the side slide function that we often see, such as Netease news:
The implementation of this slide effect is not difficult. Many people use the AsyncTask thread, but you will find that there may be obvious freezing sometimes, but the animation effect will be much smoother if used. We will implement the following functions:
Create a project: SwipeWithAnim. Create a layout file activity_main.xml, as shown below:
SwipeWithAnim/res/layout/activity_main.xml
<framelayout android:layout_height="match_parent" android:layout_width="match_parent" tools:context=".MainActivity" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools">
</framelayout>
Content is displayed on the screen, and the menu is hidden on the left. Knowledge places the transparent part of 20dp on the left side of the screen to trigger the onTouch event. The activity code corresponding to the xml file is as follows:
SwipeWithAnim/src/com/CSDN/swipewithanim/MainActivity. java
Public class MainActivity extends Activity {private View menu; private final static int SHOW_MENU = 1; private final static int HIDE_MENU =-1; private int swipe_tag = SHOW_MENU; private int max_menu_margin = 0; private int min_menu_margin; private float beginX X; private float latestX; private float diffX; private float latestMargin; private FrameLayout. layoutParams lp;/** (non-Javadoc) ** @ see android. app. Activity # onCreate (android. OS. bundle) */@ Overrideprotected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); requestWindowFeature (Window. FEATURE_NO_TITLE); setContentView (R. layout. activity_main); menu = findViewById (R. id. menu); lp = (FrameLayout. layoutParams) menu. getLayoutParams (); min_menu_margin = lp. leftMargin; menu. setOnTouchListener (new OnTouchListener () {@ Overridepublic Boolean onTouch (View v, MotionEvent event) {// TODO Auto-generated method stubint action = MotionEventCompat. getActionMasked (event); switch (action) {case MotionEvent. ACTION_DOWN: begevents = event. getX (); break; case MotionEvent. ACTION_MOVE: latestX = event. getX (); diffX = latestX-beginX; swipe_tag = diffX> 0? SHOW_MENU: HIDE_MENU; latestMargin = lp. leftMargin + diffX; if (latestMargin> min_menu_margin & latestMargin <max_menu_margin) {lp. leftMargin = (int) (latestMargin); menu. setLayoutParams (lp);} break; case MotionEvent. ACTION_UP: TranslateAnimation tAnim; if (swipe_tag = SHOW_MENU) {tAnim = new TranslateAnimation (0, max_menu_margin-latestMargin, 0, 0); tAnim. setInterpolator (new DecelerateInterpolator () ); TAnim. setDuration (800); menu. startAnimation (tAnim);} else {tAnim = new TranslateAnimation (0, min_menu_margin-latestMargin, 0, 0); tAnim. setDuration (800); menu. startAnimation (tAnim);} // move the menu position at the end of the animation to make the menu move. TAnim. setAnimationListener (new AnimationListener () {@ Overridepublic void onAnimationStart (Animation animation) {// TODO Auto-generated method stub} @ Overridepublic void Merge (Animation animation) {// TODO Auto-generated method stub} @ Overridepublic void onAnimationEnd (Animation animation) {// TODO Auto-generated method stubif (swipe_tag = SHOW_MENU) {lp. leftMargin = max_menu_margin; menu. setLayoutParams (lp);} else {lp. leftMargin = min_menu_margin; menu. setLayoutParams (lp);} menu. clearAnimation () ;}}); break ;}return true ;}});}}
The above code listens to the onTouch event of the menu, and then moves the menu according to the moving distance. When the finger picks up, the animation is started so that the Movement continues until the end. As we mentioned above, View Animation is only the effect drawn out, And the Animation component is not actually moved. To solve this problem, we listened to the AnimationListener. At the end of the Animation, move the position of menu to the end of the animation, so that the menu is successfully moved. As shown in the following figure, due to the software relationship, it seems to be stuck, and testing on a real machine is completely smooth.
The two source codes before and after the blog are attached:
ViewAnimationDemo
SwipeWithAnim