Loooong时间查看器,终于可以在StackOverflow注册了这里!
经过很长一段时间寻找在Android中滚动ViewGroup的方法后,我开发了以下内容:
public class SlidingDrawable extends Drawable implements Drawable.Callback {
private static final String TAG = "SlidingDraw";
private static float STEP_SIZE = 1.0f;
private BitmapDrawable mBitmap;
private Context mContext;
private float mPosX;
private int mBitmapWidth;
private Runnable mInvalidater;
private Handler mHandler;
public SlidingDrawable(Context c){
mContext = c;
// use this as the callback as we're implementing the interface
setCallback(this);
mHandler = new Handler();
mInvalidater = new Runnable(){
@Override
public void run(){
// decrement the drawables step size
mPosX -= SlidingDrawable.STEP_SIZE;
/*
* Check to see if the current position is at point where it should
* loop. If so, reset back to 0 to restart
*/
if(Math.abs(mPosX) >= mBitmapWidth) mPosX = 0;
// redraw
invalidateDrawable(null);
}
};
}
public static void setStepSize(float newSize){
SlidingDrawable.STEP_SIZE = newSize;
}
public void createBitmap(String path, ViewGroup parent){
// height of the parent container
int height = parent.getHeight();
/* Initialize local variables
* bgBitmap - the resulting bitmap to send into SlidingDrawable instance
* imageStream - raw bitmap data to be decoded into bgBitmap
*/
WindowManager wMgr = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
int mScreenWidth = wMgr.getDefaultDisplay().getWidth();
InputStream imageStream;
Matrix imgMatrix = new Matrix();
Bitmap bitmap = null;
try {
imageStream = mContext.getAssets().open(path);
// create a temporary bitmap object for basic data
Bitmap temp = BitmapFactory.decodeStream(imageStream);
int width = temp.getWidth();
// find the width difference as a percentage to apply to the
// transformation matrix
float widthDifference = ((float)mScreenWidth) / (float)(width / 2);
imgMatrix.postScale(widthDifference, 0, 0f, 0f);
// create a copy of the bitmap, scaled correctly to maintain loop
bitmap = Bitmap.createScaledBitmap(temp, (int)(width * widthDifference), height, true);
// recycle the temp bitmap
temp.recycle();
} catch (IOException e) {
e.printStackTrace();
}
mBitmap = new BitmapDrawable(bitmap);
// required
mBitmapWidth = getIntrinsicWidth() / 2;
Rect bounds = new Rect(0, 0, getIntrinsicWidth(), getIntrinsicHeight());
setBounds(bounds);
}
@Override
public void draw(Canvas canvas) {
canvas.drawBitmap(mBitmap.getBitmap(), mPosX, 0f, null);
scheduleDrawable(this, mInvalidater, SystemClock.uptimeMillis());
}
@Override
public int getOpacity() {
return PixelFormat.OPAQUE;
}
@Override
public void scheduleDrawable(Drawable who, Runnable what, long when) {
mHandler.postAtTime(what, who, when);
}
@Override
public void unscheduleDrawable(Drawable who, Runnable what) {
mHandler.removeCallbacks(what, who);
}
@Override
public void invalidateDrawable(Drawable who) {
invalidateSelf();
}
/*
* Methods not directly used or called omitted
*
*/
}
它在Activity中使用如下:
@Override
public void onWindowFocusChanged(boolean focus){
// set the background of the root view of main.xml
SlidingDrawable drawable = new SlidingDrawable(getApplicationContext());
drawable.createBitmap("bgimg/basebg.jpg", mRoot);
mRoot.setBackgroundDrawable(drawable);
}
长话短说,basebg.jpg图像是一个大约1600x480的可图块化图像。 SlidingDrawable的构造函数可以缩放和移动以及yaddah yaddah。它有效。
现在,问题是,这样做似乎效率很低。我似乎无法找到关于这种实现的大量信息,因此我对可以削减CPU周期的情况感到困惑,或者即使我正在使用方法调用。
我的问题包括:
我已尽可能多地研究这个...我现在将它留给StackOverflow:)
答案 0 :(得分:0)
使用绘图板一段时间后,我简化了功能。基本上,它是在每个invalidate()
上发送SystemClock.uptimeMillis()
调用,为每个步骤更改执行一次重绘。
所以,我删除了Drawable.Callback
接口并直接从处理程序传递了invalidateSelf()
调用,删除了中间接口方法,这些方法似乎没有做任何特殊的事情。
使用的CPU使用率略有不同
drawBitmap(Bitmap source, int X, int Y, Paint p)
vs.
drawBitmap(Bitmap source, Matrix matrix, Paint p)
,所以我选择后者来节省周期。
新方法如下:
// Runnable
mInvalidater = new Runnable(){
@Override
public void run(){
// decrement the drawables step size
mPosX -= SlidingDrawable.STEP_SIZE;
if(Math.abs(mPosX) >= mBitmapWidth){
mPosX = 0;
mImageMatrix.setTranslate(0, 0);
}
mImageMatrix.postTranslate(-STEP_SIZE, 0);
SlidingDrawable.this.invalidateSelf();
}
};
// Draw method
@Override
public void draw(Canvas canvas) {
canvas.drawBitmap(mBitmap.getBitmap(), mImageMatrix, null);
mHandler.postAtTime(mInvalidater, SystemClock.uptimeMillis() + 64);
}
我通过拔掉手机,运行应用程序大约一分钟,然后打开我的Moto Droid上的电池使用情况来测试电池结果。以前,电池的使用量超过了显示器,现在它可以舒适地低于显示器。
愤怒的小鸟也是一个基准,通过运行开启屏幕(bg卷轴和鸟飞到哪里)相同的时间,在某些情况下我的应用程序坐在愤怒的小鸟下面,但并不总是。
使用ADB shell命令dumpsys cpuinfo
检查了CPU使用情况,因为运行2.2的设备上的DDMS似乎出现问题viewing CPU info。
我仍然会听到关于此的其他想法,但就目前而言,它已经解决了。