您的位置:首页 > 移动开发 > Android开发

用SurfaceView,Timer以及Handler实现的一个带有音乐和文字的电子相册,可以自动播放~

2013-01-31 10:48 681 查看
这个应用可以用来送人,呵呵,你把你和女友的甜蜜照片加上去,然后写点文字,再加点音乐,是不是很浪漫呢?程序的不足在于没有加入文件浏览器,以及图片间切换时的动画没有实现,因为采用的事SurfaceView来画的,bitmap的动画不会加,所以就没有做,有哪位大大能实现这部分功能的话,麻烦不吝告知啊,小弟在此多谢了。废话到此为止下面上代码。项目结构就是两个文件一个是继承自Acitivity的ImageBrowser.java,另一个是继承自SurfaceView的ImageSurface.java。

ImageBrowser.java

package com.example.appforimagebrowser;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.Window;
import android.view.WindowManager.LayoutParams;

public class ImageBrowser extends Activity {

public static Activity instance;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

getWindow().addFlags(LayoutParams.FLAG_FULLSCREEN);
requestWindowFeature(Window.FEATURE_NO_TITLE);

setContentView(R.layout.imagebrowser);
instance = this;
}

@Override
protected void onPause() {
super.onPause();
finish();
}

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
if (keyCode == KeyEvent.KEYCODE_BACK) {
processExit();
}

return super.onKeyDown(keyCode, event);
}

private void processExit() {

new AlertDialog.Builder(ImageBrowser.this)
.setIcon(R.drawable.ic_launcher).setTitle("退出")
.setMessage("您确定要退出浏览吗?")
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
finish();
}
})
.setNegativeButton("取消", new DialogInterface.OnClickListener() {

public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub

}
}).show();
}

}


上面的代码没什么说的,无非就是创建了一个Dialog什么的 

ImageSurface.java

public class ImageSurface extends SurfaceView implements SurfaceHolder.Callback {

private final int START = 0;
private final int STOP = 1;

private AudioManager mAudioManager;

private SurfaceHolder mSurfaceHolder;

private int mImageRes[] = { R.drawable.a, R.drawable.b, R.drawable.c,
R.drawable.d, R.drawable.e, R.drawable.f, R.drawable.g,
R.drawable.h, R.drawable.i, R.drawable.j };
private String mText[] = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j" };

private Resources mRes;

private Canvas mCanvas;

private boolean mIsRun = false;

private int mScreenWidth;
private int mScreenHeight;

private Paint mPaint;

private Bitmap mBitmap;

private static int sCounter = 0;

private MyTimerTask mMyTimerTask = null;
private Timer mTimer = null;

private MediaPlayer mPlayer;

private Handler mHandler = new Handler() {

@Override
public void handleMessage(Message msg) {

switch (msg.what) {
case START:
// TODO Auto-generated method stub
mCanvas = mSurfaceHolder.lockCanvas();
mBitmap = BitmapFactory.decodeStream(mRes
.openRawResource(mImageRes[msg.arg1]));
mBitmap = resizeImage(mBitmap, mScreenWidth, mScreenHeight);
// drawBitmapWithAnim(mBitmap, mCanvas, mPaint);
mCanvas.drawBitmap(mBitmap, 0, 0, mPaint);
mPaint.setTextSize(50);
mCanvas.drawText(mText[msg.arg1], mScreenWidth / 2,
9 * mScreenHeight / 10, mPaint);
mSurfaceHolder.unlockCanvasAndPost(mCanvas);
break;
case STOP:
stopTimer();
break;

}
}

};

public ImageSurface(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub

mSurfaceHolder = this.getHolder();
mSurfaceHolder.addCallback(this);
mRes = getResources();
mCanvas = new Canvas();
mPaint = new Paint();

}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub

}

@Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
mAudioManager = (AudioManager) ImageBrowser.instance
.getSystemService(Context.AUDIO_SERVICE);
mScreenWidth = this.getWidth();
mScreenHeight = this.getHeight();
mPlayer = MediaPlayer.create(getContext(), R.raw.music);
mPlayer.setLooping(true);
mPlayer.start();
SurfaceHolder sfh = this.getHolder();
Canvas canvas = sfh.lockCanvas();
Paint p = new Paint();
p.setTextSize(60);
p.setColor(Color.BLUE);
p.setFilterBitmap(true);// 对位图进行滤波处理
p.setTextSize(scalaFonts(50));
float tX = (mScreenWidth - getFontlength(p, "轻触开始观看")) / 2;
float tY = (mScreenHeight - getFontHeight(p)) / 2 + getFontLeading(p);
canvas.drawText("轻触开始观看", tX, tY, p);
sfh.unlockCanvasAndPost(canvas);
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
mMyTimerTask.cancel();
mTimer.cancel();
mPlayer.stop();
}

public static Bitmap resizeImage(Bitmap bitmap, int w, int h) {
Bitmap BitmapOrg = null;
BitmapOrg = bitmap;
int width = BitmapOrg.getWidth();
int height = BitmapOrg.getHeight();
int newWidth = w;
int newHeight = h;
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
Matrix matrix = new Matrix();
matrix.postScale(scaleWidth, scaleHeight);
Bitmap resizedBitmap = Bitmap.createBitmap(BitmapOrg, 0, 0, width,
height, matrix, true);
return resizedBitmap;
}

@Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
Message msg = new Message();
if (mIsRun == true) {
msg.what = STOP;
mIsRun = false;

} else if (mIsRun == false) {
startTimer();
mIsRun = true;
msg.what = START;
msg.arg1 = sCounter;
}
mHandler.sendMessage(msg);
return super.onTouchEvent(event);
}

class MyTimerTask extends TimerTask {

@Override
public void run() {
// TODO Auto-generated method stub
Message msg = new Message();
msg.what = START;
msg.arg1 = sCounter;
mHandler.sendMessage(msg);
sCounter++;
if (sCounter >= mImageRes.length) {
sCounter = 0;
}
}

}

private void startTimer() {
if (mTimer == null) {
mTimer = new Timer();
}

if (mMyTimerTask == null) {
mMyTimerTask = new MyTimerTask();
}

if (mTimer != null && mMyTimerTask != null)
mTimer.schedule(mMyTimerTask, 0, 2000);

}

private void stopTimer() {

if (mTimer != null) {
mTimer.c
4000
ancel();
mTimer = null;
}

if (mMyTimerTask != null) {
mMyTimerTask.cancel();
mMyTimerTask = null;
}

}

/**
* 根据屏幕系数比例获取文字大小
*
* @return
*/
private static float scalaFonts(int size) {
// 暂未实现
return size;
}

/**
* @return 返回指定笔和指定字符串的长度
*/
public static float getFontlength(Paint paint, String str) {
return paint.measureText(str);
}

/**
* @return 返回指定笔的文字高度
*/
public static float getFontHeight(Paint paint) {
FontMetrics fm = paint.getFontMetrics();
return fm.descent - fm.ascent;
}

/**
* @return 返回指定笔离文字顶部的基准距离
*/
public static float getFontLeading(Paint paint) {
FontMetrics fm = paint.getFontMetrics();
return fm.leading - fm.ascent;
}

}


上面的文件中,主要是采用定时器定时向Handler发送消息,让Handler来更新当前界面,采用SurfaceView本意是准备提高效率,但是不知道效果相比ImageView如何。需要注意的是上面的读取drawable中图片时采用的方法,上面的stoptimer和starttimer是为了实现点击以后的Timer发送消息的暂停事件

mBitmap = BitmapFactory.decodeStream(mRes.openRawResource(mImageRes[msg.arg1]));

这种打开图片的方式是比较节省内存的,利用SurfaceView开发游戏时使用这种方法可以有效的规避OOM Exception。

额,略微无耻一下,源码下载要了一分,主要是有的时候下东西积分不够,各位海涵,不过主要代码都在上面贴着了.........

源码下载地址:http://download.csdn.net/detail/hui3909/5043031

mBitmap = BitmapFactory.decodeStream(mRes.openRawResource(mImageRes[msg.arg1]));
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