有使用Twitter客户端的朋友应该有发现在登录的时候,屏幕上方和下方的云朵图片是不断移动着的,再加上Twitter那支可爱的小鸟在不停的动着,给人的感觉就好像是小鸟在飞翔一样,感觉效果很不错。

我也试着实现了一下,发现使用自定义的Drawable加上线程,还是比较容易实现的。下面是自定义Drawable的代码,注释已经写的很详细了。这里是使用了三张图片,使用一张图就更简单了,大家完全可以举一反三,实现自己的动画图片效果。

package com.liuzhichao.dynamicdrawable;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.drawable.Drawable;
import android.util.DisplayMetrics;
import android.view.View;

public class DynamicDrawable extends Drawable implements Runnable {

	private static Bitmap mBottomBgBitmap;   //底部大图  
	private static Bitmap mBottomFgBitmap;   // 底部小图
	private static Bitmap mTopBitmap;      //顶部云图片

	private final int dispalyWidth;       //手机屏幕宽度
	private final int dispalyHeight;	 //手机屏幕高度
	private float mBottomBgTop;			 //顶部大图显示的位置
	private float mBottomFgTop;			//顶部小图显示的位置

	private int startX;                //顶部云图片和底部大图移动偏移变量
	private int mBottomFgStartX;       //底部小图移动偏移变量
	private View mView;

	public DynamicDrawable(Activity activity, View mView) {
		this.mView = mView;

		if (mTopBitmap == null) {
			mTopBitmap = BitmapFactory.decodeResource(activity.getResources(),
					R.drawable.cloud_top_bg);
		}
		if (mBottomBgBitmap == null) {
			mBottomBgBitmap = BitmapFactory.decodeResource(
					activity.getResources(), R.drawable.cloud_bottom_bg);
		}
		if (mBottomFgBitmap == null) {
			mBottomFgBitmap = BitmapFactory.decodeResource(
					activity.getResources(), R.drawable.cloud_bottom_fg);
		}

		//获取屏幕高度和宽度
		DisplayMetrics dm = new DisplayMetrics();
		dm = activity.getResources().getDisplayMetrics();
		this.dispalyHeight = dm.heightPixels;
		this.dispalyWidth = dm.widthPixels;

		//顶部图片显示的位置  = 屏幕高度 - 图片自身高 - 标题高度
		this.mBottomBgTop = dispalyHeight - mBottomBgBitmap.getHeight() - 100;
		this.mBottomFgTop = dispalyHeight - mBottomFgBitmap.getHeight() - 100;

		//开始移动图片线程
		new Thread(this).start();
	}

	@Override
	public void draw(Canvas canvas) {
		// drawBitmap (Bitmap bitmap, float left, float top, Paint paint)
		canvas.drawBitmap(mTopBitmap, startX, 0, null);
		canvas.drawBitmap(mBottomBgBitmap, startX, mBottomBgTop, null);
		canvas.drawBitmap(mBottomFgBitmap, mBottomFgStartX, mBottomFgTop, null);
	}

	@Override
	public int getOpacity() {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public void setAlpha(int arg0) {
		// TODO Auto-generated method stub

	}

	@Override
	public void setColorFilter(ColorFilter arg0) {
		// TODO Auto-generated method stub

	}

	@Override
	public void run() {
		while (!Thread.currentThread().isInterrupted()) {
			//900 是图片的长度
			//如果移动偏量已经大于图片的长度 - 屏幕宽度,则说明已经移动到了图片的末端,如果继续移动,则会显示空白
			//所以将startX重新赋予0,让图片重新开始移动
			//但是这样过渡效果会比较明显,再切换的那一刹那,会明显感觉图片变化较大
			if (startX + (900 - dispalyWidth) == 0) {
				startX = 0;
			} else {
				startX -= 1;
			}

			//底部小图的移动,
			// -=2 是让小图移动的比大图快,造成不同的视觉效果
			if (mBottomFgStartX + (900 - dispalyWidth) == 0) {
				mBottomFgStartX = 0;
			} else {
				mBottomFgStartX -= 2;
			}
			try {
				//每 1/10秒移动一次
				Thread.sleep(100L);
			} catch (InterruptedException e) {
				Thread.currentThread().interrupt();
			}
			//刷新界面
			mView.postInvalidate();
		}

	}

}

然后在需要背景图的地方,直接setBackgroundDrawable就可以了,下面的background是整个布局文件的id。

private View background;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        background = findViewById(android.R.id.background);
        background.setBackgroundDrawable(new DynamicDrawable(this, background));
    }

布局文件也还是贴出来吧:

<RelativeLayout 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"
    android:id="@android:id/background" >

     <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:padding="@dimen/padding_medium"
        android:text="@string/hello_world"
        tools:context=".MainActivity" />

 </RelativeLayout>

还是截张图吧,虽然看不到动画效果。大家如果有能在64位Win7下能用的动画截图软件,请像我推荐一下。