Androi UI 详解之ViewAnimator(ViewSwitcher,ImageSwitcher,TextSwitcher,ViewFlipper)

                                                       ViewAnimator


一、ViewAnimator 是一个基类,他继承了FrameLayout

        他可以将多个View组建叠加在一起,ViewAnimator新增加的功能正如他的名字所暗示的,可以在切换时表现动画效果,

        ViewAniamtor的继承关系

        --FrameLayout 

           --ViewAnimator

                 --ViewSwitcher

                              --imageSwitcher

                              --TextSwitcher

                 --ViewFlipper

                       viewAnimator 支持的常见XML属性

       android:animateFirstView          设置ViewAnimator 显示第一个View组建时是否使动画

       android:inAnimation              设置ViewAnimator 显示组件时使用的动画

  android:outAnimation            设置ViewAnimator隐藏组件时的使用的动画(这里隐藏是什么意思,隐藏的图片去哪里了,应该还在吧,那这样隐藏多个会不会出现性能下降?)

ViewSwitcher的功能与用法

     ViewSwitcher 代表了视图切换组件,它本身继承了FrameLayout,因此可以将多个View层叠在一起,每次只显示一个组件。当程序控制从一个

View 切换到另一个View 时,ViewSwitcher 支持指定动画效果。

下面看一个例子

Java代码

package org.crazyit.ui;

import java.util.ArrayList;

import android.os.Bundle;
import android.app.Activity;
import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.ViewSwitcher;
import android.widget.ViewSwitcher.ViewFactory;


public class ViewSwitcherTest extends Activity
{
	// 定义一个常量,用于显示每屏显示的应用程序数
	public static final int NUMBER_PER_SCREEN = 12;

	// 代表应用程序的内部类,
	public static class DataItem
	{
		// 应用程序名称
		public String dataName;
		// 应用程序图标
		public Drawable drawable;
	}

