码迷,mamicode.com
首页 > 移动开发 > 详细

Android动画使用总结

时间:2016-10-28 15:49:06      阅读:376      评论:0      收藏:0      [点我收藏+]

标签:页面   get   art   位置   抛物线   erp   应用   事先   计算   

本文介绍Android动画的相关知识和使用方法:逐帧动画和补间动画。

一.逐帧(Frame)动画

逐帧动画逐帧动画就是顺序播放事先准备好的静态图像,利用人眼的”视觉暂留”的原理,给用户选择动画的错觉.

(一)逐帧动画的使用步骤

1.设计xml文件,要放在在drawable文件夹内
2.创建AnimationDrawable对象
3.使用AnimationDrawable操作动画的开始和暂停

比如:
//实例化控件对象
 TextView textView = (TextView) findViewById(R.id.main_text);
//获取动画对象才能对动画进行操作
AnimationDrawable 
anim = (AnimationDrawable) textView.getBackground();
//开始动画
anim.start();

(二)示例演示

1.anim_frame.xml文件的编写

<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="false">
    <item
        android:drawable="@mipmap/img001"
        android:duration="200" />
    <item
        android:drawable="@mipmap/img002"
        android:duration="200" />
    <item
        android:drawable="@mipmap/img003"
        android:duration="200" />
    <item
        android:drawable="@mipmap/img004"
        android:duration="200" />
    <item
        android:drawable="@mipmap/img005"
        android:duration="200" />
    <item
        android:drawable="@mipmap/img006"
        android:duration="200" />

</animation-list>

这里每一图片的动画时间单位是毫秒,如果设置时间太长,会显示幻灯片的效果,一般设置在100毫秒左右.

2.activity_main.xml文件编写

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.lwz.frameanimation.MainActivity">

    <TextView
        android:id="@+id/main_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:background="@drawable/anim_frame"
        android:text="动态图" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:orientation="horizontal">

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="start"
            android:text="开始动画" />

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="stop"
            android:text="停止动画" />

    </LinearLayout>

</RelativeLayout>

这里的动画属性资源要放在background里面才能使用。

3.java代码的编写

public class MainActivity extends AppCompatActivity {
    //布局内的控件
    TextView textView;
    //控制帧动画的对象
    AnimationDrawable anim;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_main);
        //实例化控件对象
         textView = (TextView) findViewById(R.id.main_text);
        //获取动画对象才能对动画进行操作
        anim = (AnimationDrawable) textView.getBackground();
    }

    //开始动画
    public void start(View v) {
        anim.start();
    }

    //停止动画
    public void stop(View v) {
        anim.stop();
    }

}

这里的动画操作对象是通过getBackground获取的,所以之前的动画资源要放在background里面。如果是ImageView的src放入动画资源是无法取得动画的对象的。

4.动画效果

技术分享

技术分享
这是一个表情包效果的动画,但是主要应用还是奔跑进行中的动画使用。

二.补间(Tween)动画

补时动画就是通过对场景的对象不断进行图像变化来产生动画效果,在实现补时动画时,只要定义动画开始和结束的”关键帧”其它过度帧由系统自动计算并补齐.android中提供了4种补间动画效果:透明、旋转、缩放、平移;

补间动画也要设置xml资源文件,但是它的资源文件放在anim文件夹里面,这个文件夹需要我们自己创建在res目录下。

(一)透明度渐变动画(AlphaAnimation)的资源文件设计

<set xmlns:android="http://schemas.android.com/apk/res/android">
 <alpha android:fromAlpha="1"
 android:toAlpha="0"
 android:repeatMode="reverse"
 android:repeatCount="1" 变化次数
 android:duration="2000"/>
 </set> 

属性说明
1. android:interpolator
用于控制动画的变化速度,使用动画效果可以匀速,加速,减速或抛物线速度等各种速度变化具体
见下表android:interpolotor属性的常用属性值
2. android:repeatMode
用于设置动画的重复方式,可选择为reverse(反向)或restart(重新开始)
3. android:repeatCount
用于设置动画的重复次数,属性可以是代表次数的数值,也可以是infinite(无限循环)
4. android:duration
用于指定donghua持续的时间,单位为毫秒
5. android:fromAlpha
用于指定动画开始时的透明度,值为0.0代表完全透明 ,值为1.0代表完全不透明
6. android:toAlpha
用于指定动画结束时的透明度,值为0.0代表完全透明,值为1.0代表完全不透明

