Android中如何自定义一个数字键盘
创始人
2024-12-23 01:03:29
0次

1. 实现键盘的 xml 布局

网格样式的布局用 GridView 或者 RecyclerView 都可以实现,其实用 GridView 更方便一些,不过我为了多熟悉 RecyclerView 的用法,这里选择用了 RecyclerView。




  

  

    
  

  

  

RecyclerView 用来实现键盘布局,上面的 RelativeLayout 则是为了实现收起键盘的点击事件。

2. 在代码中实现键盘布局,填充数据、增加点击事件

我们新建类 KeyboardView 继承自 RelativeLayout,关联上面的布局文件,然后做一些初始化操作:对 RecyclerView 填充数据、设置适配器,设置出现和消失的动画效果,写一些会用到的方法等。

public class KeyboardView extends RelativeLayout {

  private RelativeLayout rlBack;
  private RecyclerView recyclerView;
  private List datas;
  private KeyboardAdapter adapter;
  private Animation animationIn;
  private Animation animationOut;


  public KeyboardView(Context context) {
    this(context, null);
  }

  public KeyboardView(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
  }

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

  private void init(Context context, AttributeSet attrs, int defStyleAttr) {
    LayoutInflater.from(context).inflate(R.layout.layout_key_board, this);
    rlBack = findViewById(R.id.rl_back);
    rlBack.setOnClickListener(new OnClickListener() {
      @Override
      public void onClick(View view) { // 点击关闭键盘
        dismiss();
      }
    });
    recyclerView = findViewById(R.id.recycler_view);

    initData();
    initView();
    initAnimation();
  }

  // 填充数据
  private void initData() {
    datas = new ArrayList<>();
    for (int i = 0; i < 12; i++) {
      if (i < 9) {
        datas.add(String.valueOf(i + 1));
      } else if (i == 9) {
        datas.add(".");
      } else if (i == 10) {
        datas.add("0");
      } else {
        datas.add("");
      }
    }
  }

  // 设置适配器
  private void initView() {
    recyclerView.setLayoutManager(new GridLayoutManager(getContext(), 3));
    adapter = new KeyboardAdapter(getContext(), datas);
    recyclerView.setAdapter(adapter);
  }

  // 初始化动画效果
  private void initAnimation() {
    animationIn = AnimationUtils.loadAnimation(getContext(), R.anim.keyboard_in);
    animationOut = AnimationUtils.loadAnimation(getContext(), R.anim.keyboard_out);
  }

  // 弹出软键盘
  public void show() {
    startAnimation(animationIn);
    setVisibility(VISIBLE);
  }

  // 关闭软键盘
  public void dismiss() {
    if (isVisible()) {
      startAnimation(animationOut);
      setVisibility(GONE);
    }
  }

  // 判断软键盘的状态
  public boolean isVisible() {
    if (getVisibility() == VISIBLE) {
      return true;
    }
    return false;
  }

  public void setOnKeyBoardClickListener(KeyboardAdapter.OnKeyboardClickListener listener) {
    adapter.setOnKeyboardClickListener(listener);
  }

  public List getDatas() {
    return datas;
  }

  public RelativeLayout getRlBack() {
    return rlBack;
  }
}

Adapter 里面都是很简单的代码,这里就不贴出了,文章末尾我会给出源码下载地址。

到这里为止,自定义数字键盘基本就算写好了,不过最重要的还是要和 Edittext 结合使用。

3. 与 Edittext 结合使用

1. 禁用系统软键盘

if (Build.VERSION.SDK_INT <= 10) {
   etInput.setInputType(InputType.TYPE_NULL);
} else {
   getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
   try {
     Class cls = EditText.class;
     Method setShowSoftInputOnFocus = cls.getMethod("setShowSoftInputOnFocus", boolean.class);
     setShowSoftInputOnFocus.setAccessible(true);
     setShowSoftInputOnFocus.invoke(etInput, false);
   } catch (Exception e) {
     e.printStackTrace();
   }
}

在网上找了一些方法,但是点击 Edittext 的时候系统软键盘依然会弹出。最后找到了这个方法,利用反射强制不弹出软键盘,效果不错。

2. 处理各个按键的点击事件

  @Override
  public void onKeyClick(View view, RecyclerView.ViewHolder holder, int position) {
    switch (position) {
      case 9: // 按下小数点
        String num = etInput.getText().toString().trim();
        if (!num.contains(datas.get(position))) {
          num += datas.get(position);
          etInput.setText(num);
          etInput.setSelection(etInput.getText().length());
        }
        break;
      default: // 按下数字键
        if ("0".equals(etInput.getText().toString().trim())) { // 第一个数字按下0的话,第二个数字只能按小数点
          break;
        }
        etInput.setText(etInput.getText().toString().trim() + datas.get(position));
        etInput.setSelection(etInput.getText().length());
        break;
    }
  }

  @Override
  public void onDeleteClick(View view, RecyclerView.ViewHolder holder, int position) {
    // 点击删除按钮
    String num = etInput.getText().toString().trim();
    if (num.length() > 0) {
      etInput.setText(num.substring(0, num.length() - 1));
      etInput.setSelection(etInput.getText().length());
    }
  }

相关内容

热门资讯

空调连续工作多久需要停机休息 空调连续工作的时间取决于多个因素,包括空调的型号、功率、使用环境和维护情况等。一般来说,空调可以连续...
空调哪个符号是除湿的 空调除湿功能通常用一个水滴形状的符号表示。不同品牌和型号的空调遥控器可能会有所差异,但一般来说,除湿...
格力空调多长时间加一次氟利昂 1、一般情况下,空调对氟利昂的使用量是非常小的,所以在空调使用了四年左右的时候再考虑加也没问题。2、...
空调用多长时间需要加氟一次 一般情况下是五年。当出现以下这几种情况时,空调才需要加氟。1、空调的室内机和室外机各有两个接口,当接...
格调生活·C标思享荟:卡萨帝在... 9月12日的郑州龙湖金融岛,夜风轻拂,灯光璀璨。“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑...
品牌价值破千亿、高端份额持续领... 9月12日,“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑州站”在郑州龙湖金融岛举办。2026...
空调主板坏了修800还是换新的 空调主板坏了是修还是换新,需要考虑多个因素,以下是一些建议:1. 维修成本:如果维修费用较低,比如 ...
空调开多久需要休息多长时间 问题:空调开多久需要休息多长时间回答:1、在使用空调的过程中,一般空调开7~8个小时左右需要休息2~...
中央空调多长时间清洗一次 1、一般空调开机前清洗一次即可,空调开机中间时段再清洗一次,空调关机时清洗一次,这样比较合理。2、空...
中央空调氟利昂多久加一次 看空调制热和制冷程度,很多人的观点认为氟利昂必须一年放一次,其实这个观点是错误的,理解上面有点偏差,...