美文网首页程序员
Android 自定组件(安全键盘)

Android 自定组件(安全键盘)

作者: 菠萝鱼_lc | 来源:发表于2018-01-30 17:35 被阅读0次

常见的安全键盘,随机排列数字,点击状态的回调。

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import router.future.com.testrouter.R;

/**
 * @author luchao
 * @time 18/1/26 上午10:30
 */
public class SafeKeyboard extends View {
    private ItemClickListener itemClickListener;
    private Paint numberPaint;
    private Paint mBgPaint;
    private Paint mLinePaint;
    private int mTextSize;
    private List<String> numberData = new ArrayList<String>() {{
        add("1");
        add("2");
        add("3");
        add("4");
        add("5");
        add("6");
        add("7");
        add("8");
        add("9");
        add("0");
    }};
    private List<RectF> squareList = new ArrayList<>();
    private static final String SPACE = "q";
    private static final String BACK = "d";
    private float squareWidth;
    private float squareHeight;
    private int columnCount = 3;
    private int rowCount;
    private int pressIndex = -1;

    public SafeKeyboard(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.RulerWheel);
        try {
            mTextSize = mTypedArray.getDimensionPixelSize(R.styleable.RulerWheel_text_Size, 80);
        } finally {
            mTypedArray.recycle();
        }
        init();
    }

    private void init() {
        numberPaint = new Paint();
        numberPaint.setColor(Color.BLACK);
        numberPaint.setTextSize(mTextSize);

        mBgPaint = new Paint();
        mBgPaint.setColor(Color.RED);
        mBgPaint.setStyle(Paint.Style.FILL);
        mBgPaint.setAntiAlias(true);

        mLinePaint = new Paint();
        mLinePaint.setColor(Color.BLACK);
        shuffleData();
    }

    /**
     * 组装数据,这里用到一些小技巧.
     */
    public void shuffleData() {
        Collections.shuffle(numberData);
        numberData.add(9, SPACE);
        numberData.add(11, BACK);
        rowCount = getRowCount();
    }

    /**
     * 控制点击背景并返回数据
     * @param event
     * @return
     */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float x = event.getX();
        float y = event.getY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                for(int i = 0; i < squareList.size(); i++) {
                    RectF rectF = squareList.get(i);
                    if(rectF.contains(x, y)) {
                        pressIndex = i;
                        postInvalidate();
                        break;
                    }
                }
                break;
            case MotionEvent.ACTION_MOVE:
                break;
            case MotionEvent.ACTION_UP:
                //返回点击后的数据
                if(itemClickListener != null) {
                    itemClickListener.click(numberData.get(pressIndex));
                }
                pressIndex = -1;
                postInvalidate();
                break;
        }
        return true;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        squareWidth = (float) MeasureSpec.getSize(widthMeasureSpec) / 3f;
        squareHeight = (float) MeasureSpec.getSize(heightMeasureSpec) / 4f;
    }

    /**
     * @param canvas
     */
    @Override
    protected void onDraw(Canvas canvas) {
        squareList.clear();
        //画按钮的背景和文字
        float topMargin = 0;
        float leftMargin = 0;
        for (int i = 0; i < numberData.size(); i++) {
            if (isNewline(i)) {
                topMargin += squareHeight;
                leftMargin = 0;
            }
            if(i == pressIndex) {
                mBgPaint.setColor(Color.GREEN);
            } else {
                mBgPaint.setColor(Color.RED);
            }
            String str = numberData.get(i);
            RectF rectF = new RectF(leftMargin, topMargin, leftMargin + squareWidth, topMargin + squareHeight);
            squareList.add(rectF);
            canvas.drawRect(rectF, mBgPaint);
            //这段代码根据现实情况修改
            if(str.equals("q")) {
                str = "";
            } else if(str.equals("d")) {
                str = "delete";
            }
            canvas.drawText(str, rectF.left + (squareWidth - getTextWidth(numberPaint, str)) / 2,  getBaseLineY(numberPaint, rectF), numberPaint);
            leftMargin += squareWidth;
        }
        //画分割线横着的
        int lineTopMargin = 0;
        for (int i = 0; i < rowCount - 1; i++) {
            canvas.drawLine(0, lineTopMargin + squareHeight, getMeasuredWidth(), lineTopMargin + squareHeight, mLinePaint);
            lineTopMargin += squareHeight;
        }

        //画分割线竖着的
        int lineLeftMargin = 0;
        for (int i = 0; i < rowCount - 1; i++) {
            canvas.drawLine(lineLeftMargin + squareWidth, 0, lineLeftMargin + squareWidth, getMeasuredHeight(), mLinePaint);
            lineLeftMargin += squareWidth;
        }

    }

    private boolean isNewline(int index) {
        if (index != 0 && index % columnCount == 0) {
            return true;
        }
        return false;
    }

    private int getRowCount() {
        int num = numberData.size() / columnCount;
        if (squareList.size() % columnCount > 0) {
            return num + 1;
        }
        return num;
    }

    private int getBaseLineY(Paint textPaint, RectF rectF) {
        Paint.FontMetrics fontMetrics = textPaint.getFontMetrics();
        float top = fontMetrics.top;//为基线到字体上边框的距离,即上图中的top
        float bottom = fontMetrics.bottom;//为基线到字体下边框的距离,即上图中的bottom
        int baseLineY = (int) (rectF.centerY() - top/2 - bottom/2);//基线中间点的y轴计算公式
        return baseLineY;
    }

    private int getTextHeight(Paint paint) {
        Paint.FontMetrics fm = paint.getFontMetrics();
        return (int) Math.ceil(fm.descent - fm.ascent);
    }

    public int getTextWidth(Paint paint, String str) {
        int iRet = 0;
        if (str != null && str.length() > 0) {
            int len = str.length();
            float[] widths = new float[len];
            paint.getTextWidths(str, widths);
            for (int j = 0; j < len; j++) {
                iRet += (int) Math.ceil(widths[j]);
            }
        }
        return iRet;
    }

    public void setItemClickListener(ItemClickListener itemClickListener) {
        this.itemClickListener = itemClickListener;
    }

    public interface ItemClickListener {
        void click(String str);
    }


}

相关文章

网友评论

    本文标题:Android 自定组件(安全键盘)

    本文链接:https://www.haomeiwen.com/subject/kriczxtx.html