Android游戏闯关模式View-(2)

1.前言

    在上次对游戏闯关模式进行一次简单的逻辑梳理,利用的是GridView经行实现,这几天有空闲时间对这个控件进行了逻辑代码的重叠性的重新构造,然后考虑进行View的自定义编写,此次主要需要用到的是圆角矩形、圆角头像、圆形图像花边,倒三角形、字体的绘制,然后解决一个简单的点击事件的监听。(项目地址:https://gitee.com/relin/GameStage.git)


2.用到的知识点 

(1)圆角矩形的绘制

    /**
     * Draw the rounded rectangle item.
     *
     * @param canvas
     */
    private void drawRoundRect(Canvas canvas) {
        paint = new Paint();
        paint.setColor(itemCountRecord <= nowPosition ? itemNormalBackgroundColor : itemLockBackgroundColor);
        RectF rectF = new RectF();
        rectF.left = paddingLeft + itemHorizontalMove;
        rectF.right = rectF.left + itemWidth;
        rectF.top = paddingTop + itemVerticalMove;
        rectF.bottom = rectF.top + itemHeight;
        canvas.drawRoundRect(rectF, 16, 16, paint);
        //item坐标记录
        itemCoordinates.put(itemCountRecord + "", rectF.left + "," + rectF.top + "&" + rectF.right + "," + rectF.bottom);
    }

(2)字体的绘制

    /**
     * Draw the round corner font item.
     *
     * @param canvas
     * @param text
     */
    private void drawRoundRectText(Canvas canvas, String text) {
        paint = new Paint();
        paint.setColor(itemCountRecord <= nowPosition ? textNormalColor : textLockColor);
        paint.setTextSize(textSize);

        Rect rect = new Rect();
        paint.getTextBounds(text, 0, text.length(), rect);
        int textWidth = rect.width();
        int textHeight = rect.height();
        canvas.drawText(text, paddingLeft + itemHorizontalMove + itemWidth / 2 - textWidth / 2, paddingTop + itemVerticalMove + (itemHeight - textHeight / 2), paint);
    }

(3)圆角头像的绘制

    /**
     * Generate round images
     *
     * @return round image bitmap
     */
    private Bitmap drawCircleHead() {
        paint = new Paint();
        Bitmap output = Bitmap.createBitmap(headSize, headSize, Bitmap.Config.ARGB_8888);
        Canvas headCanvas = new Canvas(output);
        paint.setAntiAlias(true);
        headCanvas.drawARGB(0, 0, 0, 0);
        paint.setColor(headCircleColor);
        //圆圈
        headCanvas.drawCircle(headSize / 2, headSize / 2, headSize / 2, paint);
        //设置重叠模式
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        //矩形范围
        Rect rect = new Rect(0, 0, headSize, headSize);
        Bitmap bitmap = headBitmap != null ? headBitmap : BitmapFactory.decodeResource(getResources(), itemHeadSrc);
        headCanvas.drawBitmap(bitmap, rect, rect, paint);
        //对大图进行缩放
        Matrix matrix = new Matrix();
        float sx = headSize / bitmapWidthHeight(R.mipmap.ic_head_girl)[0];
        float sy = headSize / bitmapWidthHeight(R.mipmap.ic_head_girl)[1];
        matrix.setScale(sx, sy, 0, 0);
        headCanvas.drawBitmap(bitmap, matrix, paint);
        //重置画笔
        paint.reset();
        return output;
    }

(4)倒三角形的绘制

    /**
     * Draw the triangle
     *
     * @param canvas
     * @param headXmove head of item x move
     * @param headYmove item of item y move
     */
    private void drawTriangle(Canvas canvas, int headXmove, int headYmove) {
        Paint paint = new Paint();
        paint.setColor(triangleColor);
        paint.setAntiAlias(true);
        Path path = new Path();
        path.moveTo(headSize / 5 * 2 + headXmove, headSize + headArrowPaddingTop + headYmove);// 此点为多边形的起点
        path.lineTo(headSize / 5 * 3 + headXmove, headSize + headArrowPaddingTop + headYmove);// 此点为多边形的起点
        path.lineTo(headSize / 10 * 5 + headXmove, headSize + headSize / 5 + headArrowPaddingTop + headYmove);
        path.close(); // 使这些点构成封闭的多边形
        canvas.drawPath(path, paint);
    }

(5)分割线的绘制

    /**
     * Draw the horizontal divider
     *
     * @param canvas
     */
    private void drawHorizontalDivider(Canvas canvas) {
        //每行最后一个不再需要在右边的分割线
        if (linePosition % lineColumns == 0 || (nowRow == totalRow && linePosition == modNum)) {
            return;
        }
        paint = new Paint();
        paint.setColor(itemCountRecord <= nowPosition ? itemNormalBackgroundColor : itemLockBackgroundColor);
        Rect rect = new Rect();
        rect.left = paddingLeft + itemWidth + itemHorizontalMove;
        rect.right = rect.left + dividerHorizontalWidth;
        rect.top = paddingTop + itemHeight / 2 - dividerHorizontalHeight / 2 + itemVerticalMove;
        rect.bottom = rect.top + dividerHorizontalHeight;
        canvas.drawRect(rect, paint);
    }

    /**
     * Draw the vertical divider
     *
     * @param canvas
     */
    private void drawVerticalDivider(Canvas canvas) {
        //基数行最后一个Item显示,偶数行第一个Item显示,数据的最后一个不显示
        if ((nowRow % 2 == 0 && linePosition == 1) || (nowRow % 2 != 0 && linePosition == lineColumns)) {
            if (itemCountRecord == totalColumns) {
                return;
            }
            paint = new Paint();
            paint.setColor(itemCountRecord <= nowPosition ? itemNormalBackgroundColor : itemLockBackgroundColor);
            Rect rect = new Rect();
            rect.left = paddingLeft + itemWidth / 2 - dividerHorizontalHeight / 2 + itemHorizontalMove;
            rect.right = rect.left + dividerVerticalWidth;
            rect.top = paddingTop + itemHeight + itemVerticalMove;
            rect.bottom = rect.top + dividerVerticalHeight;
            canvas.drawRect(rect, paint);
        }
    }

(6)圆角图像外边框绘制

    /**
     * Round head edge.
     *
     * @param canvas
     * @param headXmove head of item x move
     * @param headYmove item of item y move
     */
    private void drawCircleStroke(Canvas canvas, int headXmove, int headYmove) {
        Paint paint = new Paint();
        paint.setAntiAlias(true);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(headStrokeWidth);
        paint.setColor(headStrokeColor);
        canvas.drawCircle(headSize / 2 + headXmove, headSize / 2 + headYmove, headSize / 2, paint);
        paint.reset();
    }

3.attrs.xml设计

 <!-- GameStageView-->
    <declare-styleable name="GameStageView">
        <attr name="itemWidth" format="dimension" />
        <attr name="itemHeight" format="dimension" />
        <attr name="itemTextSize" format="dimension" />
        <attr name="itemDividerColor" format="color" />

        <attr name="itemDividerHorizontalWidth" format="dimension" />
        <attr name="itemDividerHorizontalHeight" format="dimension" />
        <attr name="itemDividerVerticalWidth" format="dimension" />
        <attr name="itemDividerVerticalHeight" format="dimension" />

        <attr name="totalColumns" format="integer" />
        <attr name="lineColumns" format="integer" />
        <attr name="nowPosition" format="integer" />

        <attr name="itemNormalTextColor" format="color" />
        <attr name="itemLockTextColor" format="color" />
        <attr name="itemNormalBgColor" format="color" />
        <attr name="itemLockBgColor" format="color" />

        <attr name="InnerPaddingLeft" format="dimension" />
        <attr name="InnerPaddingTop" format="dimension" />
        <attr name="InnerPaddingRight" format="dimension" />

        <attr name="itemHeadSrc" format="reference" />
        <attr name="itemHeadSize" format="dimension" />
        <attr name="itemHeadStrokeColor" format="color" />
        <attr name="itemHeadStrokeWidth" format="dimension" />
        <attr name="itemHeadArrowColor" format="color" />
        <attr name="itemHeadArrowTopPadding" format="dimension" />
    </declare-styleable>

4.控件源代码

import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by Relin on 2018/5/7.
 * Game break mode control.
 */

public class GameStageView extends View {

    /**
     * Item's brush tool.
     */
    private Paint paint;
    /**
     * Item Normal background color
     */
    private int itemNormalBackgroundColor = Color.parseColor("#3BD2B3");
    /**
     * Item lock background color
     */
    private int itemLockBackgroundColor = Color.parseColor("#DDDDDD");

    /**
     * Item triangle background color
     */
    private int triangleColor = Color.parseColor("#3BD2B3");

    /**
     * View the left margin
     */
    private int paddingLeft = (int) dpToPx(15);
    /**
     * View the top padding
     */
    private int paddingTop = (int) dpToPx(40);

    /**
     * View the top padding right
     */
    private int paddingRight = (int) dpToPx(15);

    /**
     * Height of the item
     */
    private int itemHeight = (int) dpToPx(20);
    ;
    /**
     * Width of the item
     */
    private int itemWidth = (int) dpToPx(50);
    /**
     * The font size
     */
    private int textSize = (int) dpToPx(12);
    /**
     * Normal font color
     */
    private int textNormalColor = Color.parseColor("#FFFFFF");
    /**
     * Lock font color
     */
    private int textLockColor = Color.parseColor("#FFFFFF");

    /**
     * Dividing line width.
     */
    private int dividerHorizontalWidth = (int) dpToPx(10);
    /**
     * Dividing line height.
     */
    private int dividerHorizontalHeight = (int) dpToPx(5);

    /**
     * Dividing line width.
     */
    private int dividerVerticalWidth = (int) dpToPx(5);
    /**
     * Dividing line height.
     */
    private int dividerVerticalHeight = (int) dpToPx(50);

    /**
     * The total number of item records
     */
    private int itemCountRecord = 1;
    /**
     * Item to move the distance.
     */
    private int itemHorizontalMove = 0;
    /**
     * Item to move the distance.
     */
    private int itemVerticalMove = 0;
    /**
     * The number of items per line.
     */
    private int lineColumns = 5;

    /**
     * The total number of items
     */
    private int totalColumns = 40;

    /**
     * he background color of the original head.
     */
    private int headCircleColor = Color.parseColor("#FFFFFF");

    /**
     * Head size
     */
    private int headSize = 80;
    /**
     * Head down arrow top padding
     */
    private int headArrowPaddingTop = 5;
    /**
     * Now you need to show it.
     */
    private int nowPosition = 1;

    /**
     * Border color
     */
    private int headStrokeColor = Color.parseColor("#DDDDDD");

    /**
     * Head of stroke width
     */
    private int headStrokeWidth = 8;

    /**
     * The row is total of items mod linePosition equal 0
     */
    private int fullRow;

    /**
     * The remainder of a dissatisfied row.
     */
    private int modNum;

    /**
     * Now row
     */
    private int nowRow;

    /**
     * The total row
     */
    private int totalRow;

    /**
     * Number of rows
     */
    private int linePosition = 0;

    /**
     * Items canvas
     */
    private Canvas canvas;

    /**
     * Item coordinates records
     */
    private Map<String, String> itemCoordinates;

    /**
     * Head coordinates records
     */
    private Map<String, String> headCoordinates;

    private int itemHeadSrc = R.mipmap.ic_launcher;

    private Bitmap headBitmap;


    public GameStageView(Context context) {
        super(context);
        init(context, null, 0);
    }

    public GameStageView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs, 0);
    }

    public GameStageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs, defStyleAttr);
    }

    public GameStageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init(context, attrs, defStyleAttr);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:

                break;
            case MotionEvent.ACTION_UP:
                float x = event.getX();
                float y = event.getY();
                //item 点击事件
                for (Map.Entry<String, String> entry : itemCoordinates.entrySet()) {
                    String key = entry.getKey();
                    String value = entry.getValue();
                    String coordinateStart[] = value.split("&")[0].split(",");
                    String coordinateEnd[] = value.split("&")[1].split(",");
                    if (Float.parseFloat(coordinateStart[0]) <= x && x <= Float.parseFloat(coordinateEnd[0]) && Float.parseFloat(coordinateStart[1]) <= y && y <= Float.parseFloat(coordinateEnd[1])) {
                        if (onGameItemClickListener != null) {
                            onGameItemClickListener.onGameItemClick((Integer.parseInt(key)), itemCountRecord <= nowPosition ? false : true);
                        }
                    }
                }
                //头像点击事件
                for (Map.Entry<String, String> entry : headCoordinates.entrySet()) {
                    String key = entry.getKey();
                    String value = entry.getValue();
                    String coordinateStart[] = value.split("&")[0].split(",");
                    String coordinateEnd[] = value.split("&")[1].split(",");
                    Log.e(this.getClass().getSimpleName(), "coordinateStart:" + coordinateStart[0] + "," + coordinateStart[1] + ",coordinateEnd:" + coordinateEnd[0] + "," + coordinateEnd[1]);
                    if (Float.parseFloat(coordinateStart[0]) <= x && x <= Float.parseFloat(coordinateEnd[0]) && Float.parseFloat(coordinateStart[1]) <= y && y <= Float.parseFloat(coordinateEnd[1])) {
                        if (onGameHeadClickListener != null) {
                            onGameHeadClickListener.onGameHeadClick((Integer.parseInt(key)), itemCountRecord <= nowPosition ? false : true);
                        }
                    }
                }
                break;
        }
        return true;
    }

    /**
     * Initializes the coordinate record and control properties.
     * @param context
     * @param attrs
     * @param defStyleAttr
     */
    private void init(Context context, AttributeSet attrs, int defStyleAttr) {
        itemCoordinates = new HashMap<>();
        headCoordinates = new HashMap<>();
        if (attrs !=null) {
            TypedArray array = context.getTheme().obtainStyledAttributes(attrs, R.styleable.GameStageView, defStyleAttr, 0);
            itemWidth = (int) array.getDimension(R.styleable.GameStageView_itemWidth, itemWidth);
            itemHeight = (int) array.getDimension(R.styleable.GameStageView_itemHeight, itemHeight);

            dividerHorizontalWidth = (int) array.getDimension(R.styleable.GameStageView_itemDividerHorizontalWidth, dividerHorizontalWidth);
            dividerHorizontalHeight = (int) array.getDimension(R.styleable.GameStageView_itemDividerHorizontalHeight, dividerHorizontalHeight);
            dividerVerticalWidth = (int) array.getDimension(R.styleable.GameStageView_itemDividerVerticalWidth, dividerVerticalWidth);
            dividerVerticalHeight = (int) array.getDimension(R.styleable.GameStageView_itemDividerVerticalHeight, dividerVerticalHeight);

            totalColumns =  array.getInt(R.styleable.GameStageView_totalColumns, totalColumns);
            lineColumns = array.getInt(R.styleable.GameStageView_lineColumns, lineColumns);
            nowPosition = array.getInt(R.styleable.GameStageView_nowPosition, nowPosition);

            textSize = (int) array.getDimension(R.styleable.GameStageView_itemTextSize, textSize);
            textNormalColor = array.getColor(R.styleable.GameStageView_itemNormalTextColor, textNormalColor);
            textLockColor = array.getColor(R.styleable.GameStageView_itemLockTextColor, textLockColor);
            itemNormalBackgroundColor = array.getColor(R.styleable.GameStageView_itemNormalBgColor, itemNormalBackgroundColor);
            itemLockBackgroundColor = array.getColor(R.styleable.GameStageView_itemLockBgColor, itemLockBackgroundColor);
            paddingLeft = (int) array.getDimension(R.styleable.GameStageView_InnerPaddingLeft, paddingLeft);
            paddingTop = (int) array.getDimension(R.styleable.GameStageView_InnerPaddingTop, paddingTop);
            paddingRight = (int) array.getDimension(R.styleable.GameStageView_InnerPaddingRight, paddingRight);
            headSize = (int) array.getDimension(R.styleable.GameStageView_itemHeadSize, headSize);
            headStrokeColor = array.getColor(R.styleable.GameStageView_itemHeadStrokeColor, headStrokeColor);
            headStrokeWidth = (int) array.getDimension(R.styleable.GameStageView_itemHeadStrokeWidth, headStrokeWidth);
            triangleColor = array.getColor(R.styleable.GameStageView_itemHeadArrowColor, triangleColor);
            headArrowPaddingTop = (int) array.getDimension(R.styleable.GameStageView_itemHeadArrowTopPadding, headArrowPaddingTop);
            itemHeadSrc = array.getResourceId(R.styleable.GameStageView_itemHeadSrc, itemHeadSrc);
            array.recycle();
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        this.canvas = canvas;
        fullRow = totalColumns / lineColumns;
        modNum = totalColumns % lineColumns;
        totalRow = fullRow + (modNum == 0 ? 0 : 1);
        dividerHorizontalWidth = (getScreenWidth() - paddingLeft - paddingRight - itemWidth * lineColumns) / (lineColumns - 1);
        for (int row = 1; row <= totalRow; row++) {
            nowRow = row;
            itemVerticalMove = (row - 1) * (dividerVerticalHeight + itemHeight);
            int nowLineColumns = lineColumns;
            if (row <= fullRow) {
                nowLineColumns = lineColumns;
            } else {
                if (modNum != 0) {
                    nowLineColumns = modNum;
                }
            }
            if (row % 2 != 0) {
                for (int line = 1; line <= nowLineColumns; line++) {
                    linePosition = line;
                    itemCountRecord = (row - 1) * lineColumns + line;
                    itemHorizontalMove = (line - 1) * (itemWidth + dividerHorizontalWidth);
                    String text = itemCountRecord <= nowPosition ? "第" + itemCountRecord + "关" : "未解锁";
                    drawItems(text);
                }
            } else {
                nowLineColumns = nowLineColumns == lineColumns ? 1 : nowLineColumns;
                for (int line = lineColumns; line >= nowLineColumns; line--) {
                    linePosition = line;
//                  itemCountRecord = (row - 1) * lineColumns + line;//倒数下标
                    itemCountRecord = (nowRow * lineColumns - line + 1);
                    itemHorizontalMove = (lineColumns - (lineColumns - line) - 1) * (itemWidth + dividerHorizontalWidth);
                    String text = itemCountRecord <= nowPosition ? "第" + (nowRow * lineColumns - line + 1) + "关" : "未解锁";
                    drawItems(text);
                }
            }
            Log.e(this.getClass().getSimpleName(), "itemVerticalMove:" + itemVerticalMove);
        }
    }

    /**
     * Let me draw all the items
     *
     * @param text item text
     */
    private void drawItems(String text) {
        drawRoundRect(canvas);
        drawRoundRectText(canvas, text);
        drawHorizontalDivider(canvas);
        drawVerticalDivider(canvas);
        drawHeads(canvas);
    }

    /**
     * Draw the rounded rectangle item.
     *
     * @param canvas
     */
    private void drawRoundRect(Canvas canvas) {
        paint = new Paint();
        paint.setColor(itemCountRecord <= nowPosition ? itemNormalBackgroundColor : itemLockBackgroundColor);
        RectF rectF = new RectF();
        rectF.left = paddingLeft + itemHorizontalMove;
        rectF.right = rectF.left + itemWidth;
        rectF.top = paddingTop + itemVerticalMove;
        rectF.bottom = rectF.top + itemHeight;
        canvas.drawRoundRect(rectF, 16, 16, paint);
        //item坐标记录
        itemCoordinates.put(itemCountRecord + "", rectF.left + "," + rectF.top + "&" + rectF.right + "," + rectF.bottom);
    }

    /**
     * Draw the round corner font item.
     *
     * @param canvas
     * @param text
     */
    private void drawRoundRectText(Canvas canvas, String text) {
        paint = new Paint();
        paint.setColor(itemCountRecord <= nowPosition ? textNormalColor : textLockColor);
        paint.setTextSize(textSize);

        Rect rect = new Rect();
        paint.getTextBounds(text, 0, text.length(), rect);
        int textWidth = rect.width();
        int textHeight = rect.height();
        canvas.drawText(text, paddingLeft + itemHorizontalMove + itemWidth / 2 - textWidth / 2, paddingTop + itemVerticalMove + (itemHeight - textHeight / 2), paint);
    }

    /**
     * Draw the horizontal divider
     *
     * @param canvas
     */
    private void drawHorizontalDivider(Canvas canvas) {
        //每行最后一个不再需要在右边的分割线
        if (linePosition % lineColumns == 0 || (nowRow == totalRow && linePosition == modNum)) {
            return;
        }
        paint = new Paint();
        paint.setColor(itemCountRecord <= nowPosition ? itemNormalBackgroundColor : itemLockBackgroundColor);
        Rect rect = new Rect();
        rect.left = paddingLeft + itemWidth + itemHorizontalMove;
        rect.right = rect.left + dividerHorizontalWidth;
        rect.top = paddingTop + itemHeight / 2 - dividerHorizontalHeight / 2 + itemVerticalMove;
        rect.bottom = rect.top + dividerHorizontalHeight;
        canvas.drawRect(rect, paint);
    }

    /**
     * Draw the vertical divider
     *
     * @param canvas
     */
    private void drawVerticalDivider(Canvas canvas) {
        //基数行最后一个Item显示,偶数行第一个Item显示,数据的最后一个不显示
        if ((nowRow % 2 == 0 && linePosition == 1) || (nowRow % 2 != 0 && linePosition == lineColumns)) {
            if (itemCountRecord == totalColumns) {
                return;
            }
            paint = new Paint();
            paint.setColor(itemCountRecord <= nowPosition ? itemNormalBackgroundColor : itemLockBackgroundColor);
            Rect rect = new Rect();
            rect.left = paddingLeft + itemWidth / 2 - dividerHorizontalHeight / 2 + itemHorizontalMove;
            rect.right = rect.left + dividerVerticalWidth;
            rect.top = paddingTop + itemHeight + itemVerticalMove;
            rect.bottom = rect.top + dividerVerticalHeight;
            canvas.drawRect(rect, paint);
        }
    }

    /**
     * Draw the round picture in the head view,
     * the round border of the picture and the inverted triangle.
     *
     * @param canvas
     */
    private void drawHeads(Canvas canvas) {
        if (itemCountRecord != nowPosition) {
            return;
        }
        int headXmove = paddingLeft + headSize / 2 + itemHorizontalMove;
        int headYmove = paddingTop - headSize - headSize / 5 + itemVerticalMove;
        //记录头像坐标范围
        headCoordinates.put(itemCountRecord + "", (headXmove - headSize / 2) + "," + (headYmove - headSize / 2) + "&" + (headXmove + headSize) + "," + (headYmove + headSize));
        paint = new Paint();
        //圆形头像
        Bitmap output = drawCircleHead();
        //画生成的图片
        canvas.drawBitmap(output, headXmove, headYmove, paint);
        //三角形
        drawTriangle(canvas, headXmove, headYmove);
        //边框
        drawCircleStroke(canvas, headXmove, headYmove);
    }

    /**
     * Generate round images
     *
     * @return round image bitmap
     */
    private Bitmap drawCircleHead() {
        paint = new Paint();
        Bitmap output = Bitmap.createBitmap(headSize, headSize, Bitmap.Config.ARGB_8888);
        Canvas headCanvas = new Canvas(output);
        paint.setAntiAlias(true);
        headCanvas.drawARGB(0, 0, 0, 0);
        paint.setColor(headCircleColor);
        //圆圈
        headCanvas.drawCircle(headSize / 2, headSize / 2, headSize / 2, paint);
        //设置重叠模式
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        //矩形范围
        Rect rect = new Rect(0, 0, headSize, headSize);
        Bitmap bitmap = headBitmap != null ? headBitmap : BitmapFactory.decodeResource(getResources(), itemHeadSrc);
        headCanvas.drawBitmap(bitmap, rect, rect, paint);
        //对大图进行缩放
        Matrix matrix = new Matrix();
        float sx = headSize / bitmapWidthHeight(R.mipmap.ic_head_girl)[0];
        float sy = headSize / bitmapWidthHeight(R.mipmap.ic_head_girl)[1];
        matrix.setScale(sx, sy, 0, 0);
        headCanvas.drawBitmap(bitmap, matrix, paint);
        //重置画笔
        paint.reset();
        return output;
    }

    /**
     * Draw the triangle
     *
     * @param canvas
     * @param headXmove head of item x move
     * @param headYmove item of item y move
     */
    private void drawTriangle(Canvas canvas, int headXmove, int headYmove) {
        Paint paint = new Paint();
        paint.setColor(triangleColor);
        paint.setAntiAlias(true);
        Path path = new Path();
        path.moveTo(headSize / 5 * 2 + headXmove, headSize + headArrowPaddingTop + headYmove);// 此点为多边形的起点
        path.lineTo(headSize / 5 * 3 + headXmove, headSize + headArrowPaddingTop + headYmove);// 此点为多边形的起点
        path.lineTo(headSize / 10 * 5 + headXmove, headSize + headSize / 5 + headArrowPaddingTop + headYmove);
        path.close(); // 使这些点构成封闭的多边形
        canvas.drawPath(path, paint);
    }

    /**
     * Round head edge.
     *
     * @param canvas
     * @param headXmove head of item x move
     * @param headYmove item of item y move
     */
    private void drawCircleStroke(Canvas canvas, int headXmove, int headYmove) {
        Paint paint = new Paint();
        paint.setAntiAlias(true);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(headStrokeWidth);
        paint.setColor(headStrokeColor);
        canvas.drawCircle(headSize / 2 + headXmove, headSize / 2 + headYmove, headSize / 2, paint);
        paint.reset();
    }

    /**
     * Get the picture width and height.
     *
     * @param resId
     * @return
     */
    private float[] bitmapWidthHeight(int resId) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeResource(getResources(), resId, options);
        float width = options.outWidth;
        float height = options.outHeight;
        //设置为false,解析Bitmap对象加入到内存中
        options.inJustDecodeBounds = false;
        return new float[]{width, height};
    }

    /**
     * The screen of width.
     *
     * @return
     */
    public static int getScreenWidth() {
        return Resources.getSystem().getDisplayMetrics().widthPixels;
    }

    /**
     * The screen of height.
     *
     * @return
     */
    public static int getScreenHeight() {
        return Resources.getSystem().getDisplayMetrics().heightPixels;
    }

    public void setItemNormalBackgroundColor(int itemNormalBackgroundColor) {
        this.itemNormalBackgroundColor = itemNormalBackgroundColor;
    }

    public void setItemLockBackgroundColor(int itemLockBackgroundColor) {
        this.itemLockBackgroundColor = itemLockBackgroundColor;
    }

    public void setTriangleColor(int triangleColor) {
        this.triangleColor = triangleColor;
    }

    public void setPaddingLeft(int paddingLeft) {
        this.paddingLeft = paddingLeft;
    }

    public void setPaddingTop(int paddingTop) {
        this.paddingTop = paddingTop;
    }

    public void setPaddingRight(int paddingRight) {
        this.paddingRight = paddingRight;
    }

    public void setItemHeight(int itemHeight) {
        this.itemHeight = itemHeight;
    }

    public void setItemWidth(int itemWidth) {
        this.itemWidth = itemWidth;
    }

    public void setTextSize(int textSize) {
        this.textSize = textSize;
    }

    public void setTextNormalColor(int textNormalColor) {
        this.textNormalColor = textNormalColor;
    }

    public void setTextLockColor(int textLockColor) {
        this.textLockColor = textLockColor;
    }

    public void setDividerHorizontalWidth(int dividerHorizontalWidth) {
        this.dividerHorizontalWidth = dividerHorizontalWidth;
    }

    public void setDividerHorizontalHeight(int dividerHorizontalHeight) {
        this.dividerHorizontalHeight = dividerHorizontalHeight;
    }

    public void setDividerVerticalWidth(int dividerVerticalWidth) {
        this.dividerVerticalWidth = dividerVerticalWidth;
    }

    public void setDividerVerticalHeight(int dividerVerticalHeight) {
        this.dividerVerticalHeight = dividerVerticalHeight;
    }

    public void setLineColumns(int lineColumns) {
        this.lineColumns = lineColumns;
    }

    public void setTotalColumns(int totalColumns) {
        this.totalColumns = totalColumns;
    }

    public void setHeadCircleColor(int headCircleColor) {
        this.headCircleColor = headCircleColor;
    }

    public void setHeadSize(int headSize) {
        this.headSize = headSize;
    }

    public void setHeadArrowPaddingTop(int headArrowPaddingTop) {
        this.headArrowPaddingTop = headArrowPaddingTop;
    }

    public void setNowPosition(int nowPosition) {
        this.nowPosition = nowPosition;
    }

    public void setHeadStrokeColor(int headStrokeColor) {
        this.headStrokeColor = headStrokeColor;
    }

    public void setHeadStrokeWidth(int headStrokeWidth) {
        this.headStrokeWidth = headStrokeWidth;
    }

    public void setItemHeadSrc(int itemHeadSrc) {
        this.itemHeadSrc = itemHeadSrc;
    }

    public void setHeadBitmap(Bitmap headBitmap) {
        this.headBitmap = headBitmap;
    }

    /**
     * Px to dp
     *
     * @param px
     * @return
     */
    public static float pxToDp(float px) {
        return px / getScreenDensity();
    }

    /**
     * dp to px
     *
     * @param dp
     * @return
     */
    public static float dpToPx(float dp) {
        return dp * getScreenDensity();
    }


    /**
     * Get the screen of density
     *
     * @return
     */
    public static float getScreenDensity() {
        return Resources.getSystem().getDisplayMetrics().density;
    }

    public OnGameHeadClickListener onGameHeadClickListener;

    /**
     * Set the avatar click to monitor the event.
     *
     * @param onGameHeadClickListener
     */
    public void setOnGameHeadClickListener(OnGameHeadClickListener onGameHeadClickListener) {
        this.onGameHeadClickListener = onGameHeadClickListener;
    }

    /**
     * Head click on the monitor event.
     */
    public interface OnGameHeadClickListener {
        void onGameHeadClick(int position, boolean isLock);
    }

    public OnGameItemClickListener onGameItemClickListener;

    /**
     * Set item to listen for events.
     *
     * @param onGameItemClickListener
     */
    public void setOnGameItemClickListener(OnGameItemClickListener onGameItemClickListener) {
        this.onGameItemClickListener = onGameItemClickListener;
    }

    /**
     * Item click on the listener event.
     */
    public interface OnGameItemClickListener {
        void onGameItemClick(int position, boolean isLock);
    }


}

猜你喜欢

转载自blog.csdn.net/u012127961/article/details/80242974