您的位置:首页 > 产品设计 > UI/UE

UI组件:ViewAnimator及其子类

2016-11-13 11:02 316 查看
ViewAnimator是一个基类,它继承了FrameLayout,因此它也可以将多个View组件“叠”在一起。

ViewAnimator有以下两个子类:ViewSwitcher和ViewFlipper。

ViewSwitcher的功能和用法

ViewSwitcher是视图切换组件,当程序从一个View切换到另一个View时,ViewSwitcher支持指定动画效果。

为了给ViewSwitcher添加多个组件,一般通过调用ViewSwitcher的setFactory(ViewSwitcher.ViewFactory)方法为其设置ViewFactory,并由该ViewFactory为之创建View即可。

下面的实例通过ViewSwitcher来实现Android的分屏、左右滚动效果。

创建一个DataItem类:

public class DataItem {
private String dataName;
private int drawable;

public String getDataName() {
return dataName;
}

public void setDataName(String dataName) {
this.dataName = dataName;
}

public int getDrawable() {
return drawable;
}

public void setDrawable(int drawable) {
this.drawable = drawable;
}
}


布局文件代码:

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

<ViewSwitcher
android:id="@+id/view_switcher"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<ImageView
android:id="@+id/prev"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/view_switcher"
android:layout_alignParentLeft="true"
android:src="@drawable/prev"/>
<ImageView
android:id="@+id/next"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/view_switcher"
android:layout_alignParentRight="true"
android:src="@drawable/next"/>
</RelativeLayout>


主程序代码如下所示:

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

//定义一个常量,用于显示每屏显示的应用的程序数
private static final int NUMBER_PER_SCREEN = 12;
private ViewSwitcher viewSwitcher;
//创建LayoutInflater对象
private LayoutInflater inflater;
//记录当前正在显示第几屏的程序
private int screenNo = -1;
//保存程序所占的总屏数
private int screenCount;
private ArrayList<DataItem> items = new ArrayList<>();

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
inflater = LayoutInflater.from(MainActivity.this);
for (int i = 0; i < 40; i++) { //创建一个包含40个元素的List集合,用来模拟包含40个应用程序
DataItem dataItem = new DataItem();
dataItem.setDataName(""+i);
dataItem.setDrawable(R.drawable.bomb);
items.add(dataItem);
}
//计算应用程序所占的总屏数
screenCount = items.size()%NUMBER_PER_SCREEN==0?items.size()/NUMBER_PER_SCREEN : items.size()/NUMBER_PER_SCREEN+1;
viewSwitcher.setFactory(new ViewSwitcher.ViewFactory() {
//实际上返回一个GridView组件
@Override
public View makeView() {
//加载R.layout.slide_list_view组件,实际上就是一个GridView组件
return inflater.inflate(R.layout.slide_list_view,null);
}
});
//页面加载时先显示第一屏
next();
}

private void initView() {
ImageView prev = (ImageView) findViewById(R.id.prev);
ImageView next = (ImageView) findViewById(R.id.next);
viewSwitcher = (ViewSwitcher) findViewById(R.id.view_switcher);
prev.setOnClickListener(this);
next.setOnClickListener(this);
}

@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.prev:
prev();
break;
case R.id.next:
next();
break;
default:
break;
}
}

/**
* 切换到下一屏
*/
private void next() {
if (screenNo<screenCount-1){
screenNo++;
//位ViewSwitcher设置显示过程的动画
viewSwitcher.setInAnimation(this,R.anim.slide_in_right);
//位ViewSwitcher设置隐藏过程的动画
viewSwitcher.setOutAnimation(this,R.anim.slide_out_left);
((GridView)(viewSwitcher.getNextView())).setAdapter(adapter);
//显示下一屏
viewSwitcher.showNext();
}
}

/**
* 切换到上一屏
*/
private void prev() {
if (screenNo>0){
screenNo--;
//位ViewSwitcher设置显示过程的动画
viewSwitcher.setInAnimation(this,R.anim.slide_in_left);
//位ViewSwitcher设置隐藏过程的动画
viewSwitcher.setOutAnimation(this,R.anim.slide_out_right);
((GridView)(viewSwitcher.getNextView())).setAdapter(adapter);
//显示上一屏
viewSwitcher.showPrevious();
}
}
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;
}
return NUMBER_PER_SCREEN;
}

@Override
public DataItem getItem(int 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;
ViewHolder viewHolder=new ViewHolder();
if(convertView==null)
{
view=LayoutInflater.from(MainActivity.this).inflate(R.layout.labelicon,null);
viewHolder.imageView=(ImageView)view.findViewById(R.id.imageview);
viewHolder.textView=(TextView)view.findViewById(R.id.textview);
view.setTag(viewHolder);
}
else{
view=convertView;
viewHolder=(ViewHolder)view.getTag();
}
DataItem dataItem = getItem(position);
viewHolder.imageView.setImageResource(dataItem.getDrawable());
viewHolder.textView.setText(dataItem.getDataName());
Log.d("pyh", "getView: "+screenNo);
return view;
}
class ViewHolder{
ImageView imageView;
TextView textView;
}
};
}


其中R.layout.labelicon对应的代码如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/imageview"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"/>
</LinearLayout>


R.anim.slide_in_left文件对应的代码如下:

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


R.anim.slide.slide_in_right文件对应的代码如下:

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


R.anim.slide_out_left文件对应的代码如下:

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


R.anim.slide_out_right文件对应的代码如下:

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


效果图如下:



图像切换器(ImageSwitcher)的功能和用法

