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



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="&lt;" />
    <!-- 定义滚动到下一屏的按钮 -->
    <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


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值