ViewAnimator及其子类

1. ViewAnimator相关

1.1 ViewAnimator的作用

在Android中,ViewAnimator是FrameLayout的一个子类,用来做Views之间的切换。它是一个变换控件的
元素,帮助我们在Views之间(如TextView, ImageView或者其他layout)添加变换。它有助于在屏幕view添加动画。ViewAnimator可以在两个及以上Views上平滑的切换,通过合适动画,提供从一个View到另外一个View变换的方式。

1.2 ViewAnimator及其子类关系继承图

ralation

1.3 常用的xml属性

XML属性说明
android:animateFirstView显示第一个View组件时是否使用动画
android:inAnimation显示子View组件时的动画
android:outAnimation隐藏子View组件时的动画

1.4 常用方法

  • showNext() 这个方法用于展示ViewAnimator的下一个view。,viewanimator可以有两个或者更多的子视图,一次只显示一个子视图,所以这个方法用于展示下一个视图。
  • showPrevious() 这个方法用于展示ViewAnimator的上一个view。viewanimator可以有两个或者更多的子视图,一次只显示一个子视图,所以这个方法用于展示上一个视图。
  • setInAnimation(Animation inAnimation) 这个方法用于设置对象进入屏幕的动画。
  • setOutAnimation(Animation outAnimation) 这个方法用于设置对象从屏幕上消失的动画
  • addView(View child) 这个方法用于运行时在ViewAnimator添加view
  • getCurrentView() 这个用于获取ViewAnimator当前显示的子view
  • getDisplayedChild() 这个方法用于获取ViewAnimator当前显示的子View的索引,返回一个int值。
  • getInAnimation() 此方法用于获取当前用于进入屏幕的View动画。
  • getOutAnimation() 此方法用于获取当前用于退出屏幕的View动画。
  • removeAllViews() 这个方法用于从ViewGroup移除所有的子view。
  • removeView(View view) 这个方法用于移除ViewAnimator的子View。
  • removeViewAt(int index) 这个用于移除在布局里特定位置的view。
  • setDisplayedChild(int whichChild)这个方法用于设置在ViewAnimator显示的子View。
  • setAnimateFirstView(boolean animate) 这个方法用于设置当前视图是否应在第一次显示ViewAnimator时进行动画。
  • getAnimateFirstView()这个方法检查当前view是否在第一次viewanimator显示时进行动画。

1.5 代码示意

1.5.1 activity代码

package com.example.ip_d.viewanimatorexample;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ViewAnimator;

public class MainActivity extends AppCompatActivity {

    private ViewAnimator simpleViewAnimator;
    Button btnNext;
    /**
     * array of images
     */
    int[] images = {
            R.drawable.lion,
            R.drawable.cat,
            R.drawable.dog,
            R.drawable.bird1,
            R.drawable.bird2};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        // get The references of Button and ViewAnimator
        btnNext = (Button) findViewById(R.id.buttonNext);
        // get the reference of ViewAnimator
        simpleViewAnimator = (ViewAnimator) findViewById(R.id.simpleViewAnimator);
        for (int i = 0; i < images.length; i++) {
            // create a new object  for ImageView
            ImageView imageView = new ImageView(getApplicationContext());
            // set image resource for ImageView
            imageView.setImageResource(images[i]);
            // add child view in ViewAnimator
            simpleViewAnimator.addView(imageView);
        }
        // Declare in and out animations and load them using AnimationUtils class
        Animation in = AnimationUtils.loadAnimation(this, android.R.anim.slide_in_left);
        Animation out = AnimationUtils.loadAnimation(this, android.R.anim.slide_out_right);

        // set the animation type to ViewAnimator
        simpleViewAnimator.setInAnimation(in);
        simpleViewAnimator.setOutAnimation(out);
        // set false value for setAnimateFirstView
        simpleViewAnimator.setAnimateFirstView(false);

        // ClickListener for NEXT button
        // When clicked on Button ViewSwitcher will switch between views
        // The current view will go out and next view will come in with specified animation
        btnNext.setOnClickListener(new View.OnClickListener() {

            public void onClick(View v) {
                // TODO Auto-generated method stub
                // show the next view of ViewAnimator `     `
                simpleViewAnimator.showNext();
            }
        });

    }

}

1.5.2 layout代码

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#fff"
    android:orientation="vertical">

    <ViewAnimator
        android:id="@+id/simpleViewAnimator"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

    </ViewAnimator>


    <Button
        android:id="@+id/buttonNext"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginTop="150dp"
        android:background="#055"
        android:text="NEXT"
        android:textColor="#fff"
        android:textStyle="bold" />

</LinearLayout>

2. ViewSwitcher相关

2.1 基本介绍

ViewSwitcher继承自ViewAnimator,代表了视图切换组件,大体上与ViewAnimator差不多。与ViewAnimator最大不同就是ViewSwitcher的子view最多只能有两个,多余两个将会报错。还有就是ViewSwitcher可以通过setFactory(ViewFactory factory)生成两个相同的子view,也可以通过addView(View view)方法添加子view。

