Animasi Atribut Koleksi Animasi Android - Pandangan Pertama


Pengenalan kepada bahagian ini:

Bahagian ini membawakan jenis animasi ketiga dalam animasi Android - Animasi Harta. Ingat dalam bahagian sebelumnya 8.4.2 Koleksi animasi Android tween animasi ialah Fragmen Apabila menetapkan animasi peralihan, saya menyebut bahawa Fragmen di bawah pakej App dan pakej V4 memanggil setCustomAnimations() secara sepadan. Jenis animasi adalah berbeza. Yang di bawah pakej v4 ialah Animasi, manakala yang di bawah pakej apl ialah Animator; 🎜> ialah Kami belajar tentang

animasi bingkai dan animasi tween

lebih awal! Animator ialah animasi atribut yang akan kita bincangkan dalam bahagian ini! Mengenai animasi atribut, Pak Cik Guo telah menulis tiga artikel ringkasan yang sangat bagus. Tidak perlu mencipta semula. Tetapi mari kita bincangkannya di sini Kebanyakan kandungan merujuk kepada tiga artikel berikut:

Analisis lengkap animasi atribut Android (Bahagian 1), pemahaman pertama tentang penggunaan asas animasi atribut

Analisis lengkap animasi sifat Android (Bahagian 2), penggunaan lanjutan ValueAnimator dan ObjectAnimator

Analisis lengkap animasi sifat Android (Bahagian 2), penggunaan of Interpolator and ViewPropertyAnimator

Tulisannya sangat bagus, atau anda boleh langkau artikel ini terus dan baca tiga artikel di atas~Sudah tentu, jika anda sudi membaca celoteh saya , anda juga sangat dialu-alukan Okey, mari kita mulakan bahagian ini Mari kita bercakap tentang kandungan~

1 Konsep animasi atribut membosankan


Tiada BB, cuma. muat naik gambar, sangat ganas~


2. Penggunaan mudah ValueAnimator1.jpg


Proses penggunaan

:

1. Panggil kaedah statik ofInt

() ,
    ofFloat
  • () atau ofObject() ValueAnimator untuk mencipta contoh ValueAnimator 2. Panggil kaedah setXxx contoh untuk menetapkan tempoh animasi, kaedah interpolasi, bilangan ulangan, dll.3 Panggil
  • addUpdateListener
  • untuk menambah
  • . AnimatorUpdateListener
  • pendengar dalam pendengar Anda boleh mendapatkan nilai yang dikira oleh ValueAnimator, dan anda boleh menggunakan nilai pada objek yang ditentukan~4. Panggil kaedah start() untuk memulakan animasi! Di samping itu, kita dapat melihat bahawa kedua-dua ofInt dan ofFloat mempunyai parameter sedemikian: float/int... nilai mewakili berbilang nilai!
  • Contoh penggunaan
  • :

Pelaksanaan kod2.gif:

Fail reka letak :activity_main.xml, sangat mudah, empat butang, satu ImageView

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/ly_root"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <Button
        android:id="@+id/btn_one"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="动画1" />

    <Button
        android:id="@+id/btn_two"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="动画2" />

    <Button
        android:id="@+id/btn_three"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="动画3" />

    <Button
        android:id="@+id/btn_four"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="动画4" />

    <ImageView
        android:id="@+id/img_babi"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:background="@mipmap/img_babi" /></LinearLayout>

Kemudian pergi ke MainActivity.java, Pertama, kita memerlukan kaedah untuk mengubah suai kedudukan Lihat Di sini kita memanggil moveView() untuk menetapkan koordinat permulaan kiri dan atas serta lebar dan tinggi!

Kemudian empat animasi ditakrifkan, iaitu: pergerakan linear, penskalaan, putaran dengan ketelusan dan putaran bulat!

Kemudian cetuskan animasi yang sepadan melalui butang~

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private Button btn_one;
    private Button btn_two;
    private Button btn_three;
    private Button btn_four;
    private LinearLayout ly_root;
    private ImageView img_babi;
    private int width;
    private int height;

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

    private void bindViews() {
        ly_root = (LinearLayout) findViewById(R.id.ly_root);
        btn_one = (Button) findViewById(R.id.btn_one);
        btn_two = (Button) findViewById(R.id.btn_two);
        btn_three = (Button) findViewById(R.id.btn_three);
        btn_four = (Button) findViewById(R.id.btn_four);
        img_babi = (ImageView) findViewById(R.id.img_babi);

        btn_one.setOnClickListener(this);
        btn_two.setOnClickListener(this);
        btn_three.setOnClickListener(this);
        btn_four.setOnClickListener(this);
        img_babi.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_one:
                lineAnimator();
                break;
            case R.id.btn_two:
                scaleAnimator();
                break;
            case R.id.btn_three:
                raAnimator();
                break;
            case R.id.btn_four:
                circleAnimator();
                break;
            case R.id.img_babi:
                Toast.makeText(MainActivity.this, "不愧是coder-pig~", Toast.LENGTH_SHORT).show();
                break;
        }
    }


    //定义一个修改ImageView位置的方法
    private void moveView(View view, int rawX, int rawY) {
        int left = rawX - img_babi.getWidth() / 2;
        int top = rawY - img_babi.getHeight();
        int width = left + view.getWidth();
        int height = top + view.getHeight();
        view.layout(left, top, width, height);
    }


    //定义属性动画的方法:

    //按轨迹方程来运动
    private void lineAnimator() {
        width = ly_root.getWidth();
        height = ly_root.getHeight();
        ValueAnimator xValue = ValueAnimator.ofInt(height,0,height / 4,height / 2,height / 4 * 3 ,height);
        xValue.setDuration(3000L);
        xValue.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                // 轨迹方程 x = width / 2
                int y = (Integer) animation.getAnimatedValue();
                int x = width / 2;
                moveView(img_babi, x, y);
            }
        });
        xValue.setInterpolator(new LinearInterpolator());
        xValue.start();
    }

    //缩放效果
    private void scaleAnimator(){
    
        //这里故意用两个是想让大家体会下组合动画怎么用而已~
        final float scale = 0.5f;
        AnimatorSet scaleSet = new AnimatorSet();
        ValueAnimator valueAnimatorSmall = ValueAnimator.ofFloat(1.0f, scale);
        valueAnimatorSmall.setDuration(500);

        ValueAnimator valueAnimatorLarge = ValueAnimator.ofFloat(scale, 1.0f);
        valueAnimatorLarge.setDuration(500);

        valueAnimatorSmall.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float scale = (Float) animation.getAnimatedValue();
                img_babi.setScaleX(scale);
                img_babi.setScaleY(scale);
            }
        });
        valueAnimatorLarge.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float scale = (Float) animation.getAnimatedValue();
                img_babi.setScaleX(scale);
                img_babi.setScaleY(scale);
            }
        });

        scaleSet.play(valueAnimatorLarge).after(valueAnimatorSmall);
        scaleSet.start();

        //其实可以一个就搞定的
//        ValueAnimator vValue = ValueAnimator.ofFloat(1.0f, 0.6f, 1.2f, 1.0f, 0.6f, 1.2f, 1.0f);
//        vValue.setDuration(1000L);
//        vValue.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
//            @Override
//            public void onAnimationUpdate(ValueAnimator animation) {
//                float scale = (Float) animation.getAnimatedValue();
//                img_babi.setScaleX(scale);
//                img_babi.setScaleY(scale);
//            }
//        });
//        vValue.setInterpolator(new LinearInterpolator());
//        vValue.start();
    }


    //旋转的同时透明度变化
    private void raAnimator(){
        ValueAnimator rValue = ValueAnimator.ofInt(0, 360);
        rValue.setDuration(1000L);
        rValue.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                int rotateValue = (Integer) animation.getAnimatedValue();
                img_babi.setRotation(rotateValue);
                float fractionValue = animation.getAnimatedFraction();
                img_babi.setAlpha(fractionValue);
            }
        });
        rValue.setInterpolator(new DecelerateInterpolator());
        rValue.start();
    }

    //圆形旋转
    protected void circleAnimator() {
        width = ly_root.getWidth();
        height = ly_root.getHeight();
        final int R = width / 4;
        ValueAnimator tValue = ValueAnimator.ofFloat(0,
                (float) (2.0f * Math.PI));
        tValue.setDuration(1000);
        tValue.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                // 圆的参数方程 x = R * sin(t) y = R * cos(t)
                float t = (Float) animation.getAnimatedValue();
                int x = (int) (R * Math.sin(t) + width / 2);
                int y = (int) (R * Math.cos(t) + height / 2);
                moveView(img_babi, x, y);
            }
        });
        tValue.setInterpolator(new DecelerateInterpolator());
        tValue.start();
    }
}

Baiklah, prosesnya sangat mudah buat pertama kali objek ValueAnimator dan panggil ValueAnimator.ofInt/ofFloat Dapatkan, kemudian tetapkan tempoh animasi, addUpdateListener tambah AnimatorUpdateListener pendengar acara, Kemudian gunakan parameter animasi's getAnimatedValue() untuk mendapatkan nilai semasa, dan kemudian kita boleh menahan nilai ini Untuk mengubah suai beberapa sifat Paparan untuk membentuk kesan animasi yang dipanggil, dan kemudian menetapkan mod pemaparan animasi setInterpolator, Akhir sekali, start() dipanggil untuk memulakan main balik animasi~

Sial, persamaan garis lurus dan persamaan parametrik bulatan mula menjadikan saya segi empat sama ? Si bajingan saintifik pun lupa tentang fungsi trigonometri...3.gif

Contohnya daripada github:MoveViewValueAnimator


3 🎜>

Berbanding dengan ValueAnimator, ObjectAnimator lebih mudah digunakan Melalui kelas ini, kita boleh

secara langsung menganimasikan mana-mana atribut mana-mana objek! Betul, ia adalah sebarang objek, bukan hanya Lihat objek. Tetapkan nilai atribut tertentu secara berterusan dalam objek, dan kemudian tentukan cara memaparkannya berdasarkan perubahan dalam nilai atribut objek. keluarlah! Sebagai contoh, tetapkan animasi berikut untuk TextView: ObjectAnimator.ofFloat(textview, "alpha", 1f, 0f);Di sini, nilai alpha sentiasa ditukar, daripada 1f - 0f, dan maka objek berubah mengikut perubahan nilai atribut untuk menyegarkan paparan antara muka, oleh itu Menunjukkan kesan pudar masuk dan keluar, tetapi tiada atribut alfa dalam kelas TextView Mekanisme dalaman ObjectAnimator ialah:
Cari kaedah get dan set yang sepadan dengan nama atribut yang dipindahkan~, bukannya mencari kaedah. nilai atribut! Jika anda tidak percaya, anda boleh menyemak kod sumber TextView untuk melihat sama ada terdapat atribut alfa! Okay, mari kita gunakan ObjectAnimator untuk mencapai kesan empat jenis animasi tween~

Jalankan pemaparan:

4.gif

Pelaksanaan kod: Reka letak

secara langsung menggunakan reka letak di atas, menambah butang dan menggantikan ImageView dengan TextView Kod tidak akan disiarkan di sini. Pergi terus ke bahagian

MainActivity.java kod Malah, semuanya serupa~

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private Button btn_one;
    private Button btn_two;
    private Button btn_three;
    private Button btn_four;
    private Button btn_five;
    private LinearLayout ly_root;
    private TextView tv_pig;
    private int height;
    private ObjectAnimator animator1;
    private ObjectAnimator animator2;
    private ObjectAnimator animator3;
    private ObjectAnimator animator4;
    private AnimatorSet animSet;

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

    private void bindViews() {
        ly_root = (LinearLayout) findViewById(R.id.ly_root);
        btn_one = (Button) findViewById(R.id.btn_one);
        btn_two = (Button) findViewById(R.id.btn_two);
        btn_three = (Button) findViewById(R.id.btn_three);
        btn_four = (Button) findViewById(R.id.btn_four);
        btn_five = (Button) findViewById(R.id.btn_five);
        tv_pig = (TextView) findViewById(R.id.tv_pig);

        height = ly_root.getHeight();
        btn_one.setOnClickListener(this);
        btn_two.setOnClickListener(this);
        btn_three.setOnClickListener(this);
        btn_four.setOnClickListener(this);
        btn_five.setOnClickListener(this);
        tv_pig.setOnClickListener(this);
    }

    //初始化动画
    private void initAnimator() {
        animator1 = ObjectAnimator.ofFloat(tv_pig, "alpha", 1f, 0f, 1f, 0f, 1f);
        animator2 = ObjectAnimator.ofFloat(tv_pig, "rotation", 0f, 360f, 0f);
        animator3 = ObjectAnimator.ofFloat(tv_pig, "scaleX", 2f, 4f, 1f, 0.5f, 1f);
        animator4 = ObjectAnimator.ofFloat(tv_pig, "translationY", height / 8, -100, height / 2);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_one:
                animator1.setDuration(3000l);
                animator1.start();
                break;
            case R.id.btn_two:
                animator2.setDuration(3000l);
                animator2.start();
                break;
            case R.id.btn_three:
                animator3.setDuration(3000l);
                animator3.start();
                break;
            case R.id.btn_four:
                animator4.setDuration(3000l);
                animator4.start();
                break;
            case R.id.btn_five:
                //将前面的动画集合到一起~
                animSet = new AnimatorSet();
                animSet.play(animator4).with(animator3).with(animator2).after(animator1);
                animSet.setDuration(5000l);
                animSet.start();
                break;
            case R.id.tv_pig:
                Toast.makeText(MainActivity.this, "不愧是coder-pig~", Toast.LENGTH_SHORT).show();
                break;
        }
    }
}

juga sangat mudah untuk digunakan. Kami akan bercakap tentang gabungan animasi yang disebutkan di atas


4. Gabungan animasi dan AnimatorListener

