Android 在SurfaceView中加载图像时出现问题
我需要加载保存在drawable中的汽车的不同图像,基本上模拟360度旋转,当用户拖动视图时,我已经设置了拖动距离,一旦用户穿过它,我将加载下一帧。我正在使用表面视图,并在画布上绘制图像。由于图像太大,我无法一次将所有图像加载到内存中,因此我通过在内存中只保留当前图像来动态加载图像。但这一方针过于迟缓。有人能指出我做错了什么吗?或者其他更好的方法来达到同样的效果。谢谢你的帮助 这是我的密码 /** *@作者rajeshcp *类,该类充当视图中的俯视图 *CarDetailsActivity的层次结构 *@自2013年2月13日起 */Android 在SurfaceView中加载图像时出现问题,android,surfaceview,Android,Surfaceview,我需要加载保存在drawable中的汽车的不同图像,基本上模拟360度旋转,当用户拖动视图时,我已经设置了拖动距离,一旦用户穿过它,我将加载下一帧。我正在使用表面视图,并在画布上绘制图像。由于图像太大,我无法一次将所有图像加载到内存中,因此我通过在内存中只保留当前图像来动态加载图像。但这一方针过于迟缓。有人能指出我做错了什么吗?或者其他更好的方法来达到同样的效果。谢谢你的帮助 这是我的密码 /** *@作者rajeshcp *类,该类充当视图中的俯视图 *CarDetailsActivity的层
公共类VirtualView扩展了SurfaceView,实现了SurfaceHolder.Callback、OnTouchListener、TweEnster{
私有最终整数帧_宽度=1024;
专用最终整数帧_高度=462;
私有交互侦听器mInteractionListener;
私人最终int mSnapVelocity=1000;
私人速度追踪器mVelocityTracker;
受保护的内部mTouchSlop;
私人互联网速度;
私有Rect mViewArea;
私人IQTweener动画师;
私人色彩变化;
/**************指示当前帧*********************/
私有int mCurrentFrameIndex;
/**********初始接触x坐标**************/
私人int mInitialTouchX;
/***********帧更改的拖动距离***********/
私人井内井=10;
私有最终整数mTotalFrames=36;
受保护的最终整数mMaxFrameSkip=3;
/**************单位矩阵**********************/
私有矩阵中音矩阵;
私人油漆;
/*********要在画布上绘制的位图*********/
私有位图mCurrentFrame;
私有视图更新程序mViewUpdater;
/*++++++++++++++++++++++++++++++++++++++++++++++*/
/*+++++++++++++接球手和接球手++++++++++++++*/
/*++++++++++++++++++++++++++++++++++++++++++++++*/
/**
*@param的类型为null
*@return ColorVariationVO类型的mColorVariationVO
*mColorVariationVO的getter函数
*@自2013年2月13日起
*@作者rajeshcp
*/
公共颜色变量vo getmColorVariationVO(){
返回mColorVariationVO;
}
/**
*@param mColorVariationVO类型为ColorVariationVO
*@返回null类型
*mColorVariationVO的setter函数
*@自2013年2月13日起
*@作者rajeshcp
*/
公共无效设置mColorVariationVO(颜色变量VO mColorVariationVO){
this.mColorVariationVO=mColorVariationVO;
loadNextFrame();
}
/**
*@param context类型为context
*@return of type VirtualView
*构造函数
*@自2013年2月13日起
*@作者rajeshcp
*/
公共虚拟视图(上下文){
超级(上下文);
init();
}
/**
*@param context类型为context
*@AttributeSet类型的参数attrs
*@return of type VirtualView
*构造函数
*@自2013年2月13日起
*@作者rajeshcp
*/
公共虚拟视图(上下文、属性集属性){
超级(上下文,attrs);
init();
}
/**
*@param context类型为context
*@AttributeSet类型的参数attrs
*@param defStyle类型int
*@return of type VirtualView
*构造函数
*@自2013年2月13日起
*@作者rajeshcp
*/
公共虚拟视图(上下文、属性集属性、int-defStyle){
超级(上下文、属性、定义样式);
init();
}
/**
*@param的类型为null
*@返回null类型
*函数,该函数将初始化视图的值
*@自2013年2月13日起
*/
私有void init()
{
setZOrderOnTop(真);
getHolder().setFormat(PixelFormat.TRANSPARENT);
mPaint=新绘制(Paint.FILTER_BITMAP_FLAG | Paint.抖动_FLAG | Paint.ANTI_ALIAS_FLAG);
中音矩阵=新矩阵();
mCurrentFrameIndex=0;
mViewUpdater=新的视图更新程序();
mInteractionListener=新的InteractionListener();
final ViewConfiguration=ViewConfiguration.get(getContext());
mTouchSlop=configuration.getScaledTouchlop();
mMaxVelocity=configuration.getScaledMaximumFlingVelocity();
getHolder().addCallback(此);
setOnTouchListener(这个);
setLayerType(View.LAYER\u TYPE\u硬件,mPaint);
}
/**
*@param类型int的方向
*@返回null类型
*用于更改当前帧索引的函数
*@自2013年2月13日起
*@作者rajeshcp
*/
私有void initiateFrameChange(最终整数方向)
{
mCurrentFrameIndex+=Math.max(-mMaxFrameSkip,Math.min(mMaxFrameSkip,direction));
如果(mCurrentFrameIndex>(mTotalFrames-1))
{
mCurrentFrameIndex=(mCurrentFrameIndex%(mTotalFrames-1));
}else if(mCurrentFrameIndex<0)
{
mCurrentFrameIndex=(mTotalFrames-1)+(mCurrentFrameIndex%(mTotalFrames-1));
}
loadNextFrame();
}
/**
*@param int类型的索引
*@返回类型位图
*函数,该函数将创建位图表单
*资源
*@自2013年2月13日起
*@作者rajeshcp
*/
@SuppressLint(“UseSparsearray”)
私有位图getFrame(最终整数索引)
{
位图=空;
if(mColorVariationVO!=null)
{
最终int-drawableId=getResourceId(索引);
尝试
{
位图=BitmapFactory.decodeResource(getResources(),drawableId);
}捕获(例外e){
d(getClass().getName(),e.getLocalizedMessage());
}
}
返回位图;
}
/**
*@param int类型的索引
*@返回int类型
*创建资源id的函数
*从索引
*@自2013年2月18日起
*@作者rajeshcp
*/
私有int getResourceId(最终int索引)
{
最后一个字符串frameName=mColorVariationVO.getmCarAssetPath()+“389;”+索引;
int-drawableId=0;
试一试{
@抑制警告(“原始类型”)
类别res=R.drawable.clas
public class VirtualView extends SurfaceView implements SurfaceHolder.Callback, OnTouchListener, TweenListener {
private final int frame_width = 1024;
private final int frame_height = 462;
private InteractionListener mInteractionListener;
private final int mSnapVelocity = 1000;
private VelocityTracker mVelocityTracker;
protected int mTouchSlop;
private int mMaxVelocity;
private Rect mViewArea;
private IQTweener mValueanimator;
private ColorVariationVO mColorVariationVO;
/**************Indicates the current frame*********************/
private int mCurrentFrameIndex;
/**********Initial touch x coordinate**************/
private int mInitialTouchX;
/***********The drag distance for frame change***********/
private int mDragInterWell = 10;
private final int mTotalFrames = 36;
protected final int mMaxFrameSkip = 3;
/**************Identity matrix**********************/
private Matrix mIdentityMatrix;
private Paint mPaint;
/*********The bitmap to be drawn over the canvas*********/
private Bitmap mCurrentFrame;
private ViewUpdater mViewUpdater;
/*++++++++++++++++++++++++++++++++++++++++++++++*/
/*+++++++++++++Getters and Setters++++++++++++++*/
/*++++++++++++++++++++++++++++++++++++++++++++++*/
/**
* @param of type null
* @return mColorVariationVO of type ColorVariationVO
* getter function for mColorVariationVO
* @since Feb 13, 2013
* @author rajeshcp
*/
public ColorVariationVO getmColorVariationVO() {
return mColorVariationVO;
}
/**
* @param mColorVariationVO of type ColorVariationVO
* @return of type null
* setter function for mColorVariationVO
* @since Feb 13, 2013
* @author rajeshcp
*/
public void setmColorVariationVO(ColorVariationVO mColorVariationVO) {
this.mColorVariationVO = mColorVariationVO;
loadNextFrame();
}
/**
* @param context of type Context
* @return of type VirtualView
* Constructor function
* @since Feb 13, 2013
* @author rajeshcp
*/
public VirtualView(Context context) {
super(context);
init();
}
/**
* @param context of type Context
* @param attrs of type AttributeSet
* @return of type VirtualView
* Constructor function
* @since Feb 13, 2013
* @author rajeshcp
*/
public VirtualView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
/**
* @param context of type Context
* @param attrs of type AttributeSet
* @param defStyle of type int
* @return of type VirtualView
* Constructor function
* @since Feb 13, 2013
* @author rajeshcp
*/
public VirtualView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
/**
* @param of type null
* @return of type null
* function which will initialize the values for the view
* @since 13 Feb 2013
*/
private void init()
{
setZOrderOnTop(true);
getHolder().setFormat(PixelFormat.TRANSPARENT);
mPaint = new Paint(Paint.FILTER_BITMAP_FLAG | Paint.DITHER_FLAG | Paint.ANTI_ALIAS_FLAG);
mIdentityMatrix = new Matrix();
mCurrentFrameIndex = 0;
mViewUpdater = new ViewUpdater();
mInteractionListener = new InteractionListener();
final ViewConfiguration configuration = ViewConfiguration.get(getContext());
mTouchSlop = configuration.getScaledTouchSlop();
mMaxVelocity = configuration.getScaledMaximumFlingVelocity();
getHolder().addCallback(this);
setOnTouchListener(this);
setLayerType(View.LAYER_TYPE_HARDWARE, mPaint);
}
/**
* @param direction of type int
* @return of type null
* function which will change the current frame index
* @since Feb 13, 2013
* @author rajeshcp
*/
private void initiateFrameChange(final int direction)
{
mCurrentFrameIndex += Math.max(-mMaxFrameSkip, Math.min(mMaxFrameSkip, direction));
if( mCurrentFrameIndex > (mTotalFrames - 1) )
{
mCurrentFrameIndex = (mCurrentFrameIndex % ( mTotalFrames - 1) );
}else if( mCurrentFrameIndex < 0 )
{
mCurrentFrameIndex = (mTotalFrames - 1) + (mCurrentFrameIndex % (mTotalFrames - 1));
}
loadNextFrame();
}
/**
* @param index of type int
* @return of type Bitmap
* function which will create the bitmap form the
* resources
* @since Feb 13, 2013
* @author rajeshcp
*/
@SuppressLint("UseSparseArrays")
private Bitmap getFrame(final int index)
{
Bitmap bitmap = null;
if( mColorVariationVO != null)
{
final int drawableId = getResourceId(index);
try
{
bitmap = BitmapFactory.decodeResource(getResources(), drawableId);
}catch (Exception e) {
Log.d(getClass().getName(), e.getLocalizedMessage());
}
}
return bitmap;
}
/**
* @param index of type int
* @return of type int
* function which create the resource id
* from index
* @since Feb 18, 2013
* @author rajeshcp
*/
private int getResourceId(final int index)
{
final String frameName = mColorVariationVO.getmCarAssetPath() + "_" + index;
int drawableId = 0;
try {
@SuppressWarnings("rawtypes")
Class res = R.drawable.class;
Field field = res.getField(frameName);
drawableId = field.getInt(null);
}
catch (Exception e) {
Log.e(getClass().getName(), "Failure to get drawable id.", e);
}
return drawableId;
}
/* (non-Javadoc)
* @see android.view.View#onDraw(android.graphics.Canvas)
* @since Feb 13, 2013
* @author rajeshcp
*/
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if( mCurrentFrame != null && canvas != null )
{
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
mIdentityMatrix.reset();
// mPaint.setStyle(Paint.Style.STROKE);
// mPaint.setStrokeWidth(1);
// mPaint.setColor(Color.MAGENTA);
// mPaint.setTextSize(100);
//
// canvas.drawText(String.valueOf(mCurrentFrameIndex), (getWidth() / (mTotalFrames - 1) ) * mCurrentFrameIndex, (getHeight() - 100) / 2, mPaint);
mIdentityMatrix.postTranslate(getWidth() - frame_width, (getHeight() - frame_height) / 2);
canvas.drawBitmap(mCurrentFrame, mIdentityMatrix, mPaint);
}
}
/* (non-Javadoc)
* @see android.view.SurfaceHolder.Callback#surfaceChanged(android.view.SurfaceHolder, int, int, int)
* @since Feb 13, 2013
* @author rajeshcp
*/
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
/* (non-Javadoc)
* @see android.view.SurfaceHolder.Callback#surfaceCreated(android.view.SurfaceHolder)
* @since Feb 13, 2013
* @author rajeshcp
*/
@Override
public void surfaceCreated(SurfaceHolder holder) {
if( mViewArea == null )
{
int top = (getHeight() - frame_height) / 2;
int left = getWidth() - frame_width;
mViewArea = new Rect(left, top, frame_width + left, frame_height + top);
}
mDragInterWell = (int)(mViewArea.width() / (2 * mTotalFrames));
if( mViewUpdater == null)
{
init();
}
mViewUpdater.start();
mInteractionListener.start();
}
/* (non-Javadoc)
* @see android.view.SurfaceHolder.Callback#surfaceDestroyed(android.view.SurfaceHolder)
* @since Feb 13, 2013
* @author rajeshcp
*/
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
if(mViewUpdater != null)
{
mViewUpdater.setRun(false);
mViewUpdater = null;
mInteractionListener.mIsRunning = false;
mInteractionListener = null;
}
}
private boolean isScrolled = false;
/* (non-Javadoc)
* @see android.view.View.OnTouchListener#onTouch(android.view.View, android.view.MotionEvent)
* @since Feb 13, 2013
* @author rajeshcp
*/
@Override
public boolean onTouch(View v, MotionEvent event) {
mInteractionListener.queueEvent(event);
return true;
}
/**
* @param velocity of type int
* @return of type null
* function which will initiate the
* fling animation
* @since Feb 15, 2013
* @author rajeshcp
*/
private void initiateFling(int velocity)
{
return;
// int maxDuration = mMaxFrameSkip * mSnapVelocity;
// velocity = Math.max(-maxDuration, Math.min(maxDuration, velocity));
// int end = ((int)( velocity / mSnapVelocity )) * mTotalFrames;
//
// if( mValueanimator == null )
// {
// mValueanimator = new IQTweener(mCurrentFrameIndex, mTotalFrames - 1);
// mValueanimator.setmListener(this);
// }
// mValueanimator.setMduration(2000);
// mValueanimator.setmStart(mCurrentFrameIndex);
// mValueanimator.setmEnd(end);
// mValueanimator.start();
}
/**
* @param of type null
* @return of type null
* function which will clear
* the touch values
* @since Feb 15, 2013
* @author rajeshcp
*/
private void onTouchEnd()
{
isScrolled = false;
mVelocityTracker.clear();
mVelocityTracker.recycle();
mVelocityTracker = null;
mInitialTouchX = 0;
}
/* (non-Javadoc)
* @see com.inkoniq.iqpromomultitouch.animations.IQTweener.TweenListener#onUpdate(java.lang.Object)
* @since Feb 15, 2013
* @author rajeshcp
*/
@Override
public void onUpdate(float mCurrent) {
final int mIndex = (int) mCurrent;
if( mIndex > (mTotalFrames - 1) )
{
mCurrentFrameIndex = (mIndex % ( mTotalFrames - 1) );
}else if( mIndex < 0 )
{
mCurrentFrameIndex = (mTotalFrames - 1) + (mIndex % (mTotalFrames - 1));
}
}
/**
* @param of type null
* @return of type null
* function which will load the next frame from local storage
* @since Feb 13, 2013
* @author rajeshcp
*/
private void loadNextFrame()
{
final Bitmap frame = getFrame(mCurrentFrameIndex);
if(mCurrentFrame != null)
{
Bitmap temp = mCurrentFrame;
mCurrentFrame = frame;
temp.recycle();
temp = null;
}else
{
mCurrentFrame = frame;
}
}
/**
* @author rajeshcp
* class which will take care of updating the view
* @since 13 Feb 2013
*/
private class ViewUpdater extends Thread
{
private SurfaceHolder surface;
private boolean run = true;
/**
* @param run of type boolean
* @return of type null
* setter function for run
* @since 13 Feb 2013
*/
public void setRun(boolean run) {
this.run = run;
}
/**
* @param surface of type SurfaceHolder
* @param gameView of type GameView
* Constructor function
* @since 13 Feb 2013
*/
public ViewUpdater()
{
}
/*
* (non-Javadoc)
* @see java.lang.Thread#run()
* @since Feb 13, 2013
* @author rajeshcp
*/
@Override
public void run() {
Canvas canvas;
while (run) {
canvas = null;
try {
surface = getHolder();
canvas = surface.lockCanvas(null);
synchronized (surface) {
onDraw(canvas);
}
} finally {
if (canvas != null) {
surface.unlockCanvasAndPost(canvas);
}
}
}
}
}
/**
* @author rajeshcp
* Class which will handle the touch
* events
* @since 19 Feb 2013
*/
private class InteractionListener extends Thread
{
ArrayList<MotionEvent> mEventQueue;
boolean mIsRunning = false;
/**
* @param of type null
* @return of type InteractionListener
* Constructor function
* @since Feb 19, 2013
* @author rajeshcp
*/
public InteractionListener()
{
init();
}
/**
* @param of type null
* @return of type null
* @since Feb 19, 2013
* @author rajeshcp
*/
private void init()
{
mIsRunning = true;
mEventQueue = new ArrayList<MotionEvent>();
}
/**
* @param event of type MotionEvent
* @return of type null
* function which will add the event to
* the mEventQueue
* @since Feb 19, 2013
* @author rajeshcp
*/
private void queueEvent(MotionEvent event)
{
mEventQueue.add(event);
}
/**
* @param event of type MotionEvent
* @return of type null
* function which will process the touch event
* @since Feb 19, 2013
* @author rajeshcp
*/
private void onTouch(MotionEvent event) {
if( event == null )
return;
if( mVelocityTracker == null )
{
mVelocityTracker = VelocityTracker.obtain();
}
mVelocityTracker.addMovement(event);
if( !mViewArea.contains((int)event.getX(), (int)event.getY()) )
{
return;
}
switch(event.getAction())
{
case MotionEvent.ACTION_DOWN :
{
if( mValueanimator != null )
{
mValueanimator.cancel();
}
isScrolled = false;
mInitialTouchX = (int)event.getX();
break;
}
case MotionEvent.ACTION_MOVE :
{
final int currentX = (int)event.getX();
final int draggedDistance = (currentX - mInitialTouchX);
if( draggedDistance != 0 && draggedDistance % mDragInterWell == 0 )
{
isScrolled = true;
initiateFrameChange(draggedDistance / mDragInterWell);
Log.d(getClass().getName(), "frameIndex = " + mCurrentFrameIndex);
mInitialTouchX = currentX;
}
break;
}
case MotionEvent.ACTION_UP :
{
if( isScrolled )
{
final VelocityTracker velocityTracker = mVelocityTracker;
velocityTracker.computeCurrentVelocity(1000, mMaxVelocity);
int velocityX = (int) velocityTracker.getXVelocity();
if( (velocityX > mSnapVelocity) || (velocityX < -mSnapVelocity) )
{
initiateFling(velocityX);
}
}
onTouchEnd();
break;
}
case MotionEvent.ACTION_CANCEL :
{
onTouchEnd();
break;
}
default :
{
break;
}
}
}
/* (non-Javadoc)
* @see java.lang.Thread#run()
* @since Feb 19, 2013
* @author rajeshcp
*/
@Override
public void run() {
while ( mIsRunning ) {
while ( mEventQueue.size() > 0 ) {
onTouch(mEventQueue.remove(0));
try
{
Thread.sleep(16);
}catch (Exception e) {
}
}
}
}
}
}