	// 保存系统所有应用程序的List集合
	private ArrayList<DataItem> items = new ArrayList<DataItem>();
	// 记录当前正在显示第几屏的程序
	private int screenNo = -1;
	// 保存程序所占的总屏数
	private int screenCount;
	ViewSwitcher switcher;
	// 创建LayoutInflater对象
	LayoutInflater inflater;

	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		inflater = LayoutInflater.from(ViewSwitcherTest.this);
		// 创建一个包含40个元素的List集合,用于模拟包含40个应用程序
		for (int i = 0; i < 40; i++)
		{
			String label = "" + i;
			Drawable drawable = getResources().getDrawable(
					R.drawable.ic_launcher);
			DataItem item = new DataItem();
			item.dataName = label;
			item.drawable = drawable;
			items.add(item);
		}
		// 计算应用程序所占的总屏数。
		// 如果应用程序的数量能整除NUMBER_PER_SCREEN,除法的结果就是总屏数。
		// 如果不能整除,总屏数应该是除法的结果再加1。
		screenCount = items.size() % NUMBER_PER_SCREEN == 0 ? 
				items.size()/ NUMBER_PER_SCREEN :
				items.size() / NUMBER_PER_SCREEN	+ 1;
		switcher = (ViewSwitcher) findViewById(R.id.viewSwitcher);
		switcher.setFactory(new ViewFactory()
		{
			// 实际上就是返回一个GridView组件
			@Override
			public View makeView()
			{
				// 加载R.layout.slidelistview组件,实际上就是一个GridView组件。
				return inflater.inflate(R.layout.slidelistview, null);
			}
		});
		// 页面加载时先显示第一屏。
		next(null);
	}

	public void next(View v)
	{
		if (screenNo < screenCount - 1)
		{
			screenNo++;
			// 为ViewSwitcher的组件显示过程设置动画
			switcher.setInAnimation(this, R.anim.slide_in_right);
			// 为ViewSwitcher的组件隐藏过程设置动画
			switcher.setOutAnimation(this, R.anim.slide_out_left);
			// 控制下一屏将要显示的GridView对应的 Adapter
			((GridView) switcher.getNextView()).setAdapter(adapter);
			// 点击右边按钮,显示下一屏,
			// 学习手势检测后,也可通过手势检测实现显示下一屏.
			switcher.showNext();  // ①
		}
	}

	public void prev(View v)
	{
		if (screenNo > 0)
		{
			screenNo--;
			// 为ViewSwitcher的组件显示过程设置动画
			switcher.setInAnimation(this, android.R.anim.slide_in_left);
			// 为ViewSwitcher的组件隐藏过程设置动画
			switcher.setOutAnimation(this, android.R.anim.slide_out_right);
			// 控制下一屏将要显示的GridView对应的 Adapter
			((GridView) switcher.getNextView()).setAdapter(adapter);
			// 点击左边按钮,显示上一屏,当然可以采用手势
			// 学习手势检测后,也可通过手势检测实现显示上一屏.
			switcher.showPrevious();   // ②
		}
	}

	// 该BaseAdapter负责为每屏显示的GridView提供列表项
	private BaseAdapter adapter = new BaseAdapter()
	{
		@Override
		public int getCount()
		{
			// 如果已经到了最后一屏,且应用程序的数量不能整除NUMBER_PER_SCREEN
			if (screenNo == screenCount - 1
					&& items.size() % NUMBER_PER_SCREEN != 0)
			{
				// 最后一屏显示的程序数为应用程序的数量对NUMBER_PER_SCREEN求余
				return items.size() % NUMBER_PER_SCREEN;
			}
			// 否则每屏显示的程序数量为NUMBER_PER_SCREEN
			return NUMBER_PER_SCREEN;
		}

		@Override
		public DataItem getItem(int position)
		{
			// 根据screenNo计算第position个列表项的数据
			return items.get(screenNo * NUMBER_PER_SCREEN + position);
		}

		@Override
		public long getItemId(int position)
		{
			return position;
		}

		@Override
		public View getView(int position
				, View convertView, ViewGroup parent)
		{
			View view = convertView;
			if (convertView == null)
			{
				// 加载R.layout.labelicon布局文件
				view = inflater.inflate(R.layout.labelicon, null);
			}
			// 获取R.layout.labelicon布局文件中的ImageView组件,并为之设置图标
			ImageView imageView = (ImageView)
					view.findViewById(R.id.imageview);
			imageView.setImageDrawable(getItem(position).drawable);
			// 获取R.layout.labelicon布局文件中的TextView组件,并为之设置文本
			TextView textView = (TextView) 
					view.findViewById(R.id.textview);
			textView.setText(getItem(position).dataName);
			return view;
		}
	};
}
main.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_alignParentBottom="true"
		android:layout_alignParentLeft="true"
		android:onClick="prev"
		android:text="<" />
	<!-- 定义滚动到下一屏的按钮 -->
	<Button
		android:id="@+id/button_next"
		android:layout_width="wrap_content"
		android:layout_height="wrap_content"
		android:layout_alignParentBottom="true"
		android:layout_alignParentRight="true"
		android:onClick="next"
		android:text=">" />
</RelativeLayout>
slidelistview.xml

<?xml version="1.0" encoding="utf-8"?>
<GridView
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:numColumns="4"
  android:layout_height="match_parent">
    
</GridView>
lablicon.xml
<?xml version="1.0" encoding="utf-8"?>
<!-- 定义一个垂直的LinearLayout,该容器中放置一个ImageView和一个TextView -->
<LinearLayout
	xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="vertical"
	android:layout_width="match_parent"
	android:layout_height="match_parent"
	android:gravity="center">
	<ImageView
	    android:id="@+id/imageview"
		android:layout_width="wrap_content"
		android:layout_height="wrap_content"
		 />
	<TextView
	    android:id="@+id/textview"
		android:layout_width="wrap_content"
		android:layout_height="wrap_content"
		android:gravity="center"
		 />	
</LinearLayout>

动画效果xml,将其放在resource下新建的文件夹anim 然后在程序中可以通过R.anim.文件名访问

slide_in_right.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 设置从右边拖进来的动画
    android:duration指定动画持续时间  -->
	<translate
		android:fromXDelta="100%p"
		android:toXDelta="0"
		android:duration="@android:integer/config_mediumAnimTime" />
