您的位置:首页 > 编程语言

代码垃圾杂记 - Surface实现的较高性能书籍列表

2012-12-23 15:04 218 查看
因为各种问题没解决而中断,暂时记录下来,方便日后有用的时候查看。代码中涉及到分辨率配饰问题,涉及到dps和pix的转换。

 

package fproject.view;

import java.util.Iterator;

import com.fproject.cloudshare.R;

import fproject.mod.MyData;
import fproject.mod.MyData.BookData;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.PixelFormat;
import android.graphics.PointF;
import android.graphics.Rect;
import android.os.Handler;
import android.text.Layout.Alignment;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.ImageView;

public class BookView extends SurfaceView implements SurfaceHolder.Callback
{
public Context c;
public MyData d;

public Bitmap bmp_shelf;
private Bitmap bmp_row;
private Bitmap bmp_book;
private int dpi;
private int row;
private int rowheight;

private SurfaceHolder holder;

public BookView(Context context) {
super(context);
c = context;
init();
}

public BookView(Context context, AttributeSet attrs) {
super(context,attrs);
c = context;
init();
/*
Log.d("MyDebug","Display.density: " + res.getDisplayMetrics().densityDpi);
TypedValue value = new TypedValue();
res.openRawResource(R.drawable.shelf, value);
Log.d("MyDebug","Shelf.density: " + value.density);
Log.d("MyDebug","Bitmap.density: " + bitmap.getDensity());*/
}

private void init() {
d = MyData.d.get();

getSuitBitmap();
drawShelf();
drawBooks();

holder = this.getHolder();
holder.addCallback(this);
}

public void getSuitBitmap() {
Resources res = MyData.d.get().a_main.get().getResources();

row = (d.list_book.size()-1)/4 + 1;
dpi = res.getDisplayMetrics().densityDpi;
rowheight = 200 * dpi / 240;

bmp_row = BitmapFactory.decodeResource(res, R.drawable.shelf);
if (dpi != 240) {
Matrix matrix = new Matrix();
matrix.postScale((float) (d.screen_width / 480.0f) * 240.0f / dpi, 1.0f);

bmp_row = Bitmap.createBitmap(bmp_row, 0, 0, bmp_row.getWidth(), bmp_row.getHeight(), matrix, true);

text_size = text_size * dpi / 240.0f;
}

bmp_book = BitmapFactory.decodeResource(res, R.drawable.book);
/*
if (dpi != 240) {
Matrix matrix = new Matrix();
//matrix.postScale((float) (bmp_book.getWidth() / 480.0f) * 240.0f / dpi, 1.0f);

bmp_book = Bitmap.createBitmap(bmp_book, 0, 0, bmp_book.getWidth(), bmp_book.getHeight(), matrix, true);
}*/
bmp_book.setDensity(dpi);
}

public void drawShelf() {
bmp_shelf = Bitmap.createBitmap(d.screen_width, row * rowheight, Config.RGB_565);
Canvas canvas = new Canvas(bmp_shelf);
for (int i = 0; i < row; i++) {
canvas.drawBitmap(bmp_row, 0, i * rowheight, null);
}

bmp_shelf.setDensity(dpi);
}

float text_size = 25.0f;
public void drawBooks() {
Canvas canvas = new Canvas(bmp_shelf);

int i=0;
float row_average = d.screen_width/4.0f;
int offset_x = (int)((row_average - bmp_book.getWidth())/2.0f);
int offset_y = rowheight - bmp_book.getHeight() - 20;
int title_offset_y = (int)(90.0f*dpi/240.0f);

TextPaint textPaint = new TextPaint();
textPaint.setARGB(0xff, 255, 255, 255);
textPaint.setTextSize(text_size);
textPaint.setTextAlign(Align.RIGHT);
textPaint.setAntiAlias(true);

for(Iterator<BookData> itr=d.list_book.iterator();itr.hasNext();) {
BookData bd = itr.next();
int r = i/4;
int book_x = (int)((i%4)*(row_average)+offset_x);
int book_y = r*rowheight+offset_y;

canvas.drawBitmap(bmp_book, book_x, book_y, null);

String title = measureTitle(bd.title);
StaticLayout layout = new StaticLayout(title, textPaint, 240, Alignment.ALIGN_NORMAL, 1.0F, 0.0F, true);
canvas.translate(book_x+bmp_book.getWidth(), book_y+title_offset_y);
layout.draw(canvas);
canvas.translate(-book_x-bmp_book.getWidth(), -book_y-title_offset_y);

i++;
}
}

public String measureTitle(String title) {
TextPaint textPaint = new TextPaint();
textPaint.setTextSize(text_size);

if(textPaint.measureText(title, 0, title.length())<bmp_book.getWidth())
return title;

int i; String str=null;
for(i=title.length();i>0;i--) {
str = title.substring(0, i) + "...";
float width = textPaint.measureText(str);
if(width<bmp_book.getWidth()) {
break;
}
}

return str;
}

private myRunnable run_draw;
private Thread thread_draw;
@Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {}

@Override
public void surfaceCreated(SurfaceHolder holder) {}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
stopDraw();
}

