之前博客中,介绍过使用谷歌提供的键盘的一些api,可以很好地自定义键盘,参考我之前的博客链接:android 自定义键盘 ,这个有一个局限性,只能占满屏幕,无法做到只能占一部分的需求键盘,如下图我平板中的键盘需求:(由于公司保密需要,所以比较恐怖一点,嘿嘿)
类似于上方的左下角的一小块键盘,这就不能使用系统自带的一些键盘api,需要自己写布局,并且对输入的金额进行位数的限制,以及一些栏位输入的整数和小数位的控制,整体的实现步骤如下;
1.点击某个edittext,弹出下方的键盘(也就是使用popuwindow的方式),需要监听edittext获得焦点以及点击的事件,还需要隐藏掉系统自带的键盘,如下:
limitEditText = (EditText) fragmentLayout.findViewById(R.id.ordertrade_limit_price); //禁止系统键盘弹出 MainActionUtilHelper.hideSoftInputMethod(limitEditText, getActivity()); digit = allone.verbank.apad.client.util.InstrumentUtil.getDigitByInstrument(instName); limitEditText.setOnFocusChangeListener(new android.view.View.OnFocusChangeListener() { @Override public void onFocusChange(View v, boolean hasFocus) { if (hasFocus) { if (popupMenu != null) { popupMenu.destroyPopupMenu(); } popupMenu = PopupMenuFactory.createPopupWindowKeyBoard(getActivity(), limitEditText, order_amount_layout, IPopupMenu.MENU_TYPE_JPY, digit == 2, digit); popupMenu.showPopupMenu(); popupMenu.createPupupWindow().setOnDismissListener(new PopupWindow.OnDismissListener() { @Override public void onDismiss() { } }); } else { // 此处为失去焦点时的处理内容 } } }); //监听弹出数字键盘 limitEditText.setOnClickListener(new OnClickListener() { @Override public void onClick(View vi) { if (popupMenu != null) { popupMenu.destroyPopupMenu(); } // 浮出菜单 popupMenu = PopupMenuFactory.createPopupWindowKeyBoard(getActivity(), limitEditText, order_amount_layout, IPopupMenu.MENU_TYPE_JPY, digit == 2, digit); popupMenu.showPopupMenu(); popupMenu.createPupupWindow().setOnDismissListener(new PopupWindow.OnDismissListener() { @Override public void onDismiss() { } }); } }); //======================================================================================(2)隐藏系统自带的键盘,方法如下,需要传入activity和edittext控件,如下代码:
/** * 隐藏系统键盘 * * @param ed * @author qiulinhe * @createTime 2016年5月31日 下午1:50:33 */ public static void hideSoftInputMethod(EditText ed, Activity activity) { activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); int currentVersion = android.os.Build.VERSION.SDK_INT; String methodName = null; if (currentVersion >= 16) { // 4.2 methodName = "setShowSoftInputOnFocus"; } else if (currentVersion >= 14) { // 4.0 methodName = "setSoftInputShownOnFocus"; } if (methodName == null) { ed.setInputType(InputType.TYPE_NULL); } else { Class<EditText> cls = EditText.class; Method setShowSoftInputOnFocus; try { setShowSoftInputOnFocus = cls.getMethod(methodName, boolean.class); setShowSoftInputOnFocus.setAccessible(true); setShowSoftInputOnFocus.invoke(ed, false); } catch (NoSuchMethodException e) { ed.setInputType(InputType.TYPE_NULL); e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } }
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="300dp" android:layout_height="400dp" android:background="#ffffff" android:orientation="vertical" > <TextView android:id="@+id/hide_keyboard" android:layout_width="wrap_content" android:layout_height="30dp" android:background="@drawable/keyboardblow" /> <LinearLayout android:layout_width="fill_parent" android:layout_height="40dp" android:layout_gravity="center_horizontal" android:layout_margin="2px" android:orientation="horizontal" > <Button android:id="@+id/seven" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="1px" android:layout_weight="1" android:background="@drawable/keyboard_longbackground" android:text="7" android:textColor="#ffffff" android:textSize="13sp" android:textStyle="bold" /> <Button android:id="@+id/eight" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="1px" android:layout_weight="1" android:background="@drawable/keyboard_longbackground" android:text="8" android:textColor="#ffffff" android:textSize="13sp" android:textStyle="bold" /> <Button android:id="@+id/nine" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="1px" android:layout_weight="1" android:background="@drawable/keyboard_longbackground" android:text="9" android:textColor="#ffffff" android:textSize="13sp" android:textStyle="bold" /> <Button android:id="@+id/first_selfdefine" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="1px" android:layout_weight="1" android:background="@drawable/keyboard_longbackground" android:text="200,000" android:textColor="#ffffff" android:textSize="13sp" android:textStyle="bold" /> </LinearLayout> <LinearLayout android:layout_width="fill_parent" android:layout_height="40dp" android:layout_gravity="center_horizontal" android:layout_margin="2px" android:orientation="horizontal" > <Button android:id="@+id/four" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="1px" android:layout_weight="1" android:background="@drawable/keyboard_longbackground" android:text="4" android:textColor="#ffffff" android:textSize="13sp" android:textStyle="bold" /> <Button android:id="@+id/five" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="1px" android:layout_weight="1" android:background="@drawable/keyboard_longbackground" android:text="5" android:textColor="#ffffff" android:textSize="13sp" android:textStyle="bold" /> <Button android:id="@+id/six" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="1px" android:layout_weight="1" android:background="@drawable/keyboard_longbackground" android:text="6" android:textColor="#ffffff" android:textSize="13sp" android:textStyle="bold" /> <Button android:id="@+id/second_selfdefine" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="1px" android:layout_weight="1" android:background="@drawable/keyboard_longbackground" android:text="500,000" android:textColor="#ffffff" android:textSize="13sp" android:textStyle="bold" /> </LinearLayout> <LinearLayout android:layout_width="fill_parent" android:layout_height="40dp" android:layout_gravity="center_horizontal" android:layout_margin="2px" android:orientation="horizontal" > <Button android:id="@+id/one" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="1px" android:layout_weight="1" android:background="@drawable/keyboard_longbackground" android:text="1" android:textColor="#ffffff" android:textSize="13sp" android:textStyle="bold" /> <Button android:id="@+id/two" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="1px" android:layout_weight="1" android:background="@drawable/keyboard_longbackground" android:text="2" android:textColor="#ffffff" android:textSize="13sp" android:textStyle="bold" /> <Button android:id="@+id/three" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="1px" android:layout_weight="1" android:background="@drawable/keyboard_longbackground" android:text="3" android:textColor="#ffffff" android:textSize="13sp" android:textStyle="bold" /> <Button android:id="@+id/three_selfdefine" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="1px" android:layout_weight="1" android:background="@drawable/keyboard_longbackground" android:text="1,000,000" android:textColor="#ffffff" android:textSize="13sp" android:textStyle="bold" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="40dp" android:layout_gravity="center_horizontal" android:layout_margin="2px" android:orientation="horizontal" > <Button android:id="@+id/double_zero" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="1px" android:layout_weight="1" android:background="@drawable/keyboard_longbackground" android:text="00" android:textColor="#ffffff" android:textSize="13sp" android:textStyle="bold" /> <Button android:id="@+id/zero" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="1px" android:layout_weight="1" android:background="@drawable/keyboard_longbackground" android:text="0" android:textColor="#ffffff" android:textSize="13sp" android:textStyle="bold" /> <Button android:id="@+id/donte" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="1px" android:layout_weight="1" android:background="@drawable/keyboard_longbackground" android:text="." android:textColor="#ffffff" android:textSize="13sp" android:textStyle="bold" /> <Button android:id="@+id/delete_btn" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="1px" android:layout_weight="1" android:background="@drawable/keyboard_longbackground" android:text="X" android:textColor="#ffffff" android:textSize="13sp" android:textStyle="bold" /> </LinearLayout> </LinearLayout>
3.接着就是点击edittext时候,弹出popuwindow窗口的管理类了,如下代码:
package allone.verbank.apad.client.component.menu.impl; import allone.verbank.apad.client.R; import allone.verbank.apad.client.component.menu.IPopupMenu; import allone.verbank.apad.client.util.SharepreferencesUtilSystemSettings; import android.app.Activity; import android.graphics.drawable.ColorDrawable; import android.view.Gravity; import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup.LayoutParams; import android.widget.Button; import android.widget.EditText; import android.widget.PopupWindow; import android.widget.TextView; import android.widget.Toast; /** * 数字键盘,点击edittext控件,下方弹出键盘 * * @author qiulinhe * @createTime 2016年5月31日 上午10:33:20 */ public class DigitKeyboardPopupMenu implements IPopupMenu { private boolean isJPY; private int digit; //=============键盘数字初始化============ private TextView hide_keyboard;//隐藏键盘 private Button seven, eight, nine, first_selfdefine;//键盘的第一行 private Button four, five, six, second_selfdefine;//键盘的第一行 private Button one, two, three, three_selfdefine;//键盘的第一行 private Button double_zero, zero, donte, delete_btn;//键盘的第一行 private StringBuffer inputStringAdd = new StringBuffer();//用来存放输入数字的sb //========================================== private PopupWindow popupMenu; private Activity activity; private EditText sourceEditView;//输入的edittext,弹出键盘 private View keylinearlayout;//为了计算键盘的尺寸,传入布局 private int keyboardType;//键盘类型 public DigitKeyboardPopupMenu(Activity activity, View sourceEditView, View sourLayout, int keyboardType, boolean ifJPY, int instrumentdigit) { this.activity = activity; this.sourceEditView = (EditText) sourceEditView; this.keylinearlayout = sourLayout; this.keyboardType = keyboardType; this.isJPY = ifJPY; this.digit = instrumentdigit; initComponent(); } private void initComponent() { //当从键盘切换到另一个键盘,重新回来,需要获得原来的已经输入的字符串 inputStringAdd.append(sourceEditView.getText().toString()); View view = activity.getLayoutInflater().inflate(R.layout.small_keyboard, null); // 创建弹出窗口 // 窗口内容为layoutLeft,里面包含一个ListView // 窗口宽度跟tvLeft一样 popupMenu = new PopupWindow(view, keylinearlayout.getWidth(), LayoutParams.WRAP_CONTENT); ColorDrawable cd = new ColorDrawable(R.color.white); popupMenu.setBackgroundDrawable(cd); popupMenu.setAnimationStyle(R.style.AnimBottom); popupMenu.update(); popupMenu.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED); popupMenu.setTouchable(true); // 设置popupwindow可点击 popupMenu.setOutsideTouchable(true); // 设置popupwindow外部可点击 popupMenu.setFocusable(true); // 获取焦点 popupMenu.setTouchInterceptor(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { // 如果点击了popupwindow的外部,popupwindow也会消失 if (event.getAction() == MotionEvent.ACTION_OUTSIDE) { popupMenu.dismiss(); return true; } return false; } }); //初始化键盘上的数字 initALLDig(view); } @Override public PopupWindow createPupupWindow() { return popupMenu; } @Override public void showPopupMenu() { if (popupMenu != null && popupMenu.isShowing()) { popupMenu.dismiss(); } else { //popupMenu.showAsDropDown(sourceEditView); popupMenu.showAtLocation(keylinearlayout, Gravity.BOTTOM | Gravity.LEFT, 0, 0); //设置layout在PopupWindow中显示的位置 // popupMenu.showAsDropDown(sourceView, // Math.round(sourceView.getX()), // (int) (sourceView.getY())); } } @Override public void destroyPopupMenu() { } /** * 初始化键盘上的所有数字,进行监听处理 * * @param view * @author qiulinhe * @createTime 2016年5月31日 下午2:24:34 */ private void initALLDig(View view) { // 自定义输入金额key,2015年12月21日14:28:06:当用户点击自定义金额,清除掉之前的内容,输入自定义金额 final String selfdig20 = SharepreferencesUtilSystemSettings.getValue(activity, "amount2", "200,000"); final String selfdig50 = SharepreferencesUtilSystemSettings.getValue(activity, "amount5", "500,000"); final String selfdig100 = SharepreferencesUtilSystemSettings.getValue(activity, "amount10", "1,000,000"); //=====================第一行,隐藏键盘的按钮=============================== hide_keyboard = (TextView) view.findViewById(R.id.hide_keyboard); hide_keyboard.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { popupMenu.dismiss(); } }); //=================第二行,7,8,9,第一个自定义金额======================= seven = (Button) view.findViewById(R.id.seven); seven.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { //追加数字 inputAppendData(seven); } }); eight = (Button) view.findViewById(R.id.eight); eight.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { //追加数字 inputAppendData(eight); } }); nine = (Button) view.findViewById(R.id.nine); nine.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { //追加数字 inputAppendData(nine); } }); first_selfdefine = (Button) view.findViewById(R.id.first_selfdefine); first_selfdefine.setText(selfdig20); first_selfdefine.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { //如果是输入为小数位,禁止自定义金额点击 if (keyboardType == IPopupMenu.MENU_TYPE_JPY) { } else { String dValue = selfdig20; dValue = dValue.replace(",", ""); selfDefAppendData(dValue); } } }); //=================第二行4,5,6,第二个自定义金额======================= four = (Button) view.findViewById(R.id.four); four.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { //追加数字 inputAppendData(four); } }); five = (Button) view.findViewById(R.id.five); five.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { //追加数字 inputAppendData(five); } }); six = (Button) view.findViewById(R.id.six); six.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { //追加数字 inputAppendData(six); } }); second_selfdefine = (Button) view.findViewById(R.id.second_selfdefine); second_selfdefine.setText(selfdig50); second_selfdefine.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { //如果是输入为小数位,禁止自定义金额点击 if (keyboardType == IPopupMenu.MENU_TYPE_JPY) { } else { String dValue = selfdig50; dValue = dValue.replace(",", ""); selfDefAppendData(dValue); } } }); //=================第二行1,2,3,第三个自定义金额======================= one = (Button) view.findViewById(R.id.one); one.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { //追加数字 inputAppendData(one); } }); two = (Button) view.findViewById(R.id.two); two.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { //追加数字 inputAppendData(two); } }); three = (Button) view.findViewById(R.id.three); three.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { //追加数字 inputAppendData(three); } }); three_selfdefine = (Button) view.findViewById(R.id.three_selfdefine); three_selfdefine.setText(selfdig100); three_selfdefine.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { //如果是输入为小数位,禁止自定义金额点击 if (keyboardType == IPopupMenu.MENU_TYPE_JPY) { } else { String dValue = selfdig100; dValue = dValue.replace(",", ""); selfDefAppendData(dValue); } } }); //=================第二行00,0,.,第四个自定义金额======================= double_zero = (Button) view.findViewById(R.id.double_zero); double_zero.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { //追加数字 inputAppendData(double_zero); } }); zero = (Button) view.findViewById(R.id.zero); zero.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { //追加数字 inputAppendData(zero); } }); donte = (Button) view.findViewById(R.id.donte); donte.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { //当键盘为输入金额的时候,小数点不能点击 if (keyboardType == IPopupMenu.MENU_TYPE_AMOUNT) { donte.setEnabled(false); } else { //如果已经有有一个小数点,则不能再点击 if (sourceEditView.getText().toString().contains(".")) { donte.setEnabled(false); } else { //追加数字,只能有一个小数点 inputAppendData(donte); } } } }); delete_btn = (Button) view.findViewById(R.id.delete_btn); delete_btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { //删除功能 deleteAppendData(); } }); } /** * 点击数字,进行追加 * * @author qiulinhe * @createTime 2016年5月31日 下午2:59:29 */ private void inputAppendData(Button digBtn) { //当键盘为输入金额的时候,小数点不能点击,且只能输入7位数,不能输入小数 if (keyboardType == IPopupMenu.MENU_TYPE_AMOUNT) { String oldValue = inputStringAdd.toString().trim(); String newValue = digBtn.getText().toString().trim();//千分位格式化 String dValue = oldValue + newValue; if (!dValue.equals("") && dValue.length() > 7) { Toast.makeText(activity, activity.getString(R.string.customdialogpricemodify_onlyseven), Toast.LENGTH_SHORT) .show(); } else { inputStringAdd.append(digBtn.getText().toString().trim()); sourceEditView.setText(inputStringAdd.toString().trim()); //设置光标位于最后一位 sourceEditView.setSelection(sourceEditView.getText().length()); } } else if (keyboardType == IPopupMenu.MENU_TYPE_JPY) {//当商品含有JPY的,输入的数值:整数位最多为3位,小数位最多为2位 sourceEditView.setText(inputStringAdd.append(ifJPYReturnData(digBtn))); //设置光标位于最后一位 sourceEditView.setSelection(sourceEditView.getText().length()); } } /** * 如果是JPY的,进行判断,返回数据 * * @param digBtn * @author qiulinhe * @createTime 2016年6月1日 上午10:45:19 */ private String ifJPYReturnData(Button digBtn) { String oriValue = inputStringAdd.toString().trim(); StringBuffer sb = new StringBuffer(oriValue); sb.append(digBtn.getText().toString().trim()); String newValue = sb.toString(); String[] newValueVec = newValue.split("\\."); if (newValueVec.length == 2) { double number = Double.parseDouble(newValueVec[0]); boolean numberflag = true; if (isJPY) { numberflag = ((number - 999 > 0.000001) ? false : true); } else { numberflag = ((number - 99 > 0.000001) ? false : true); } boolean digitflag = true; try { String digitNumber = newValueVec[1]; digitflag = digitNumber.toCharArray().length > digit ? false : true; } catch (Exception ex) { digitflag = false; } if (numberflag && digitflag) { return digBtn.getText().toString().trim(); } else { return ""; } } else { double value = Double.parseDouble(newValue); if (isJPY) { return value > 999 ? "" : digBtn.getText().toString().trim(); } else { return value > 99 ? "" : digBtn.getText().toString().trim(); } } } /** * 删除功能 * * @author qiulinhe * @createTime 2016年5月31日 下午3:03:03 */ private void deleteAppendData() { //当键盘为输入金额的时候,小数点不能点击,且只能输入7位数,不能输入小数 if (keyboardType == IPopupMenu.MENU_TYPE_AMOUNT) { String dValue = sourceEditView.getText().toString(); //格式化之后重新赋值 inputStringAdd.setLength(0); inputStringAdd.append(dValue); if (inputStringAdd.length() - 1 >= 0) { inputStringAdd.delete(inputStringAdd.length() - 1, inputStringAdd.length()); sourceEditView.setText(inputStringAdd.toString().trim()); sourceEditView.setSelection(sourceEditView.getText().length()); } } else { if (inputStringAdd.length() - 1 >= 0) { inputStringAdd.delete(inputStringAdd.length() - 1, inputStringAdd.length()); sourceEditView.setText(inputStringAdd.toString().trim()); sourceEditView.setSelection(sourceEditView.getText().length()); } } } /** * 自定义金额,输入自定义金额时,将原来的界面清空,填入自定义金额 * * @author qiulinhe * @createTime 2016年5月31日 下午3:04:02 */ private void selfDefAppendData(String selfData) { inputStringAdd.replace(0, inputStringAdd.length(), selfData); sourceEditView.setText(inputStringAdd.toString().trim()); sourceEditView.setSelection(sourceEditView.getText().length()); } }
上述的控制类中,就已经有一些关于限制金额的输入为7位数,限制有些输入的数据整数位3位/小数为2位的逻辑.很多注释已经加上,代码有些是不全的,所以有问题可以交流.