</set>
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:fromXDelta="0"
		android:toXDelta="-100%p"
		android:duration="@android:integer/config_mediumAnimTime" />
</set>



这里重点就是ViewSwitcher设置的ViewFactory对象,当程序点击下一个时,viewswitcher会调用showNext()显示下一页,而每次动画效果由setInAnimation()和setOutAnimation()设定。


二、图片切换器的功能与用法(ImageSwitcher

        1.ImageSwitcher 继承了ViewAnimator ,并且重写了shownext()和showPrevious(),因此使用ImageSwitcher更加简单,只需要两个步骤

       ①为ImageSwitcher 提供一个ViewFacotory,该ViewFactory生成的View组件必须是ImageView,(上面的则没有限制是什么View)

       ②需要切换图片时只需要调用ImageSwitcher的setImageDrawable(Drawable drawable),setImageResource(int resid)和setImageURI(URI uri) 方法更换图片


     注意:ImageSwitcher和ImageView 功能上是一样的用来显示图片,但是ImageSwitcher比ImageView效果更炫。


下面是一个支持动画的图片浏览器


package org.crazyit.ui;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ViewSwitcher.ViewFactory;
import android.widget.GridView;
import android.widget.ImageSwitcher;
import android.widget.ImageView;
import android.widget.SimpleAdapter;


public class ImageSwitcherTest extends Activity
{
	int[] imageIds = new int[]
	{
		R.drawable.bomb5 , R.drawable.bomb6 , R.drawable.bomb7 
		, R.drawable.bomb8 , R.drawable.bomb9 , R.drawable.bomb10
		, R.drawable.bomb11 , R.drawable.bomb12	, R.drawable.bomb13
		, R.drawable.bomb14 , R.drawable.bomb15 , R.drawable.bomb16
	};
	ImageSwitcher switcher;
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		// 创建一个List对象,List对象的元素是Map
		List<Map<String, Object>> listItems = 
				new ArrayList<Map<String, Object>>();
		for (int i = 0; i < imageIds.length; i++)
		{
			Map<String, Object> listItem = new HashMap<String, Object>();
			listItem.put("image", imageIds[i]);
			listItems.add(listItem);
		}
		// 获取显示图片的ImageSwitcher
		switcher = (ImageSwitcher)
				findViewById(R.id.switcher);
		// 为ImageSwitcher设置图片切换的动画效果
		switcher.setFactory(new ViewFactory()
		{
			@Override
			public View makeView()
			{
				// 创建ImageView对象
				ImageView imageView = new ImageView(ImageSwitcherTest.this);
				imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
				imageView.setLayoutParams(new ImageSwitcher.LayoutParams(
					LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
				// 返回ImageView对象
				return imageView;
			}
		});
		// 创建一个SimpleAdapter
		SimpleAdapter simpleAdapter = new SimpleAdapter(this,
			listItems
			// 使用/layout/cell.xml文件作为界面布局
			, R.layout.cell, new String[]{"image"},
			new int[] { R.id.image1 });
		GridView grid = (GridView) findViewById(R.id.grid01);
		// 为GridView设置Adapter
		grid.setAdapter(simpleAdapter);
		// 添加列表项被选中的监听器
		grid.setOnItemSelectedListener(new OnItemSelectedListener()
		{
			@Override
			public void onItemSelected(AdapterView<?> parent, View view,
					int position, long id)
			{
				// 显示当前被选中的图片
				switcher.setImageResource(imageIds[position]);
			}

			@Override
			public void onNothingSelected(AdapterView<?> parent)
			{
			}
		});
		// 添加列表项被单击的监听器
		grid.setOnItemClickListener(new OnItemClickListener()
		{
			@Override
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id)
			{
				// 显示被单击的图片的图片
				switcher.setImageResource(imageIds[position]);
			}
		});
	}
}

main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="vertical"
	android:layout_width="fill_parent"
	android:layout_height="fill_parent"
	android:gravity="center_horizontal"
	>
<!-- 定义一个GridView组件 -->
<GridView  
	android:id="@+id/grid01"
	android:layout_width="fill_parent" 
	android:layout_height="wrap_content" 
	android:horizontalSpacing="pt"
	android:verticalSpacing="2pt"
	android:numColumns="4"
	android:gravity="center"
	/>
<!-- 定义一个ImageSwitcher组件 -->
<ImageSwitcher android:id="@+id/switcher"
	android:layout_width="300dp"
	android:layout_height="300dp"
	android:layout_gravity="center_horizontal"
	android:inAnimation="@android:anim/fade_in"
	android:outAnimation="@android:anim/fade_out"
	/>	
</LinearLayout>

cell.xml

<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="horizontal"
	android:layout_width="fill_parent"
	android:layout_height="fill_parent"
	android:gravity="center_horizontal"
	android:padding="4pt"
	>
<ImageView
	android:id="@+id/image1"
	android:layout_width="50dp" 
	android:layout_height="50dp" 
	/>	
</LinearLayout>

三、

      TextView也是继承ViewSwitcher ,因此也具有它的动画特性,但是他的ViewFactory中的makeView() 返回的是TextView


下面看一个例子,文本切换器

<?xml version="1.0" encoding="utf-8" ?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	xmlns:tools="http://schemas.android.com/tools"
	android:layout_width="match_parent"
	android:layout_height="match_parent" >
<!-- 定义一个TextSwitcher,并指定了文本切换时的动画效果 -->
<TextSwitcher
    android:id="@+id/textSwitcher"
	android:layout_width="match_parent"
	android:layout_height="wrap_content"
	android:inAnimation="@android:anim/slide_in_left"
	android:outAnimation="@android:anim/slide_out_right"
	android:onClick="next"
/>
</LinearLayout>

java代码

package org.crazyit.ui;

import android.os.Bundle;
import android.view.View;
import android.widget.TextSwitcher;
import android.widget.TextView;
import android.widget.ViewSwitcher;
import android.app.Activity;
import android.graphics.Color;


public class TextSwitcherTest extends Activity
{
	TextSwitcher textSwitcher;
	String[] strs = new String[]
		{
			"疯狂Java讲义",
			"轻量级Java EE企业应用实战",
			"疯狂Android讲义",
			"疯狂Ajax讲义"
		};
	int curStr;
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		textSwitcher = (TextSwitcher) findViewById(R.id.textSwitcher);
		textSwitcher.setFactory(new ViewSwitcher.ViewFactory()
		{
			public View makeView()
			{
				TextView tv = new TextView(TextSwitcherTest.this);
				tv.setTextSize(40);
				tv.setTextColor(Color.MAGENTA);
				return tv;
			}
		});
		// 调用next方法显示下一个字符串
		next(null);
	}
	// 事件处理函数,控制显示下一个字符串
	public void next(View source)
	{
		textSwitcher.setText(strs[curStr++ % strs.length]);  //①
	}
}

四、ViewFlipper的功能和用法


ViewFliper组件继承了ViewAnimator,他可调用addView(View v) 添加多个组件,一旦向ViewFlipper,添加了多个组件之后,ViewFlipper 就可以使用动画控制个组件的切换效果,

     ViewFliper与前面接受啊的AdapterViewFlipper有较大的相似,他们可以控制组件切换效果,他们的区别是ViewFlipper需要开发者通过addView()添加多个View,而AdapterViewFlipper则只要传入一个Adapter,Adapter将会负责提供多个View。因此ViewFlipper可以指定与AdapterViewFlipper相同的xml


自动播放的图片库

package org.crazyit.ui;

import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.widget.ViewFlipper;


public class ViewFlipperTest extends Activity
{
	private ViewFlipper viewFlipper;

	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		viewFlipper = (ViewFlipper) findViewById(R.id.details);
	}

	public void prev(View source)
	{
		viewFlipper.setInAnimation(this, R.anim.slide_in_right);
		viewFlipper.setOutAnimation(this, R.anim.slide_out_left);
		// 显示上一个组件
		viewFlipper.showPrevious();
		// 停止自动播放
		viewFlipper.stopFlipping();
	}

	public void next(View source)
	{
		viewFlipper.setInAnimation(this, android.R.anim.slide_in_left);
		viewFlipper.setOutAnimation(this, android.R.anim.slide_out_right);
		// 显示下一个组件。
		viewFlipper.showNext();
		// 停止自动播放
		viewFlipper.stopFlipping();
	}

	public void auto(View source)
	{
		viewFlipper.setInAnimation(this, android.R.anim.slide_in_left);
		viewFlipper.setOutAnimation(this, android.R.anim.slide_out_right);
		// 开始自动播放
		viewFlipper.startFlipping();
	}
}

xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
	xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="vertical"
	android:layout_width="match_parent"
	android:layout_height="match_parent">
	<ViewFlipper
		android:id="@+id/details"
		android:layout_width="match_parent"
		android:layout_height="match_parent"
		android:persistentDrawingCache="animation"
		android:flipInterval="1000">
		<ImageView
			android:src="@drawable/java"
			android:layout_width="fill_parent"
			android:layout_height="wrap_content">
		</ImageView>
		<ImageView
			android:src="@drawable/android"
			android:layout_width="fill_parent"
			android:layout_height="wrap_content">
		</ImageView>
		<ImageView
			android:src="@drawable/ee"
			android:layout_width="fill_parent"
			android:layout_height="wrap_content">
		</ImageView>
	</ViewFlipper>
	<Button
		android:text="<"
		android:onClick="prev"
		android:layout_width="wrap_content"
		android:layout_height="wrap_content"
		android:layout_alignParentBottom="true"
		android:layout_alignParentLeft="true" />
	<Button
		android:layout_width="wrap_content"
		android:layout_height="wrap_content"
		android:layout_alignParentBottom="true"
		android:layout_centerInParent="true"
		android:onClick="auto"
		android:text="自动播放" />
	<Button
		android:text=">"
		android:onClick="next"
		android:layout_width="wrap_content"
		android:layout_height="wrap_content"
		android:layout_alignParentBottom="true"
		android:layout_alignParentRight="true" />
</RelativeLayout>


上面代码实现非常简单一个是定义这个组件都不需要我们设置他的setFactory,直接获取组件,设置显示和隐藏的动画,然后电泳shownext或showPrevious,startFlipping()开始自动播放,stopFlipping停止自动播放





  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ViewFlipperViewSwitcher的使用:屏幕切换指的是在同一个Activity内屏幕见的切换,最长见的情况就是在一个FrameLayout内有多个页面,比如一个系统设置页面;一个个性化设置页面。 通过查看OPhone API文档可以发现,有个android.widget.ViewAnimator类继承至FrameLayout,ViewAnimator类的作用是为FrameLayout里面的View切换提供动画效果。该类有如下几个和动画相关的函数: l setInAnimation:设置View进入屏幕时候使用的动画,该函数有两个版本,一个接受单个参数,类型为android.view.animation.Animation;一个接受两个参数,类型为Context和int,分别为Context对象和定义Animation的resourceID。 setOutAnimation: 设置View退出屏幕时候使用的动画,参数setInAnimation函数一样。 showNext: 调用该函数来显示FrameLayout里面的下一个View。 showPrevious:调用该函数来显示FrameLayout里面的上一个View。 一般不直接使用ViewAnimator而是使用它的两个子类ViewFlipperViewSwitcherViewFlipper可以用来指定FrameLayout内多个View之间的切换效果,可以一次指定也可以每次切换的时候都指定单独的效果。该类额外提供了如下几个函数: isFlipping: 用来判断View切换是否正在进行 setFilpInterval:设置View之间切换的时间间隔 startFlipping:使用上面设置的时间间隔来开始切换所有的View,切换会循环进行 stopFlipping: 停止View切换 ViewSwitcher 顾名思义Switcher特指在两个View之间切换。可以通过该类指定一个ViewSwitcher.ViewFactory 工程类来创建这两个View。该类也具有两个子类ImageSwitcherTextSwitcher分别用于图片和文本切换。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值