public void startDraw() {
run_draw = new myRunnable(holder);
flag = "run";
thread_draw = new Thread(run_draw,"bookview_thread");
thread_draw.start();
}
public void stopDraw() {
flag = "exit";
synchronized(flag) {
if(flag=="end")
flag = "";
}

setBackup();
}

public String flag;
class myRunnable implements Runnable {
private SurfaceHolder holder;
public myRunnable(SurfaceHolder holder) {
this.holder =holder;
}

@Override
public void run() {
synchronized(flag) {
int frame = 0;
Canvas c = null;
Rect rt_dest = new Rect();
rt_dest.top = 0; rt_dest.left = 0; rt_dest.bottom = BookView.this.getHeight(); rt_dest.right = d.screen_width;
Rect rt_src = new Rect();
rt_src.left = 0; rt_src.right = rt_dest.right;

while(flag=="run")
{
try
{
if(need_accl) accl();
rt_src.top = (int)-nowp.y; rt_src.bottom = rt_src.top + rt_dest.bottom;
synchronized (holder)
{
c = holder.lockCanvas();//锁定画布,一般在锁定后就可以通过其返回的画布对象Canvas,在其上面画图等操作了。
c.drawBitmap(bmp_shelf, rt_src, rt_dest, null);
}
}
catch (Exception e) {
e.printStackTrace();
}
finally
{
if(c!= null)
holder.unlockCanvasAndPost(c);//结束锁定画图,并提交改变。
}
if(frame++==60) frame = 0;
}
flag = "end";
}
}

private void accl(){
speed = (float)speed - 0.04f*t_f;

if(isadd) nowp.y += speed;
else nowp.y -= speed;

float top = BookView.this.getHeight()-row*rowheight;
if(nowp.y>0) {
nowp.y=0;
speed = 0.0f;
} else if(nowp.y<top) {
nowp.y = top;
speed = 0.0f;
}

if((speed<0.0f) || (speed==0.0f)) {
t_f = 0.0f;
need_accl = false;
return;
}

t_f++;
}
}

static final int NONE = 0;
static final int DRAG = 1;
int mode = NONE;
PointF nowp = new PointF();
PointF downp = new PointF();
float speed,t_f;
boolean isadd;
boolean need_accl = false;
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
mode = DRAG;
speed = 0.0f;
need_accl = false;
downp.set(0.0f, event.getY());
setBackup();
break;

case MotionEvent.ACTION_UP:
mode = NONE;
if(speed>0.0f) isadd = true;
else { isadd = false; speed = -speed;}

t_f = 0.0f;
need_accl = true;
break;

case MotionEvent.ACTION_MOVE:
if (mode == DRAG) {
speed = event.getY() - downp.y;
nowp.y += speed;

float top = BookView.this.getHeight()-row*rowheight;
if(nowp.y>0) {
nowp.y=0;
speed = 0.0f;
} else if(nowp.y<top) {
nowp.y = top;
speed = 0.0f;
}

downp.set(0.0f, event.getY());
}
break;
}

return true;
}

public void setBackup() {
//设置backup的matrix
Matrix matrix = new Matrix();
matrix.postTranslate(0, nowp.y);
d.a_main.get().iv_backup.setImageMatrix(matrix);
}
}


 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: