zoukankan      html  css  js  c++  java
  • MapUnit单元格源代码

    package cjz.project.maptry4;

    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Matrix;
    import android.graphics.Paint;
    import android.graphics.Rect;
    import android.graphics.RectF;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.view.ViewGroup;
    import android.widget.FrameLayout;
    import android.widget.ImageView;

    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.nio.ByteBuffer;
    import java.util.Random;

    /**
    * Created by cjz on 2019/4/30.
    */

    public class MapUnit extends ImageView {

    private int beforeTag[] = new int[]{Integer.MIN_VALUE, Integer.MIN_VALUE};

    /**状态位:判断是否需要刷新**/
    public boolean isNeedRefresh = false;

    private Bitmap tempBitmap = null;
    private Bitmap bm = null;

    /**默认保存缓存图的路径**/
    private String cachePath = "";

    public Bitmap cacheBitmap;
    private Bitmap newBitmap;

    /**开启debug界面**/
    private boolean isDebug = true;
    private byte[] readPixels;
    private int mWidth, mHeight;

    /**
    * 是否初始化完成
    **/
    private boolean isInitFinished = false;

    public MapUnit(Context context) {
    super(context);
    init();
    }

    public MapUnit(Context context, AttributeSet attrs) {
    super(context, attrs);
    init();
    }

    public MapUnit(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    init();
    }

    private void init(){
    cachePath = getContext().getFilesDir().getAbsolutePath() /*+ File.separator + pos[0] + File.separator + pos[1]*/;
    //Log.i("缓存路径", cachePath);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    int width = MeasureSpec.getSize(widthMeasureSpec);
    int height = MeasureSpec.getSize(heightMeasureSpec);
    // if(width > 0 && height > 0){
    mWidth = width;
    mHeight = height;
    // }
    // if(getWidth() > 0 && getHeight() > 0){
    // isInitFinished = true;
    // Log.i("初始化完成","asdasdasd");
    // }
    }

    @Override
    public void setLayoutParams(ViewGroup.LayoutParams params) {
    if(mWidth == 0 && mHeight == 0){
    mWidth = params.width;
    mHeight = params.height;
    }
    //Log.i("长度宽度setLayoutParams", String.format("mWidth : %d, mHeight : %d", mWidth, mHeight));
    super.setLayoutParams(params);
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
    super.onLayout(changed, left, top, right, bottom);
    }

    /**读取该单元格对应的Bitmap**/
    private Bitmap readUnitBitmap(){
    File file = new File(cachePath);
    if(file.exists()){
    try {
    FileInputStream fileInputStream = new FileInputStream(file);
    // if(!isInitFinished){
    // if (mWidth == 0 || mHeight == 0) {
    // Log.i("长度宽度异常", "");
    // return null;
    // } else {
    // isInitFinished = true;
    // }
    // } else {
    if (mWidth <= 0 || mHeight <= 0) {
    Log.i("长度宽度异常", "");
    return null;
    }
    // }
    Bitmap unitPixelBitmap = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888);
    if(readPixels == null){
    readPixels = new byte[fileInputStream.available()];
    } else if(readPixels.length < fileInputStream.available()){
    readPixels = new byte[fileInputStream.available()];
    }
    fileInputStream.read(readPixels);
    unitPixelBitmap.copyPixelsFromBuffer(ByteBuffer.wrap(readPixels));
    fileInputStream.close();
    //Log.i("正常返回图片", "");
    return unitPixelBitmap;
    } catch (FileNotFoundException e) {
    Log.i("读图出错了", "读图出错了0");
    e.printStackTrace();
    } catch (IOException e) {
    Log.i("读图出错了", "读图出错了1");
    e.printStackTrace();
    }
    }
    return null;
    }

    // /**读取该单元格对应的Bitmap**/
    // private Bitmap readUnitBitmap2(){
    // File file = new File(cachePath);
    // if(file.exists()){
    // try {
    // FileInputStream fileInputStream = new FileInputStream(file);
    // if (getWidth() == 0 || getHeight() == 0) {
    // Log.i("长度宽度异常", "");
    // return null;
    // }
    // Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
    // if(readPixels == null){
    // readPixels = new byte[fileInputStream.available()];
    // } else if(readPixels.length < fileInputStream.available()){
    // readPixels = new byte[fileInputStream.available()];
    // }
    // fileInputStream.read(readPixels);
    // bitmap.copyPixelsFromBuffer(ByteBuffer.wrap(readPixels));
    // fileInputStream.close();
    // //Log.i("正常返回图片", "");
    // return bitmap;
    // } catch (FileNotFoundException e) {
    // e.printStackTrace();
    // } catch (IOException e) {
    // e.printStackTrace();
    // }
    // }
    // return null;
    // }

    /**换坐标之前保存该单元格对应的Bitmap**/
    private void saveUnitBitmap(){
    File file = new File(cachePath);
    try {
    if (!file.exists()) {
    file.createNewFile();
    }
    FileOutputStream fileOutputStream = new FileOutputStream(file);
    Bitmap cacheBitmap = this.cacheBitmap;
    if(cacheBitmap == null){
    buildDrawingCache();
    cacheBitmap = getDrawingCache();
    }
    byte pixels[] = new byte[cacheBitmap.getWidth() * cacheBitmap.getHeight() * 4];
    cacheBitmap.copyPixelsToBuffer(ByteBuffer.wrap(pixels));
    fileOutputStream.write(pixels);
    fileOutputStream.close();
    } catch (FileNotFoundException e) {
    e.printStackTrace();
    } catch (IOException e) {
    e.printStackTrace();
    }
    }


    public void setCachePath(String cachePath){
    this.cachePath = cachePath;
    }

    @Override
    public void setTag(Object tag) {
    super.setTag(tag);
    //设置标签的同时创建缓存文件夹和缓存文件
    int pos[] = (int[]) tag;
    File file = new File(getContext().getFilesDir().getAbsolutePath() + File.separator + pos[0]);
    if(!file.exists()){
    file.mkdir();
    }
    file = new File(getContext().getFilesDir().getAbsolutePath() + File.separator + pos[0] + File.separator + pos[1]);
    if(!file.exists()){
    file.mkdir();
    }
    cachePath = getContext().getFilesDir().getAbsolutePath() + File.separator + pos[0] + File.separator + pos[1] + File.separator + "unit.dat";
    // Log.i("缓存路径", cachePath);
    //用Tag对应图片刷新Unit
    if(pos[0] != beforeTag[0] || pos[1] != beforeTag[1]){
    Bitmap bitmap = readUnitBitmap();
    if(bitmap != null){
    //Log.i("刷新图片", "refreshBitmap:" + cachePath);
    setImageBitmap(bitmap);
    } else {
    Log.i("刷新图片", "refreshNull:" + cachePath);
    setImageBitmap(null);
    }
    }
    beforeTag[0] = pos[0];
    beforeTag[1] = pos[1];
    }

    @Override
    public void setImageBitmap(Bitmap bm) {
    super.setImageBitmap(bm);
    if(this.bm != null){
    this.bm.recycle();
    this.bm = null;
    }
    this.bm = bm;
    }

    /**绘制图片**/
    public void drawBitmap(Bitmap bitmap){
    //先读取本Unit对应的Tag对应的文件夹是否有图片,有的话需要现在的图叠加起来
    // if(cacheBitmap != null && !cacheBitmap.isRecycled()){
    // cacheBitmap.recycle();
    // cacheBitmap = null;
    // }
    // if(newBitmap != null && !newBitmap.isRecycled()){
    // newBitmap.recycle();
    // newBitmap = null;
    // }
    // System.gc();
    cacheBitmap = readUnitBitmap();
    if(cacheBitmap == null){
    cacheBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
    }
    Canvas canvas = new Canvas(cacheBitmap);
    if(bitmap != null && !bitmap.isRecycled()){
    FrameLayout parent = (FrameLayout) getParent();
    //获取本控件在屏幕可见区域对应的位图像素,并制作成Bitmap显示
    Rect targetRect = new Rect(0, 0, 0, 0);
    //计算本Unit需要截取父控件固定画布Bitmap的范围Start:
    if (getX() + (1 - getScaleX()) / 2 * getWidth() < parent.getLeft()) { //左边缘小于0
    targetRect.left = parent.getLeft();
    } else {
    targetRect.left = (int)(getX() + (1 - getScaleX()) / 2 * getWidth());
    }

    if (getX() + (1 - getScaleX()) / 2 * getWidth() + getWidth() * getScaleX() > parent.getRight()) { //单元的右边缘大于父控件右边缘
    targetRect.right = parent.getRight();
    } else {
    targetRect.right = (int)(getX() + (1 - getScaleX()) / 2 * getWidth() + getWidth() * getScaleX());
    }

    if (getY() + (1 - getScaleY()) / 2 * getHeight() < parent.getTop()) {
    targetRect.top = parent.getTop();
    } else {
    targetRect.top = (int)(getY() + (1 - getScaleY()) / 2 * getHeight());
    }

    if (getY() + (1 - getScaleY()) / 2 * getHeight() + getHeight() * getScaleY() > parent.getBottom()) {
    targetRect.bottom = parent.getBottom();
    } else {
    targetRect.bottom = (int)(getY() + (1 - getScaleY()) / 2 * getHeight() + getHeight() * getScaleY());
    }

    if(targetRect.width() <= 0 || targetRect.height() <= 0){
    return;
    }
    //计算本Unit需要截取父控件固定画布Bitmap的范围End;
    //生成位图
    int pixels[] = new int[targetRect.width() * targetRect.height()];
    if(targetRect.right > bitmap.getWidth()){
    targetRect.right = bitmap.getWidth();
    }
    if(targetRect.bottom > bitmap.getHeight()){
    targetRect.bottom = bitmap.getHeight();
    }
    bitmap.getPixels(pixels, 0, targetRect.width(), targetRect.left, targetRect.top, targetRect.width(), targetRect.height());
    newBitmap = Bitmap.createBitmap(pixels, targetRect.width(), targetRect.height(), Bitmap.Config.ARGB_8888);
    Log.i("显示范围", targetRect.toString());
    //由于Unit无论缩放之后视觉大小多大,初始大小依然是满屏的,所以切出来的屏幕画布一部分的像素块,无法铺满Unit,需要对像素块拉伸:
    setScaleType(ScaleType.MATRIX);
    Matrix matrix = new Matrix();
    //如果Unit的做边框在父控件左侧外面,则需要把像素块移动到Unit可见区域的骑士位置再拉伸。所以这里计算左边框要偏移多少
    float dx = 0;
    float dy = 0;
    if(getX() + (1 - getScaleX()) / 2 * getWidth() < 0){
    dx = -(getX() + (1 - getScaleX()) / 2 * getWidth()) / getScaleX(); //左偏了多少,图片就要右偏多少,而且即使格子缩小了也只是视觉上缩少了,格子的像素量不变,所以截出来的图的坐标还要反向放大进行偏移
    }
    if(getY() + (1 - getScaleY()) / 2 * getHeight() < 0){
    dy = -(getY() + (1 - getScaleY()) / 2 * getHeight()) / getScaleY();
    }
    matrix.postTranslate(dx, dy);
    //之前的步骤计算了图片覆盖的左起点和顶起点,现在计算图片覆盖的右终点和底终点
    float parentWidth = ((FrameLayout) getParent()).getRight(); //父控件右边终点
    float parentHeight = ((FrameLayout) getParent()).getBottom();

    float unitRightBoarder = (getX() + (1 - getScaleX()) / 2 * getWidth() + getWidth() * getScaleX()); //本Unit在屏幕实际的右边界位置
    /**如果Unit右边界位置超出父控件右边界,则“Unit可见区域右边界 = 父控件右边界 - Unit实际可见左边界”并反向放大至和图片等效比例尺。
    /否则直接用Unit真实右边界**/
    float rightBoarder = unitRightBoarder > parentWidth ?
    (parentWidth - (getX() + (1 - getScaleX()) / 2 * getWidth())) / getScaleX() :
    getWidth() ;//右边框
    //原理同上
    float unitBottomBoarder = (getY() + (1 - getScaleY()) / 2 * getHeight() + getHeight() * getScaleY());
    float bottomBoarder = unitBottomBoarder > parentHeight ?
    (parentHeight - (getY() + (1 - getScaleY()) / 2 * getHeight())) / getScaleY(): //(屏幕边界 - View实际起始边界) / 缩放率 反向放大
    getHeight() ;
    //图片在Unit中实际应显示范围
    RectF visibleRect = new RectF(dx, dy, rightBoarder, bottomBoarder);
    //以实际应显示范围的左上角作为缩放中心,长、宽分别除以像素块的长、宽,得到像素块应该拉伸或者收缩的比例:
    matrix.postScale(visibleRect.width() / newBitmap.getWidth(), visibleRect.height() / newBitmap.getHeight(), dx, dy);
    canvas.drawBitmap(newBitmap, matrix, null);
    setImageBitmap(cacheBitmap);
    // setImageMatrix(matrix);
    //保存本次绘图
    saveUnitBitmap();
    } else {
    setImageBitmap(cacheBitmap);
    }
    }

    //todo x作为一级文件夹,y作为二级文件夹,然后分别放对应(x,y)的bitmap文件
    @Override
    protected void onDraw(Canvas canvas) {
    //传入的是空白的canvas,因此绘制过的内容并不能不断叠加
    super.onDraw(canvas);
    if(isDebug){
    drawTest(canvas);
    }
    }

    private void drawTest(Canvas canvas){
    Random random = new Random();
    //Log.i("onDraw", hashCode() + "");
    Paint paint = new Paint();
    paint.setStrokeWidth(8f);
    // paint.setColor((0xFF000000 | (random.nextInt(255) & 0xFF) << 16 | (random.nextInt(255) & 0xFF) << 8 | (random.nextInt(255) & 0xFF)));
    paint.setColor(Color.GRAY);
    paint.setStyle(Paint.Style.STROKE);
    //绘制背景
    canvas.drawRect(0, 0, getWidth(), getHeight(), paint);
    Paint paintPen = new Paint();
    paintPen.setStrokeWidth(4f);
    paintPen.setStyle(Paint.Style.FILL);
    paintPen.setColor(Color.RED);
    paintPen.setTextSize(32f);
    paintPen.setAntiAlias(true);
    //绘制自己是第几列第几行的单元
    if(getTag() != null) {
    int position[] = (int[]) getTag();
    canvas.drawText(String.format("UnitX: %d, UnitY: %d", position[0], position[1]), getWidth() / 2 - 100, getHeight() / 2, paintPen);
    }

    //绘制边界点
    paint.setColor(Color.BLUE);
    canvas.drawPoint(0, 0, paint);
    canvas.drawPoint(0, getHeight(), paint);
    canvas.drawPoint(getWidth(), 0, paint);
    canvas.drawPoint(getWidth(), getHeight(http://www.amjmh.com/v/BIBRGZ_558768/), paint);

    // paint.setColor(Color.WHITE);
    // Path path = new Path();
    // path.moveTo(0, 0);
    // path.lineTo(getWidth(), getHeight());
    // canvas.drawPath(path, paint);
    }
    }

  • 相关阅读:
    IOS6.0 应用内直接下载程序 不需跳转AppStore
    维护Product
    CRM Service summary 1
    "No update of sales order X from purchase order (error V1 154)."
    Organizational Management
    懂PMP的好处
    Buying Center
    更新
    Business Partner定义,以及与Account的区分
    Fact Sheet
  • 原文地址:https://www.cnblogs.com/hyhy904/p/11373122.html
Copyright © 2011-2022 走看看