您的位置:首页 > 移动开发 > Android开发

Android技术——视图切换(三)ViewAnimator及其子类

2015-03-18 11:34 399 查看
Android技术——视图切换(一)~(四)项目的源代码在:https://github.com/YongYuIT/MeiNv_Liulanqi

一、回顾帧布局(FrameLayout)
FrameLayout是最简单的布局管理器。FrameLayout只是简单地将子视图放置在布局的边界内,默认位置是左上角,可以通过gravity改变默认。添加多个子视图时,它会把新子视图堆积在前一个子视图的上面。

二、ViewAnimator是一个基类,它继承自FrameLayout,因此它具有FrameLayout的特性——可以将多个View组件“堆叠”在一起。另外,ViewAnimator还可以在View切换的时候表现出动画效果。

        ViewAnimator及其子类继承关系如下:



ViewAnimator及其子类的重要使命是增加动画效果,使界面更加酷炫。ViewAnimator有如下XML属性。



三、ViewSwitcher的使用

1、ViewSwitcher是视图切换组件。它继承自FrameLayout,所以可以将多个View层叠在一起,每次只显示一个组件,当程序控制从这些层叠的组件中的一个切换到另一个时,可以为ViewSwitcher指定切换的动画效果。

2、使用ViewSwitcher时,主要是如下两个要点:

       a、需要提供一个实现了ViewFactory(接口)的工厂类。在切换视图时,这个工厂类负责提供下一个视图实例。

       b、需要切换视图时。

             调用ViewSwitcher的setInAnimation和setOutAnimation分别设置新视图进入ViewSwitcher和就视图退出的动画效果。

             调用ViewSwitcher的getNextView方法即可获得下一个View的实例(其实就是ViewFactory通过makeView方法创建的那个实例),这时我们可以对这个实例进行操作。   

             调用ViewSwitcher的showNext或者showPrevious进行视图切换。

3、下面是使用ViewSwitcher进行视图切换的实例(基于前面两篇文章,《Android技术——视图切换(一)》和《Android技术——视图切换(二)》里面的项目添加而来):

/MeiNv_Liulanqi/src/com/example/meinv_liulanqi/ViewSwitcherActivity.java文件:

package com.example.meinv_liulanqi;

import com.example.meinv_liulanqi.R;

import android.app.Activity;

import android.os.Bundle;

import android.view.LayoutInflater;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

import android.widget.ImageView;

import android.widget.LinearLayout;

import android.widget.ViewSwitcher;

import android.widget.ViewSwitcher.ViewFactory;

public class ViewSwitcherActivity extends Activity

{

    private int          screenNo = -1;

    private int          screenNum;

    private ViewSwitcher switcher;

    private int[]        img_ids;

    @Override

    protected void onCreate(Bundle savedInstanceState)

    {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_view_switcher);

        img_ids = new int[] { R.drawable.linzhiling, R.drawable.liuyan,

                R.drawable.yangmi };

        screenNum = img_ids.length;

        // 为ViewSwitcher提供视图工厂

        switcher = (ViewSwitcher) findViewById(R.id.viewSwitcher);

        myViewFactory factory = new myViewFactory(this.getLayoutInflater());

        switcher.setFactory(factory);

        // 初始化

        getNext(switcher, img_ids);

        // 进行切换

        Button btn_next = (Button) findViewById(R.id.button_next);

        btn_next.setOnClickListener(new OnClickListener()

        {

            @Override

            public void onClick(View arg0)

            {

                getNext(switcher, img_ids);

            }

        });

        Button btn_prev = (Button) findViewById(R.id.button_prev);

        btn_prev.setOnClickListener(new OnClickListener()

        {

            @Override

            public void onClick(View arg0)

            {

                getPrev(switcher, img_ids);

            }

        });

    }

    private void getNext(ViewSwitcher _switcher, int[] _img_ids)

    {

        if (screenNo < screenNum - 1)

        {

            screenNo++;

            // 设置视图切换的动画效果

            _switcher.setInAnimation(ViewSwitcherActivity.this,

                    R.anim.slide_in_right);

            _switcher.setOutAnimation(ViewSwitcherActivity.this,

                    R.anim.slide_out_left);

            // 获取下一个视图的实例

            LinearLayout lil = (LinearLayout) _switcher.getNextView();

            ImageView img = (ImageView) lil.findViewById(R.id.img_meinv);

            img.setImageResource(_img_ids[screenNo]);

            // 切换视图

            _switcher.showNext();

        }

    }

    private void getPrev(ViewSwitcher _switcher, int[] _img_ids)

    {

        if (screenNo > 0)

        {

            screenNo--;

            // 设置视图切换的动画效果

            _switcher.setInAnimation(ViewSwitcherActivity.this,

                    R.anim.slide_in_lef);

            _switcher.setOutAnimation(ViewSwitcherActivity.this,

                    R.anim.slide_out_right);

            // 获取下一个视图的实例

            LinearLayout lil = (LinearLayout) _switcher.getNextView();

            ImageView img = (ImageView) lil.findViewById(R.id.img_meinv);

            img.setImageResource(_img_ids[screenNo]);

            // 切换视图

            _switcher.showPrevious();

        }

    }

    class myViewFactory implements ViewFactory

    {

        private LayoutInflater inflater;

        public myViewFactory(LayoutInflater inf)

        {

            inflater = inf;

        }

        @Override

        public View makeView()

        {

            // 提供下一个视图的实例

            return inflater.inflate(R.layout.fragment_layout, null);

        }

    }

}

/MeiNv_Liulanqi/res/layout/activity_view_switcher.xml文件:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="fill_parent"

    android:layout_height="fill_parent" >

    <!-- 定义一个ViewSwitcher组件 -->

    <ViewSwitcher

        android:id="@+id/viewSwitcher"

        android:layout_width="fill_parent"

        android:layout_height="fill_parent" />

    <!-- 定义滚动到上一屏的按钮 -->

    <Button

        android:id="@+id/button_prev"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_alignParentLeft="true"

        android:layout_centerVertical="true"

        android:background="#b0000000"

        android:text="<" />

    <!-- 定义滚动到下一屏的按钮 -->

    <Button

        android:id="@+id/button_next"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_alignParentRight="true"

        android:layout_centerVertical="true"

        android:background="#b0000000"

        android:text=">" />

</RelativeLayout>

/MeiNv_Liulanqi/res/layout/fragment_layout.xml文件:

<?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" >

    <ImageView

        android:id="@+id/img_meinv"

        android:layout_width="match_parent"

        android:layout_height="match_parent"

        android:scaleType="fitXY"

        android:src="@drawable/app_logo" />

</LinearLayout>

/MeiNv_Liulanqi/res/anim/slide_in_right.xml文件:

<?xml version="1.0" encoding="utf-8"?>

<set xmlns:android="http://schemas.android.com/apk/res/android" >

    <!-- 设置从右边拖进来的动画 android:duration指定动画持续时间 -->

    <!-- fromXDelta:动画起始时,X坐标上的位置;fromYDelta:动画起始时Y坐标上的位置 -->

    <!-- toXDelta:动画结束时,X坐标上的位置;toYDelta:动画结束时Y坐标上的位置 -->

    <!-- "100%":表示自身View的100%,即自身View的起始位置 -->

    <!-- "100%p":表示父层View的100% -->

    <!-- fromXDelta="100%p", toXDelta="0" 表示子View几何中心点从父View几何中心点左边一倍于父View长度处到父View几何中心点左边0倍于父View长度处(即到父子View几何中心点重合) -->

    <translate

        android:duration="@android:integer/config_mediumAnimTime"

        android:fromXDelta="100%p"

        android:toXDelta="0" />

</set>

/MeiNv_Liulanqi/res/anim/slide_in_lef.xml文件:

<?xml version="1.0" encoding="utf-8"?>

<set xmlns:android="http://schemas.android.com/apk/res/android" >

    <!--

    设置从左边拖出去的动画 

    android:duration指定动画持续时间

    -->

    <translate

        android:duration="@android:integer/config_mediumAnimTime"

        android:fromXDelta="-100%p"

        android:toXDelta="0" />

</set>

/MeiNv_Liulanqi/res/anim/slide_out_left.xml文件:

<?xml version="1.0" encoding="utf-8"?>

<set xmlns:android="http://schemas.android.com/apk/res/android" >

    <!-- 设置从左边拖出去的动画 android:duration指定动画持续时间 -->

    <translate

        android:duration="@android:integer/config_mediumAnimTime"

        android:fromXDelta="0"

        android:toXDelta="-100%p" />

</set>

/MeiNv_Liulanqi/res/anim/slide_out_right.xml文件:

<?xml version="1.0" encoding="utf-8"?>

<set xmlns:android="http://schemas.android.com/apk/res/android" >

    <!--

    设置从左边拖出去的动画 

    android:duration指定动画持续时间

    -->

    <translate

        android:duration="@android:integer/config_mediumAnimTime"

        android:fromXDelta="0"

        android:toXDelta="100%p" />

</set>

实现的效果:



美女切换中...

四、ImageSwatcher和TextSwatcher的用法

1、ImageSwatcher继承自ViewSwitcher因此它具有ViewSwitcher的相同能力:切换View组件时使用动画效果。

      ImageSwatcher重写了showNext和showPrevious方法,因此使用起来比ViewSwitcher更加简单,主需要两步:

      a、提供ViewFactory,注意这个ViewFactory的makeView方法生成的View实例只能是ImageView及其子类的实例。

      b、需要切换图片时,只需要调用ImageSwatcher的setImageDrawable或者setImageResources或者setImageURL方法即可实现切换图片。(原理其实就是将

            setImageDrawable或者setImageResources或者setImageURL提供的图片资源赋值给ViewFactory创建的新ImageView,然后切换View而已。只是在ViewSwitcher中

            这些动作要自己写代码完成,而ImageSwatcher已经封装了这些代码使之自动完成而已)

2、TextSwatcher与ImageSwatcher完全是类似的。

       也需要提供一个ViewFactory。类似地,这个ViewFactory的makeView方法生成的View实例只能是TextView及其子类的实例。

       需要切换View时,只需要调用TextSwatcher的setText方法即可。

五、ViewFlipper的用法

        ViewFlipper实现的效果与ViewSwatcher类似,但是却不如ViewSwatcher灵活,自然使用上也比ViewSwatcher简单。通过ViewFlipper的addView(或者直接在xml嵌套定义)可以向ViewFlipper添加几个View。然后就可以通过调用ViewFlipper的showPrevious和showNext实现在这些View的切换。当然,在执行切换动作前可以通过ViewFlipper的setInAnimation和setOutAnimation设置切换的动画效果。

       ViewFlipper 唯一一点比ViewSwatcher增强的地方是,ViewFlipper可以调用startFlipping函数实现多个View(就是通过ViewFlipper的addView或者直接在xml嵌套定义添加进来的那几个View)自动循环切换(通过stopFlipping停止)。当然,在执行startFlipping前,通常需要通过ViewFlipper的setInAnimation和setOutAnimation设置切换的动画效果。

Android技术——视图切换(一)~(四)项目的源代码在:https://github.com/YongYuIT/MeiNv_Liulanqi
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android
相关文章推荐