Android 自定组件(安全键盘)

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

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 numberData = new ArrayList() {{
    add(“1”);
    add(“2”);
    add(“3”);
    add(“4”);
    add(“5”);
    add(“6”);
    add(“7”);
    add(“8”);
    add(“9”);
    add(“0”);
    }};
    private List 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);
    }

}
技术类作者:菠萝鱼_lc链接:https://www.jianshu.com/p/6f1c1bbcfbe7来源:简书

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值