7.android:interpolator属性的常用属性值
1) @android:anim/linear_interpolator 动画一直在做匀速改变
2) @android:anim/accelerate_interpolator 动画一在开始的地方变较慢,然后开始加

3) @android:anim/decelerate_interpolator 在动画开始的地方改变速度较快,然后开
始减速
4)@android:anim/accelerate_decelerate_interpolator 动画在开始和结束的地方
改变速度较慢,在中间的时候加速
5) @android:anim/cycle_interpolator 动画循环播放特定的次数,变化速度按正弦
曲线改变
6)@android:anim/bounce_interpolator 动画结束的地方采用弹球效果
7)@android:anim/anticipate_overshoot_interpolator 在动画开始的地方先向后退一
小步,再开始动画,到结束的地方再超出一小步,最后回到动画结束的地方
8)@android:anim/overshoot_interpolator 动画快速到达终点,并超出一小步最后回到动画结束的地方
9)@android:anim/anticipate_interpolator 在动画开始的地方先向后退一小步,再快速到达动画结束的地方

上面的很多属性值对下面的动画效果也是有效的。

(二)旋转动画(RotateAnimation)

旋转动画就是通过为动画指定开始时的旋转角度,结束时的旋转角度,经及持续时间来创建动画,在旋转时还可以通过指定轴心点坐标来改为旋转的中心
旋转动画的资源文件设计如下:

<set xmlns:android="http://schemas.android.com/apk/res/android">
<rotate
android:interpolator="@android:anim/accelerate_interpolator"
android:fromDegrees="0"
android:toDegrees="720"
android:pivotX="50%"
android:pivotY="50%"
android:duration="2000">
 </rotate>
</set>

属性说明
1. android:interpolotor 用于控制动画的变化速度,使用动画效果可以匀速,加速,减速或抛物线速度等各种速度变化具体
见表android:interpolator属性的常用属性值
2. android:fromDegrees 用于指定动画开始时旋转的角度
3. android:toDeggrees 用于指定动画结束时旋转的角度
4. android:pivotX 用于指定轴心点X轴坐标
5. android:pivotY 用于指定轴心点Y轴坐标
6. android:repeatMode 用于设置动画的重复方式,可选择为reverse(反向)或restart(重新开始)
7. android:repeatCount 用于设置动画的重复次数,属性可以是代表次数的数值,也可以是infinite(无限循环)
8. android:duration 用于指定动画持续的时间,单位为毫秒

(三)缩放动画(scaleAnimation)

缩放动画就是通过为动画指定开始时报缩放系数,结束时的缩放系数,以及持续时间来他建动画,在缩放时还可以通过指定轴心点坐标来改变绽放的中心。
 <set xmlns:android="http://schemas.android.com/apk/res/android">
 <scale android:fromXScale="1"
android:interpolator="@android:anim/decelerate_interpolator"
 android:fromYScale="1"
 android:toXScale="2.0"
 android:toYScale="2.0"
 android:pivotX="50%"
 android:pivotY="50%"
 android:repeatCount="1"
 android:repeatMode="reverse"
 android:duration="2000"/>
 </set>

属性说明
1. android:interpolotor 用于控制动画的变化速度,使用动画效果可以匀速,加速,减速或抛物线速度等各种速度变化具体见表android:interpolotor属性的常用属性值
2. android:fromXScale 用于指定动画开始时水平方向上的缩放系数,值为1.0表示不变化
3. android:toXScale 用于指定动画结束时水平方向上的缩放系数,值为1.0表示不变化
4. android:fromYScale 用于指定动画开始时垂直方向上的缩放系数,值为2.0表示放大一倍
5. android:toYScale 用于指定动画结束时垂直方向上的缩放系数,值为2.0表示放大一倍
6. android:pivotX 用于指定轴心点X轴坐标,50%表示自身的x轴中心点的,50%p表示父框体的x轴中心点
7. android:pivotY 用于指定轴心点Y轴坐标,50%表示自身的y轴中心点的,50%p表示父框体的y轴中心点
8. android:repeatMode 用于设置动画的重复方式,可选择为reverse(反向)或restart(重新开始)
9. android:repeatCount 用于设置动画的重复次数,属性可以是代表次数的数值,也可以是infinite(无限循环)
10. android:duration 用于指定动画持续的时间,单位为毫秒

(四)平移动画(TranslateAnimation)

平稳动画就是通过为动画指定开始时的位置,结束时的位置,经及持续时间来创建动画

<set xmlns:android="http://schemas.android.com/apk/res/android" android:fillAfter="true"
>
<translate
 android:fromXDelta="0"
android:toXDelta="320"
android:fromYDelta="0"
android:toYDelta="0"
android:repeatMode="reverse"
android:repeatCount="1"
android:duration="2000">
 </translate>
 </set>

属性说明
1. aandroid:fillAfter 用于指定动画结束后是否保存最后的效果,true代表是,这个属相一般要写在根标签里面,写在子标签里面是起不到作用的。
2. android:fromXDelta 用于指定动画开始时水平方向上的起始位置,默认单位是像素,可以使用100%代表的是自身长度,100%p代表的是父框体的长度。下面的距离也可以这样表示。
3. android:toXDelta 用于指定动画结束时水平方向上的起始位置
4. android:fromYDelta 用于指定动画开始时垂直方向上的起始位置
5. android:toYDelta 用于指定动画结束时垂直方向上的起始位置
6. android:repeatMode 用于设置动画的重复方式,可选择为reverse(反向)或restart(重新开始)
7. android:repeatCount 用于设置动画的重复次数,属性可以是代表次数的数值,也可以是infinite(无限循环)
8. android:duration 用于指定动画持续的时间,单位为毫秒

     上面就是四种补间动画的资源文件的属性介绍,其中有很多属性的值是相同的,有些也是有区别的,有些值是必须要设置的,比如:动画时间,相关动画效果的起始值和结束值。
     注意:持续时间是一次动画的时间,如果设置的动画的次数是2,那么动画结束时花的时间是3倍的动画持续时间。
     还有就是,一个set标签里面可以放多个动画效果的标签,比如一个在移动的图片可以让它同时改变透明的,也可以让它同时旋转等等。

(五)补间动画程序示例

1.透明效果动画资源文件alpha.xml的代码

<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="4000"
    android:fromAlpha="1"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
    android:repeatCount="5"
    android:fillAfter="true"
    android:toAlpha="0" />

这里的透明效果是从开始显示到最后完全消失,执行六次,总共花费时间24秒。最后完全消失!

2.旋转效果动画资源文件rotate.xml的代码

<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="4000"
    android:fillAfter="true"
    android:fromDegrees="0"
    android:toDegrees="1080"
    android:pivotX="50%"
    android:pivotY="50%"
    android:repeatMode="reverse"
    android:repeatCount="3"
     />

这里的旋转效果是图片从正常状态开始顺时针旋转三圈,然后反向旋转三圈,顺时针旋转三圈,然后反向旋转三圈,旋转四圈后停止。而且这里的旋转都是以自身的中心点开始旋转的。

3.缩放效果动画资源文件scale.xml的代码

<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="4000"
    android:fillAfter="true"
    android:fromXScale="1"
    android:fromYScale="1"
    android:toXScale="1.5"
    android:toYScale="1.5"
    android:pivotX="50%"
    android:pivotY="50%"
      />

这里的缩放效果没有指定重复的次数,照片以自己图片为中心放大1.5倍后,最后显示的是1.5倍图片大小的效果。

4.平移效果动画资源文件translate.xml的代码

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="4000"
    android:fillAfter="true"
    android:fromXDelta="0"
    android:fromYDelta="0"
    android:interpolator="@android:anim/cycle_interpolator"
    android:toXDelta="0"
    android:toYDelta="500" />

这里的平移效果比较简单只是从原来的位置往下平移500像素的距离,最后停留在那里。

5.各个效果动画资源文件anim_all的代码

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"    >
    <alpha
        android:duration="4000"
        android:fromAlpha="1"
        android:interpolator="@android:anim/accelerate_decelerate_interpolator"
        android:repeatCount="1"
        android:toAlpha="0.3"
        />

    <rotate
        android:duration="4000"
        android:fromDegrees="0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:repeatCount="3"
        android:toDegrees="1080" />

    <scale
        android:duration="4000"
        android:fromXScale="0.5"
        android:fromYScale="0.5"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toXScale="1.5"
        android:toYScale="1.5" />
    <translate
        android:duration="4000"
        android:fromXDelta="0"
        android:fromYDelta="0"
        android:interpolator="@android:anim/cycle_interpolator"
        android:toXDelta="0"
        android:toYDelta="500" />

</set>

这里只是把上面几个动画效果拼接起来,作为一个动画效果,可以看到,这个动画效果,有透明的效果,有旋转的效果,有缩放的效果,有平移的效果。

6.布局文件activity_main.xml的代码

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
     >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="alpha"
            android:text="透明动画" />


        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="rotate"
            android:text="旋转动画" />

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="scale"
            android:text="大小动画" />

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="translate"
            android:text="位置动画" />
    </LinearLayout>

    <TextView
        android:id="@+id/main_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:background="@mipmap/mm"
        android:text="Hello World!" />


</LinearLayout>

这里设置几个按钮来选择动画效果的显示,还有一个TextView来显示动画的效果,这里的显示效果控件可以是各种控件,可以是图片ImageView也可以是其他的。

7.java代码文件设计

package com.lwz.tweenanimation;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.TextView;

public class MainActivity extends Activity {
    //定义布局内的控件
    TextView textView;
    int index = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //实例化布局的内的控件
        textView = (TextView) findViewById(R.id.main_text);
        //定义操作补间动画的对象
        Animation anima = AnimationUtils.loadAnimation(this, R.anim.anim_all);
        textView.setAnimation(anima);


        //给补间动画设置监听事件
        anima.setAnimationListener(new Animation.AnimationListener() {
            //动画开始的时候回调
            @Override
            public void onAnimationStart(Animation animation) {
                Log.e("TAG", "start:" + index++);
            }

            //动画结束的时候回调
            @Override
            public void onAnimationEnd(Animation animation) {
                Log.e("TAG", "end:" + index++);              
            }

            //动画重复运行的时候回调
            @Override
            public void onAnimationRepeat(Animation animation) {
                Log.e("TAG", "repeat:" + index++);
            }
        });

    }

    public void alpha(View view) {
        Animation anima = AnimationUtils.loadAnimation(this, R.anim.alpha);
        textView.setAnimation(anima);
    }

    public void rotate(View view) {
        Animation anima = AnimationUtils.loadAnimation(this, R.anim.rotate);
        textView.setAnimation(anima);
    }

    public void scale(View view) {
        Animation anima = AnimationUtils.loadAnimation(this, R.anim.scale);
        textView.setAnimation(anima);
    }

    public void translate(View view) {
        Animation anima = AnimationUtils.loadAnimation(this, R.anim.translate);
        textView.setAnimation(anima);
    }

}

     上面的代码可以显示各种动画的效果,其中这里也测试了一下动画的监听事件,可以在监听事件里面做其他事情,比如在一个动画结束时,马上执行另一个动画。

程序运行效果:
技术分享

     动画正在进行时点击其他的动画效果的按钮,会停止原来的动画效果,显示新点击的动画效果。
     但是这个程序有一个debug就是,动画结束后再点击其他的动画效果是没有反应的。

(六)总结一下补间动画的使用步骤

1.设计xml文件,要放在在anim文件夹内

2.创建Animation对象

3.在某个控件对象中放入Animation对象就可以显示动画了。

比如:
TextView textView = (TextView) findViewById(R.id.main_text);
//定义操作补间动画的对象
Animation anima = AnimationUtils.loadAnimation(this, R.anim.anim_all);
textView.setAnimation(anima);
这里的R.anim.anim_all是资源文件

三.程序示例使用逐帧动画和补间动画

程序效果:小猪在页面上来回跑,并且脚是前后摆动的;
这个程序需要五张图片资源,一个大的背景图片,两张往前走的小猪的姿势图片,两张往回走的小猪的姿势图片。

这个程序可以使用很多方法来实现。
1.可以是图片的隐藏和显示的方法实现
小猪跑到最左边后隐藏,显示右边的小猪,一直重复上面的操作。
2.资源替换的方法
小猪跑到最左边后把动画效果和图片资源换成右边的小猪,一直重复上面的操作。
3.动画的时间监听来完成
小猪跑到最左边后把另一个动画效果切换,一直重复上面的操作。

但是无论任何都要使用到的是:
帧动画:使小猪的腿一直再跑的状态
补间动画:使小猪平移

(一)程序思路

     这里使用的是两个小猪在一直跑的状态的方法:
     第一个小猪从屏幕起点向右跑,一直跑到屏幕两倍的距离,一直重复这个动画;
     第二个小猪在屏幕两倍距离多一点的位置开始跑,跑过屏幕左边为止为止。一直重复这个动画。
     当第一个小猪跑过屏幕右边时,第二个小猪刚好从屏幕的右边界出现,看起来是同一个小猪在屏幕上来回跑。

(二)逐帧动画设计

1.第一个小猪的pig1_2.xml文件

<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:drawable="@mipmap/pig1"
        android:duration="100" />
    <item
        android:drawable="@mipmap/pig2"
        android:duration="100" />
</animation-list>

2.第二个小猪的pig3_4.xml文件

<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:drawable="@mipmap/pig3"
        android:duration="100" />
    <item
        android:drawable="@mipmap/pig4"
        android:duration="100" />
</animation-list>

(三)补间动画设计

1.第一个小猪的run.xml文件

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="10000"
        android:fromXDelta="0"
        android:fromYDelta="0"
        android:repeatCount="infinite"
        android:toXDelta="200%p"
        android:toYDelta="0" />

</set>

2.第二个小猪的run2.xml文件

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="10000"
        android:fromXDelta="120%p"
        android:fromYDelta="0"
        android:toXDelta="-100%p"
        android:repeatCount="infinite"
        android:toYDelta="0" />
</set>

第二个小猪的控件初始的位置是在屏幕的右边,所以再往右一个屏幕多一点,就是两个屏幕的距离。

(四)布局文件的设计

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@mipmap/background"
    tools:context="com.lwz.animation.MainActivity">

    <TextView
        android:id="@+id/main_iv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="130dp"
        android:background="@drawable/pig1_2" />

    <TextView
        android:id="@+id/main_iv2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_marginTop="150dp"
        android:background="@drawable/pig3_4" />
</RelativeLayout>

这里大背景在整个布局中,两个TextView来显示两个小猪。

(五)java代码设计

package com.lwz.animation;

import android.graphics.drawable.AnimationDrawable;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //第一只小猪
        TextView tv = (TextView) findViewById(R.id.main_iv);
        //帧动画的设置
        AnimationDrawable animationDrawable = (AnimationDrawable) tv.getBackground();
        animationDrawable.start();
        //补间动画的设置
        Animation animation = AnimationUtils.loadAnimation(this, R.anim.run);
        tv.setAnimation(animation);


        //对第二个小猪图片
        TextView tv2 = (TextView) findViewById(R.id.main_iv2);
        //帧动画的设置
        AnimationDrawable animationDrawable2 = (AnimationDrawable) tv2.getBackground();
        animationDrawable2.start();
        //补间动画的设置
        Animation animation2 = AnimationUtils.loadAnimation(MainActivity.this, R.anim.run2);
        tv2.setAnimation(animation2);


    }


}

这里的java代码都是比较简单的。

(六)运行效果

往前跑时:

技术分享

技术分享
往回跑时:
技术分享

技术分享

     这里就基本实现小猪来回跑的效果了,这里的第二个小猪要往右边的距离长一点是因为这里的小猪没有设置平移的速度,它在中间会加速前进,这里也可以设置两个小猪匀速前进。

Android动画使用总结

标签:页面   get   art   位置   抛物线   erp   应用   事先   计算   

原文地址:http://blog.csdn.net/wenzhi20102321/article/details/52955725

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!