1. 使用TextSwitcher和ImageSwitcher
当我们需要改变界面上某一处文字时,通常使用TextView.setText()方法来实现,瞬间即完成。而TextSwitcher可以让我们在改变文字时添加一个退出和一个进入动画。TextSwitcher实现步骤如下:
1. 通过findViewById()初始化TextSwitcher控件2. 通过switcher.setFactory()创建一个构造器,在这里添加textview3. 添加文字进入动画 switcher.setInAnimation();3. 添加文字退出动画 switcher.setOutAnimation();
具体实现代码如下:
public class MainActivity extends AppCompatActivity {
private TextSwitcher mTextSwitcher;
private String[] StringArray={"First","Second","Third"};
private Button button;//点击按钮显示下一个词
private int currentPosition=0;//记录当前显示的词
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//初始化按钮
button=(Button)findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onSwitchText();
}
});
//初始化TextSwitcher
mTextSwitcher=(TextSwitcher)findViewById(R.id.text_switcher);
mTextSwitcher.setFactory(new ViewSwitcher.ViewFactory() {
@Override
public View makeView() {
TextView t = new TextView(MainActivity.this);
t.setGravity(Gravity.CENTER);
t.setTextSize(24);
return t;
}
});
mTextSwitcher.setInAnimation(this,android.R.anim.slide_in_left);
mTextSwitcher.setOutAnimation(this,android.R.anim.slide_out_right);
onSwitchText();
}
public void onSwitchText() {
mTextSwitcher.setText(StringArray[currentPosition]);
currentPosition++;
if(currentPosition==StringArray.length){
currentPosition=0;
}
}
}
ImageSwitcher和TextSwitcher实现方法类似,可以实现类似于图片滚动显示的效果。
2. 为ViewGroup的子View添加漂亮效果
默认情况下,View被加载到ViewGroup中的过程是瞬间完成的。然而我们也可以使用LayoutAnimationController为这个加载过程添加动画效果。
实现代码如下:
public class MainActivity extends ListActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getListView().setLayoutAnimation(
new LayoutAnimationController(AnimationUtils.loadAnimation(
this, R.anim.list_animation), 0.5f));
setListAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, Countries.COUNTRIES));
}
}
R.anim.list_animation文件
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<alpha
android:duration="50"
android:fromAlpha="0"
android:toAlpha="1" />
<translate
android:duration="100"
android:fromYDelta="-100%"
android:toYDelta="0%" />
</set>
这里动画效果写在xml文件中,也可以通过java代码实现:
mListView = (ListView) findViewById(R.id.my_listview_id);
AnimationSet set = new AnimationSet(true); //动画集,可以添加多个动画
Animation animation = new AlphaAnimation(0.0f, 1.0f);//透明动画
animation.setDuration(50);
set.addAnimation(animation);
animation = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.0f,
Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF,
-1.0f, Animation.RELATIVE_TO_SELF, 0.0f);//平移动画
animation.setDuration(100); animation.
set.addAnimation(animation);
LayoutAnimationController controller = new LayoutAnimationController(set, 0.5f);//第二个参数指定两个动画之间的间隔时间
mListView.setLayoutAnimation(controller);
平移动画的参数介绍:
public TranslateAnimation(int fromXType, float fromXValue, int toXType,float toXValue, int fromYType, float fromYValue, int toYType,float toYValue) {}
其中Type有三种:
Animation.ABSOLUTE 绝对位置
Animation.RELATIVE_TO_SELF 相对自身位置
Animation.RELATIVE_TO_PARENT 相对父控件位置
3.使用Canvas绘制动画
用Android官方api绘制动画时,可能会有某些局限。使用Canvas类提供的功能,我们能够直接在屏幕上绘制图形或动画。
下面的例子将 绘制一个正方形小方块,让它在屏幕上自行移动,当它移动到屏幕边缘时,将调转方向继续移动。
1. 首先创建一个Rectangle类,用它来绘制小方块,并提供移动,移动速度等控制方法。
public class Rectangle extends View {
public static final int MAX_SIZE = 40;
private static final int ALPHA = 255;
private int mCoordX = 0;
private int mCoordY = 0;
private int mRealSize = 40;
private int mSpeedX = 3;
private int mSpeedY = 3;
private boolean goRight = true;
private boolean goDown = true;
private DrawView mDrawView;
private Paint mInnerPaint;
private RectF mDrawRect;
public Rectangle(Context context, DrawView drawView) {
super(context);
mDrawView = drawView;
mInnerPaint = new Paint();
mDrawRect = new RectF();
/* Red is default */
mInnerPaint.setARGB(ALPHA, 255, 0, 0);
mInnerPaint.setAntiAlias(true);
}
public void setARGB(int a, int r, int g, int b) {
mInnerPaint.setARGB(a, r, g, b);
}
public void move() {
moveTo(mSpeedX, mSpeedY);
}
private void moveTo(int goX, int goY) {
// check the borders, and set the direction if a border has reached
if (mCoordX > (mDrawView.width - MAX_SIZE)) {
goRight = false;
}
if (mCoordX < 0) {
goRight = true;
}
if (mCoordY > (mDrawView.height - MAX_SIZE)) {
goDown = false;
}
if (mCoordY < 0) {
goDown = true;
}
// move the x and y
if (goRight) {
mCoordX += goX;
} else {
mCoordX -= goX;
}
if (goDown) {
mCoordY += goY;
} else {
mCoordY -= goY;
}
}
public int getSpeedX() {
return mSpeedX;
}
public void setSpeedX(int speedX) {
mSpeedX = speedX;
}
public int getmSpeedY() {
return mSpeedY;
}
public void setSpeedY(int speedY) {
mSpeedY = speedY;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(getResources().getColor(android.R.color.white));
mDrawRect.set(mCoordX, mCoordY, mCoordX + mRealSize, mCoordY
+ mRealSize);
canvas.drawRoundRect(mDrawRect, 0, 0, mInnerPaint);
}
}
2.创建DrawView类,作为小方块的载体
public class DrawView extends View {
private Rectangle mRectangle;
public int width;
public int height;
public DrawView(Context context) {
super(context);
mRectangle = new Rectangle(context, this);//初始化小方块
mRectangle.setARGB(255, 255, 0, 0); //设置小方块颜色
mRectangle.setSpeedX(3); //小方块X轴移动速度
mRectangle.setSpeedY(3);//小方块Y轴移动速度
}
@Override
protected void onDraw(Canvas canvas) {
mRectangle.move(); //让小方块移动
mRectangle.onDraw(canvas);//绘制小方块
invalidate(); //强制绘制,这意味着onDraw方法绘制完成之后会接着重新绘制
}
}
3.在Activity中加载出来
public class MainActivity extends Activity {
private DrawView mDrawView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Display display = getWindowManager().getDefaultDisplay();//获取屏幕
mDrawView = new DrawView(this);
mDrawView.height = display.getHeight();//让drawView填充整个屏幕
mDrawView.width = display.getWidth();
setContentView(mDrawView);//加载drawView
}
}
在onDraw()方法中通过调用invalidate()更新view的位置是实现自定义动画的一种简易方式,如果想做一个小游戏,这个小技巧也许适用。
4.实现Ken Burns effect幻灯片效果
Ken Burns effect是一种让静态图片平移和放大的视频特效。下面这个例子实现让图片平移和放大:
首先创建一个layout容器,往里面添加一个ImageView
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mImageContainer=new FrameLayout(this);
mImageContainer.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT));
imageView=createNewImageView();
mImageContainer.addView(imageView);
setContentView(mImageContainer);
}
private ImageView createNewImageView(){
ImageView img=new ImageView(this);
img.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
img.setImageResource(images[imageIndex]);
img.setScaleType(ImageView.ScaleType.FIT_XY);
imageIndex=imageIndex+1<images.length?imageIndex+1:0;
return img;
}
然后为ImageView添加动画
private void nextAnimation(){
AnimatorSet animatorSet=new AnimatorSet();
int index=random.nextInt(images.length);
switch (index){
case 0://放大
animatorSet.playTogether(
ObjectAnimator.ofFloat(imageView,"scaleX",1f,1.5f),
ObjectAnimator.ofFloat(imageView,"scaleY",1f,1.5f)
);
break;
case 1://平移
AnimatorProxy.wrap(imageView).setScaleX(1.5f);
AnimatorProxy.wrap(imageView).setScaleY(1.5f);
animatorSet.playTogether(ObjectAnimator.ofFloat(imageView,
"translationX", 0f, 80f));
break;
}
animatorSet.setDuration(5000);
animatorSet.addListener(this);
animatorSet.start();
}
其实这个动画效果就是使用了NineOldAndroid开源库,属性动画,与旧版本的动画相比,属性动画解决了老版本动画的如下缺点:
1.老版本动画只支持View的动画效果
2.老版本动画只支持移动,缩放,旋转,透明度
3.老版本动画在view移动时只是视觉上移动,实际位置无法改变