2.2 代码示例

2.2.1 直接在xml添加子view

package com.xiayutian.widgettest;

import android.os.Bundle;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.ViewSwitcher;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;

public class ViewSwitcherActivity extends AppCompatActivity {

    @BindView(R.id.btn_switch)
    Button btnSwitch;
    @BindView(R.id.view_switcher)
    ViewSwitcher viewSwitcher;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.view_switcher_activity);
        ButterKnife.bind(this);
        initSwitcher();
    }

    private void initSwitcher() {
        Animation slide_in_left = AnimationUtils.loadAnimation(this, android.R.anim.slide_in_left);
        Animation slide_out_right = AnimationUtils.loadAnimation(this, android.R.anim.slide_out_right);

        viewSwitcher.setInAnimation(slide_in_left);
        viewSwitcher.setOutAnimation(slide_out_right);
    }

    @OnClick(R.id.btn_switch)
    void switchView() {
        viewSwitcher.showNext();
    }
}


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

    <Button
        android:id="@+id/btn_switch"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="切换"/>
    
    <ViewSwitcher
        android:id="@+id/view_switcher"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="我是第一个子View"
            android:layout_gravity="center"
            android:background="@color/colorAccent"/>

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/screen2"/>
    </ViewSwitcher>

</LinearLayout>

2.2.2 通过ViewFactory添加子view

package com.xiayutian.widgettest;

import android.os.Bundle;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.TextView;
import android.widget.ViewSwitcher;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;

public class ViewSwitcherActivity extends AppCompatActivity {

    @BindView(R.id.btn_switch)
    Button btnSwitch;
    @BindView(R.id.view_switcher)
    ViewSwitcher viewSwitcher;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.view_switcher_activity);
        ButterKnife.bind(this);
        initSwitcher();
    }

    private void initSwitcher() {
        Animation slide_in_left = AnimationUtils.loadAnimation(this, android.R.anim.slide_in_left);
        Animation slide_out_right = AnimationUtils.loadAnimation(this, android.R.anim.slide_out_right);

        viewSwitcher.setInAnimation(slide_in_left);
        viewSwitcher.setOutAnimation(slide_out_right);
        /**
         * 通过setFactory可以给ViewSwitcher添加两个基本相同的子view
         */
        viewSwitcher.setFactory(() -> {
            TextView textView = new TextView(ViewSwitcherActivity.this);
            textView.setLayoutParams(new FrameLayout.LayoutParams(300,300));
            textView.setBackgroundResource(R.color.colorAccent);
            textView.setText("我是第一个文本");
            return textView;
        });
    }

    @OnClick(R.id.btn_switch)
    void switchView() {
        viewSwitcher.showNext();
        /**
         * 当viewSwitcher.getDisplayedChild() == 0时就是第一个子view,否者就是第二个子view
         * 分别给他们设置不同的内容
         */
        ((TextView)viewSwitcher.getCurrentView()).setText(viewSwitcher.getDisplayedChild() == 0 ? "我是第一个文本" : "我是第二个文本");
    }
}


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

    <Button
        android:id="@+id/btn_switch"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="切换" />

    <ViewSwitcher
        android:id="@+id/view_switcher"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</LinearLayout>

3. ImageSwitcher相关

3.1 基本介绍

ImageSwitcher是ViewSwitcher的子类,大多特性和ViewSwitcher一样,也可以当成一个ViewSwitcher使用。不过ImageSwicher添加setImageResource(@DrawableRes int resid),
setImageURI(Uri uri),setImageDrawable(Drawable drawable)等方法在切换到下一次时,同时也把要显示的图片资源设置。从下面的源码可以看出,调用这几个setImagexxx方法时,必须保证ImageSwitcher的子view是ImageView,否者程序无法正常运行。

    public void setImageResource(@DrawableRes int resid)
    {
        ImageView image = (ImageView)this.getNextView();
        image.setImageResource(resid);
        showNext();
    }

3.2 代码示例

这个例子和前面的ViewSwitcher有点不一样,在这里给子view设置不同的图片资源,实现了一个图片轮播的场景。

package com.xiayutian.widgettest;

import android.os.Bundle;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageSwitcher;
import android.widget.ImageView;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;

public class ImageSwitcherActivity extends AppCompatActivity {
    @BindView(R.id.btn_next)
    Button btnNext;
    @BindView(R.id.image_switcher)
    ImageSwitcher imageSwitcher;

    private int position = 0;
    private int[] images = {R.drawable.screen1, R.drawable.screen2, R.drawable.screen3, R.drawable.screen4,
            R.drawable.screen5, R.drawable.screen6, R.drawable.screen7, R.drawable.screen8};

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.image_switcher_activity);
        ButterKnife.bind(this);
        initSwitcher();
    }

    private void initSwitcher() {
        Animation slide_in_left = AnimationUtils.loadAnimation(this, android.R.anim.slide_in_left);
        Animation slide_out_right = AnimationUtils.loadAnimation(this, android.R.anim.slide_out_right);

        imageSwitcher.setInAnimation(slide_in_left);
        imageSwitcher.setOutAnimation(slide_out_right);
        /**
         * 通过setFactory可以给ViewSwitcher添加两个基本相同的子view
         */
        imageSwitcher.setFactory(() -> {
            ImageView imageView = new ImageView(ImageSwitcherActivity.this);
            imageView.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,
                    FrameLayout.LayoutParams.WRAP_CONTENT));
            imageView.setImageResource(images[0]);
            return imageView;
        });
    }

    @OnClick(R.id.btn_next)
    void switchView() {
        position++;
        if (position > 7) {
            position = 0;
        }
        imageSwitcher.setImageResource(images[position]);
    }
}


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

    <Button
        android:id="@+id/btn_next"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="下一个" />

    <ImageSwitcher
        android:id="@+id/image_switcher"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</LinearLayout>

4. TextSwitcher相关

TextSwitcher与ImageSwitcher基本相同,只是子view必须是TextView,然后有一个setText(CharSequence text)方法可以切换到下一个子view并设置文本内容。还有一点要注意的,从下面代码可以看出TextSwitcher限制更加严格,在添加子view的时候就必须是TextView,而ImageSwitcher只有在使用setImagexxx方法时才限制是ImageView,所以TextSwitcher不能当成普通的ViewSwitcher使用。

    @Override
    public void addView(View child, int index, ViewGroup.LayoutParams params) {
        if (!(child instanceof TextView)) {
            throw new IllegalArgumentException(
                    "TextSwitcher children must be instances of TextView");
        }

        super.addView(child, index, params);
    }

5. ViewFlipper相关

5.1 基本介绍

ViewFlipper继承了ViewAnimator,主要区别在于它添加了一些方法和属性可以实现自动循环播放的效果。而且ViewFlipper和AdapterViewFlipper基本相似,区别在于ViewFlipper通过addView(View v)添加数据,而AdapterViewFlipper是通过设置adapter来实现数据配置。

关键xml属性

  • flipInterval 自动播放的事件间隔
  • autoStart 是否自动播放

关键方法

  • setFlipInterval(int milliseconds) 设置自动播放的时间间隔
  • startFlipping() 开始自动播放
  • stopFlipping() 停止播放
  • isFlipping() 判断是否正在播放
  • setAutoStart(boolean autoStart) 设置是否自动播放
  • isAutoStart() 判断是否自动播放

5.2 代码示例

package com.xiayutian.widgettest;

import android.os.Bundle;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ViewFlipper;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;

public class ViewFlipperActivity extends AppCompatActivity {
    @BindView(R.id.view_flipper)
    ViewFlipper viewFlipper;
    @BindView(R.id.btn_pre)
    Button btnPre;
    @BindView(R.id.btn_next)
    Button btnNext;
    @BindView(R.id.btn_start_or_stop)
    Button btnStartOrStop;

    private int[] images = {R.drawable.screen1, R.drawable.screen2, R.drawable.screen3, R.drawable.screen4,
            R.drawable.screen5, R.drawable.screen6, R.drawable.screen7, R.drawable.screen8};

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.view_flipper_activity);
        ButterKnife.bind(this);
        initViewFlipper();
    }

    private void initViewFlipper() {
        Animation slide_in_left = AnimationUtils.loadAnimation(this, android.R.anim.slide_in_left);
        Animation slide_out_right = AnimationUtils.loadAnimation(this, android.R.anim.slide_out_right);

        viewFlipper.setInAnimation(slide_in_left);
        viewFlipper.setOutAnimation(slide_out_right);

        for (int resId : images) {
            ImageView imageView = new ImageView(ViewFlipperActivity.this);
            imageView.setScaleType(ImageView.ScaleType.FIT_XY);
            imageView.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,
                    FrameLayout.LayoutParams.MATCH_PARENT));
            imageView.setImageResource(resId);
            viewFlipper.addView(imageView);
        }
    }

    @OnClick(R.id.btn_pre)
    void pre() {
        viewFlipper.showPrevious();
    }

    @OnClick(R.id.btn_next)
    void next() {
        viewFlipper.showNext();
    }

    @OnClick(R.id.btn_start_or_stop)
    void auto() {
        if (viewFlipper.isFlipping()) {
            viewFlipper.stopFlipping();
        } else {
            viewFlipper.startFlipping();
        }
    }
}


<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ViewFlipper
        android:id="@+id/view_flipper"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:autoStart="true"
        android:flipInterval="2000"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

    <Button
        android:id="@+id/btn_pre"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="上一个"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

    <Button
        android:id="@+id/btn_next"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="下一个"
        app:layout_constraintBottom_toBottomOf="@+id/view_flipper"
        app:layout_constraintEnd_toEndOf="parent" />

    <Button
        android:id="@+id/btn_start_or_stop"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="开始/停止"
        app:layout_constraintBottom_toBottomOf="@+id/view_flipper"
        app:layout_constraintEnd_toStartOf="@+id/btn_next"
        app:layout_constraintStart_toEndOf="@+id/btn_pre" />

</androidx.constraintlayout.widget.ConstraintLayout>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值