我自横刀向天笑,去留肝胆两昆仑。这篇文章主要讲述Android 平板中 自己定义键盘(popuwindow) 居于屏幕左下方 仿微信的password输入界面相关的知识,希望能为你提供帮助。
? ? ? 之前博客中,介绍过使用谷歌提供的键盘的一些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(); } } }
? ? ?2.写好popuwindow的xml布局文件,也就是你须要呈现的键盘布局,xml文件例如以下:
< ?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"); //=====================第一行,隐藏键盘的button=============================== 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 = https://www.songbingjia.com/android/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 = https://www.songbingjia.com/android/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 = https://www.songbingjia.com/android/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(); } }); } /** * PV数字,进行追加 * * @author qiulinhe * @createTime 2016年5月31日 下午2:59:29 */ private void inputAppendData(Button digBtn) {//当键盘为输入金额的时候,小数点不能点击,且仅仅能输入7位数,不能输入小数 if (keyboardType == IPopupMenu.MENU_TYPE_AMOUNT) { String oldValue = https://www.songbingjia.com/android/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 = https://www.songbingjia.com/android/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 = https://www.songbingjia.com/android/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 = https://www.songbingjia.com/android/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位的逻辑.非常多凝视已经加上,代码有些是不全的,所以有问题能够交流.
=========================2016年7月15日14:37:12,补充=========================
【Android 平板中 自己定义键盘(popuwindow) 居于屏幕左下方 仿微信的password输入界面】假设出现键盘遮挡的问题,能够套一层scrollview或者又一次设置listview的高度,例如以下链接:http://blog.csdn.net/nihaoqiulinhe/article/details/51917530
推荐阅读
- [译]Dapper教程
- 解决Android Studio 3.0导入module依赖后unable to merge index
- Android studio 3.0安装MUMU模拟器
- [LeetCode] Find Anagram Mappings 寻找异构映射
- 《Android进阶之光》--Dagger2
- 《Android进阶之光》--事件总线
- jQuery中append appendTo prepend prependTo insertBefore insertAfter after before之间的区别
- android studio gradle统一管理版本
- 全民充电节APP又上新福利,你发现了吗()