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

因为各种问题没解决而中断,暂时记录下来,方便日后有用的时候查看。代码中涉及到分辨率配饰问题,涉及到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);
	}
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值