Daripada dua contoh di atas, kami telah mengalami animasi gabungan, menggunakan kelas

AnimatorSet!

Kami memanggil kaedah main() dan kemudian menghantar animasi pertama untuk mula melaksanakan Pada masa ini, ia akan mengembalikan kelas Builder kepada kami:

5.png

Seterusnya Kita boleh memanggil empat kaedah yang disediakan oleh Builder untuk menggabungkan animasi lain:

  • selepas(Animator anim) Masukkan animasi sedia ada ke dalam animasi masuk dan laksanakan
  • < . animasi sedia ada dan animasi masuk pada masa yang sama
  • dengan
  • (Animator anim) Mari kita bercakap tentang pemantauan acara animasi Pendengar ValueAnimator kami di atas ialah
  • AnimatorUpdateListener. . Apabila status nilai berubah, kaedah onAnimationUpdate
  • akan dipanggil semula!
  • Selain acara seperti ini, terdapat: pemantauan kemajuan animasi ~ AnimatorListener
  • , kita boleh memanggil kaedah
addListener

Tambah pendengar, dan kemudian gantikan empat kaedah panggil balik berikut: onAnimationStart()

: animasi bermula

onAnimationRepeat(): Pelaksanaan berulang animasi

    onAnimationEnd()
  • : Animasi tamat
  • onAnimationCancel()
  • : Animasi dibatalkanYa ><🎜 jika anda benar-benar menggunakan AnimatorListener, anda perlu menulis semula keempat-empat kaedah itu, ia adalah sama seperti bahagian gerak isyarat sebelumnya. Android telah memberikan kami kelas penyesuai:
  • AnimatorListenerAdapter
  • , di mana setiap antara muka telah Kaedah-kaedah itu semua dilaksanakan, jadi kita boleh menulis kaedah panggil balik di sini!
  • 5. Gunakan XML untuk menulis animasi
  • Gunakan XML untuk menulis animasi mungkin mengambil masa lebih lama daripada kod Java, tetapi ia lebih mudah untuk digunakan semula. Teg XML yang sepadan ialah: <animator
  • ><
objectAnimator

><set> Atribut yang berkaitan dijelaskan seperti berikut:


android:ordering

: Tentukan susunan main balik animasi: secara berurutan (pelaksanaan berurutan), bersama-sama (pelaksanaan serentak) android:duration: Tempoh animasi

android:propertyName
    ="x": x di sini, ingat "alfa" di atas? Diperlukan dalam objek yang memuatkan animasi Tentukan kaedah getx dan setx, iaitu bagaimana objectAnimator mengubah suai nilai dalam objek!
  • android:valueFrom
  • ="1": Nilai awal permulaan animasi
  • android:valueTo
  • ="0": Nilai akhir daripada nilai akhir animasi
  • android:valueType
  • ="floatType": Tukar jenis data nilai
  • Contoh penggunaan adalah seperti berikut
  • :
  • Animasi peralihan lancar dari 0 hingga 100
  • :
    <animator xmlns:android="http://schemas.android.com/apk/res/android"  
        android:valueFrom="0"  
        android:valueTo="100"  
        android:valueType="intType"/>

    Tukar atribut alfa pandangan daripada 1 kepada 0:

    <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"  
        android:valueFrom="1"  
        android:valueTo="0"  
        android:valueType="floatType"  
        android:propertyName="alpha"/>

    tetapkan demonstrasi penggunaan animasi:

     <set android:ordering="sequentially" >
        <set>
            <objectAnimator
                android:duration="500"
                android:propertyName="x"
                android:valueTo="400"
                android:valueType="intType" />
            <objectAnimator
                android:duration="500"
                android:propertyName="y"
                android:valueTo="300"
                android:valueType="intType" />
        </set>
        <objectAnimator
            android:duration="500"
            android:propertyName="alpha"
            android:valueTo="1f" /></set>

    Muat fail animasi kami :

    AnimatorSet set = (AnimatorSet)AnimatorInflater.loadAnimator(mContext, 
                 R.animator.property_animator);  
    animator.setTarget(view);  
    animator.start();

    6. Muat turun contoh kod dalam bahagian ini:

    AnimatorDemo1.zip

    AnimatorDemo2.zip


    Ringkasan bahagian ini:

    Baiklah, bahagian ini akan memberi anda pengenalan ringkas kepada penggunaan asas animasi atribut dalam Android Saya tidak tahu sama ada anda mendapatnya , tetapi kandungannya agak mudah. Ya, dan contoh-contohnya agak menarik, saya percaya anda akan menyukainya, nah, itu sahaja, terima kasih~

    Terima kasihGuo Shen atas artikelnya~

    6.jpg