ImageSwitcher继承了ViewSwitcher,可以在切换View组件时使用动画。

使用ImageSwitcher只需要以下两步即可:

(1)为ImageSwitcher提供一个ViewFactory,该ViewFactory生成的View组件必须是ImageView。

(2)需要切换图片时,只要调用ImageSwitcher的setImageDrawable(Drawable drawable)、setImageResource(int resid)和setImageURI(Uri uri)方法切换图片即可。

下面通过一个实例介绍ImageSwitcher的用法。

布局文件如下所示:

<?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">
<GridView
android:id="@+id/grid"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:horizontalSpacing="3dp"
android:verticalSpacing="3dp"
android:numColumns="4"
android:gravity="center"/>
<ImageSwitcher
android:id="@+id/image_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>


通过android:inAnimation和android:outAnimation指定图片切换时的动态效果。

主程序代码如下所示:

public class ImageSwitcherActivity extends AppCompatActivity {

private 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
};
private ImageSwitcher imageSwitcher;
private GridView gridView;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_image_switcher);
imageSwitcher = (ImageSwitcher) findViewById(R.id.image_switcher);
gridView = (GridView) findViewById(R.id.grid);
List<Map<String,Object>> listItems = new ArrayList<>();
for (int i = 0; i < imageIds.length; i++) {
Map<String,Object> item = new ArrayMap<>();
item.put("image",imageIds[i]);
listItems.add(item);
}
SimpleAdapter adapter = new SimpleAdapter(this,listItems,R.layout.ceil,new String[]{"image"},new int[]{R.id.image});
imageSwitcher.setFactory(new ViewSwitcher.ViewFactory() {
@Override
public View makeView() {
ImageView imageView = new ImageView(ImageSwitcherActivity.this);
imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
imageView.setLayoutParams(new ImageSwitcher.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
return imageView;
}
});
gridView.setAdapter(adapter);
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//显示被选中的图片
imageSwitcher.setImageResource(imageIds[position]);
}
});
}
}


R.layout.ceil文件对应的代码如下所示:

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


效果如下所示:



图片切换时会使用动态效果。

文本切换器(TextSwitcher)的功能和用法

TextSwitcher继承了ViewSwitcher,在切换View的时候也能使用动画

TextSwitcher与TextView的区别在于,TextSwitcher可以指定文本切换时的动态效果。

布局文件如下:

<?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">
<TextSwitcher
android:id="@+id/text_switcher"
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>


主程序代码如下:

package com.example.administrator.viewanimatorinfo;

import android.graphics.Color;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextSwitcher;
import android.widget.TextView;
import android.widget.ViewSwitcher;

public class TextSwitcherActivity extends AppCompatActivity {

private TextSwitcher textSwitcher;
private String[] strs = new String[]{"疯狂Android讲义","疯狂Java讲义","疯狂Ajax讲义"};
private int curStr=0;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_text_switcher);
textSwitcher = (TextSwitcher) findViewById(R.id.text_switcher);
textSwitcher.setFactory(new ViewSwitcher.ViewFactory() {
@Override
public View makeView() {
TextView textView = new TextView(TextSwitcherActivity.this);
textView.setTextSize(17);
textView.setTextColor(Color.MAGENTA);
return textView;
}
});
//调用next()方法显示下一条字符串
next(null);
}

/**
* 事件处理方法
* @param view
*/
public void next(View view){
textSwitcher.setText(strs[curStr++%strs.length]);
}
}


效果图如下:



当点击文字时,文本切换使用动态效果。

ViewFlipper的功能和用法

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

下面的实例实现了自动播放的图片库。

布局文件代码如下所示:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ViewFlipper
android:id="@+id/details"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:flipInterval="3000">
<ImageView
android:src="@drawable/android"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<ImageView
android:src="@drawable/java"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<ImageView
android:src="@drawable/ee"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</ViewFlipper>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:onClick="prev"
android:text="上一个"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:onClick="auto"
android:text="自动播放"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:onClick="next"
android:text="下一个"/>
</RelativeLayout>


主程序代码如下所示:

public class ViewFlipperActivity extends AppCompatActivity {

private ViewFlipper viewFlipper;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_flipper);
viewFlipper = (ViewFlipper) findViewById(R.id.details);
}
public void next(View v){
//设置拖进、拖出动态效果
viewFlipper.setInAnimation(ViewFlipperActivity.this,R.anim.slide_in_right);
viewFlipper.setOutAnimation(ViewFlipperActivity.this,R.anim.slide_out_left);
//显示下一个组件
viewFlipper.showNext();
//停止自动播放
viewFlipper.stopFlipping();
}
public void prev(View v){
//设置拖进、拖出动态效果
viewFlipper.setInAnimation(ViewFlipperActivity.this,R.anim.slide_in_left);
viewFlipper.setOutAnimation(ViewFlipperActivity.this,R.anim.slide_out_right);
//显示下一个组件
viewFlipper.showPrevious();
//停止自动播放
viewFlipper.stopFlipping();
}
public void auto(View v){
//设置拖进、拖出动态效果
viewFlipper.setInAnimation(ViewFlipperActivity.this,R.anim.slide_in_right);
viewFlipper.setOutAnimation(ViewFlipperActivity.this,R.anim.slide_out_left);
//开始自动播放
viewFlipper.startFlipping();
}
}


R.anim.slide_in_right、R.anim.slide_in_left、R.anim.slide_out_right、R.anim.slide_out_left文件与“ViewSwitcher的功能和用法”处对应的文件代码相同。

效果图如下所示:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: