2011-03-24 20:25:00 pochuanpiao 阅读数 4109

    android系统上面的输入法,针对手机用户,已经做的比较完善了,但是如果在TV上面跑的话,就需要做一些改动。

比如,对软键盘的操作,我们不能去触摸电视屏幕,只能靠焦点的移动去选择我们需要的信息。

 


下面针对软键盘上面焦点的移动做一些关键点说明:

 

1、调试使用的是自带的demo:softKeyboard,跑起来之后,是不能控制焦点的。
  参考了源代码里面的pinyinIME,在pinyinIME里面,是可以通过方向键选择候选区中候选词的。
  
2、软键盘上面每一个键值控制,参考代码:
  Keyboard current = mInputView.getKeyboard();
  Key[] mKeys;
  Key key;
   
  List<Key> keys = current.getKeys();
  mKeys = keys.toArray(new Key[keys.size()]);
 
  key = mKeys[keyNumber];
  
  current是当前的键盘类,mInputView是KeyboardView类
  每一个mKeys是一个键子,可以得到键盘的键子个数:mKeys.length
  键子所占的区域:keyx.x,key.y,key.width,key.height
  
3、在LatinKeyboardView中重写onDraw,画一个焦点出来
   private Drawable mActiveCellDrawable;
   mActiveCellDrawable.setBounds(x,y,w,h);
   mActiveCellDrawable.draw(canvas);
  
   setBounds里面就是软键盘的键子区域
   注意onDraw里面不要忘记:invalidate(); 哦
  
4、呵呵,接下来就简单了,只需要我们在响应onKeydown的时候,根据方向键,变化键子坐标就可以了

 

2016-06-17 17:38:24 kaizideai 阅读数 1866


/**
 * 键盘操作工具类
 * Created by kaiyuan on 16/5/31.
 */

/**
 * 键盘操作工具类
 * Created by kaiyuan on 16/5/31.
 */
public class KeyboardUtil {

    public static void hideKeyboard(Context context, View view) {
        InputMethodManager imm = (InputMethodManager) context
                .getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(view.getWindowToken(), 0);

    }

    public static void showKeyboard(Context context, View view) {
        InputMethodManager imm = (InputMethodManager) context
                .getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.showSoftInput(view, 0);
    }
}

2015-06-27 13:45:16 tanxuewe 阅读数 774
当我们在项目中难免会发现Android自带的键盘输入法不能满足我们的业务需示时,我们需要对键盘进行改造,让他更好的服务于我们的项目,下面的关于自定义数据键盘来记录键盘的开发过程。

首先我们需要一个键盘的定义文件:res/xml/digit.xml, 该文件用来定义你的键盘布局

<?xml version="1.0" encoding="utf-8"?>
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
    android:keyWidth="25%p" android:keyHeight="50dp"
    android:horizontalGap="0px" android:verticalGap="0px">

    <Row>
        <Key android:codes="49" android:keyLabel="1"></Key>
        <Key android:codes="50" android:keyLabel="2"></Key>
        <Key android:codes="51" android:keyLabel="3"></Key>
        <Key android:codes="152" android:keyLabel="清除" android:keyHeight="100dp"></Key>
    </Row>
    <Row>
        <Key android:codes="52" android:keyLabel="4"></Key>
        <Key android:codes="53" android:keyLabel="5"></Key>
        <Key android:codes="54" android:keyLabel="6"></Key>
    </Row>
    <Row>
        <Key android:codes="55" android:keyLabel="7"></Key>
        <Key android:codes="56" android:keyLabel="8"></Key>
        <Key android:codes="57" android:keyLabel="9"></Key>
        <Key android:codes="-4" android:keyLabel="确定" android:keyHeight="100dp"></Key>
    </Row>
    <Row>
        <Key android:codes="46" android:keyLabel="."></Key>
        <Key android:codes="48" android:keyLabel="0"></Key>
        <Key android:codes="-5" android:keyLabel="删除"></Key>
    </Row>
</Keyboard>

其中

Row:表示每一行的布局属性

Key:每一个键的定义

codes:键的标识符

keyLabel:键上显示的字符

keyHeight:键的高度


定义键盘控件:

<android.inputmethodservice.KeyboardView
        android:id="@+id/keyboard"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/white"
        android:shadowColor="@color/white"
        android:focusable="true"
        android:focusableInTouchMode="true"
        android:keyBackground="@drawable/bord"
        android:layout_alignParentBottom="true"
        android:keyTextColor="@color/black"
        android:visibility="gone"
        />

KeyBoardView就是Android专门为键盘定义的一个控件,我们可以把上面定义的键盘布局与该控件关联来显示:

        keyboardView = (KeyboardView) findViewById(R.id.keyboard);
        keyboard = new Keyboard(this, R.xml.digit);
        keyboardView.setKeyboard(keyboard);
        keyboardView.setPreviewEnabled(false);//不显示预览提示
        keyboardView.setOnKeyboardActionListener(new KeyboardView.OnKeyboardActionListener() {
            @Override
            public void onPress(int primaryCode) {

            }

            @Override
            public void onRelease(int primaryCode) {

            }

            @Override
            public void onKey(int primaryCode, int[] keyCodes) {
                Editable editable = editText.getText();
                int start = editText.getSelectionStart();
                if(primaryCode == Keyboard.KEYCODE_DONE){
                    hideKeyBoard();
                }else if(primaryCode == Keyboard.KEYCODE_DELETE){
                    if(editable != null && editable.length()>0){
                        if(start>0){
                            editable.delete(start-1,start);
                        }
                    }
                }else if(primaryCode == 152){
                    editable.clear();
                }else{
                    editable.insert(start, Character.toString((char)primaryCode));
                }
            }

            @Override
            public void onText(CharSequence text) {

            }

            @Override
            public void swipeLeft() {

            }

            @Override
            public void swipeRight() {

            }

            @Override
            public void swipeDown() {

            }

            @Override
            public void swipeUp() {

            }
        });

其中

KeyboardView.OnKeyboardActionListener()

回调函数就是用来监听你的按键:当你按下某个键后,在digit.xml中定义的codes就会作为参数传入,primaryCode就是该codes,这时候你就可以随意发挥你的想像,在我们的代码中实现你的梦想吧。

另外,当你在EditText中使用时,不免会自动带出系统内置的输入法,可以通过设置editText.setInputType(InputType.TYPE_NULL);来屏蔽它

通过控制keyBoardView的显示属性来控制键盘的显示与隐藏。

至此我们的键盘基本就完成了。
2015-09-15 09:58:26 omayyouhappy 阅读数 6359

        系统自带的键盘,键值太多,不符合客户的需求,需要自定义键盘,如下图:







      分别是字母和数字的键盘,感谢很多前辈提供的例子,朋友们可以到这个链接下载资源:前辈android 自定义键盘详解讲的非常清楚,我下了他的代码,在这基础上进行修改,遇到的第一个问题就是第一个图上的: “  .?&”  ,如何在键盘上显示这样的文本,假设采用楼主设置文本的形式进行设置的时候,会遇到如下错误:

    <Key android:codes="-2" android:keyLabel=".?&" />

     The entity name must immediately follow the ‘&’ in the entity reference

    这个错误的解决方案是:

    

主要是xml无法解析 && 这样一个逻辑符号。所以要将他写出

<Key android:codes="-2" android:keyLabel=".?&amp;" />这样就可以了。。



   2.好,接着第二个问题:其他特殊符合如“,”之类的都可以使用转义字符,但遇到“@”,你就不能好好的使用转义字符来解决了:


   <Key android:codes="64" android:keyLabel="&#064;" />



   上述代码同样会报一个这样的错误:error: Error: No resource type

 specified (at 'keyLabel' with value '@').万能的百度也没有搜到解决方

案,我就很奇怪,不是已经转义了吗?怎么还是识别不了呢,后来想想是不是xml

文件会不会认为@后面还得跟个什么东西,所以这样写就是有错的,那好我就再用

如下语句:“\”来进行转义,应该就可以了,我修改成如下的代码,保存,运行

没有出错了。

    <Key android:codes="64" android:keyLabel="\&#064;" />
 <Key android:codes="-5" android:keyEdgeFlags="right" android:isRepeatable="true"android:keyIcon="&#064;drawable/sym_keyboard_delete" />


   注意:如果你使用到图片的话,@drawable/delete这样的时候,也需要将@进行转义,这个问题的确很奇怪,我在另外一个xml文件直接使用是没有问题的,不知道是什么原因,大神如果知道的话,麻烦告诉一声。



 3.第三个问题:遇到键盘上要显示反斜杠,也就是“\”的时候,因为\是起转义


字符的作用,所以要显示\,需要再进行转义一次,也就是如下语句:

  

  <Key android:codes="92" android:keyLabel="\\" />



  4.在设置了edittext之后,要隐藏系统的软键盘,这时候就会遇到奇怪的问

题,光标消失了并且没有闪烁,所以百度了一下,将edittext传入到函数里面

,然后就可以使用如下方法,就可以使光标出现:


edit = (EditText) this.findViewById(R.id.edit);
// edit.setInputType(InputType.TYPE_NULL);
hideSoftInputMethod(edit);
// 隐藏系统键盘
	public void hideSoftInputMethod(EditText ed) {
		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) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IllegalArgumentException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

    主要是因为各个android系统对于光标的处理是不一样的,具体的解释,请大神告知。


  5.如果你有如下的需求:在点击界面上任何一个edittext,弹出自定义键盘还

有一个按钮,用来隐藏自定义键盘,如下图:



  也就是点击隐藏的图标,隐藏掉自定义键盘,这个需求其实蛮简单的:就是需要

给显示键盘的布局一个id,当点击隐藏按钮之后,将布局Visibility的属性设置

为Gone或者InVisibility,其中gone表示不占空间和内存。示例如下(部分代

码:

private RelativeLayout relakey;
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		ctx = this;
		act = this;
		relakey = (RelativeLayout) this.findViewById(R.id.relakey);

		hideshow = (TextView) this.findViewById(R.id.hideshow);
		hideshow.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				relakey.setVisibility(View.GONE);

			}
		});
		edit = (EditText) this.findViewById(R.id.edit);
		// edit.setInputType(InputType.TYPE_NULL);
		hideSoftInputMethod(edit);

		edit.setOnTouchListener(new OnTouchListener() {
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				relakey.setVisibility(View.VISIBLE);
				hideshow.setVisibility(View.VISIBLE);
				
				new KeyboardUtil(act, ctx, edit).showKeyboard();
				return false;
			}
		});</span>

      在布局文件中,一开始设置布局文件为gone或者invisible,都是可以的,我的布局文件如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <EditText
        android:id="@+id/edit"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />

    <EditText
        android:id="@+id/edit1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />

    <View
        android:layout_width="wrap_content"
        android:layout_height="270dp" />

   <span style="color:#ff0000;"><strong> <RelativeLayout
        android:id="@+id/relakey"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" 
        android:padding="3dp"
        android:visibility="invisible">   <!-- 这个其实就是需要隐藏的布局,用来控制键盘是否显示与隐藏-->
        <TextView
            android:id="@+id/hideshow"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:background="@drawable/ret"
            android:visibility="invisible" />

        <android.inputmethodservice.KeyboardView
            android:id="@+id/keyboard_view"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:background="@color/white"
            android:focusable="true"
            android:focusableInTouchMode="true"
            android:keyBackground="@drawable/d"
            android:keyTextColor="@color/white"
            android:keyTextSize="20sp"
            android:labelTextSize="15sp"
            android:padding="3dp"
android:visibility="invisible" /></span>
    </RelativeLayout>

</LinearLayout>

     只需要在代码中对该属性进行控制,就可以完成上述需求。


    6.其他的问题如给key按键设置自己的图片,我会遇到莫名其妙的问题,就是图片太大,把键盘挤出去了,而我使用系统默认的比如删除、切换大小写之类的图片就不会出现这样的问题,期待大神给予帮助,目前为止还未解决


    7.最后一个问题,如果看过这篇博文的人,android 自定义键盘(前辈)应该都知道如果要自定义键盘的话,需要重写里面的键盘布局xml文件,其实是很简单,就是一行一行的进行配置即可,下面对于一些属性我加上自己的使用经验和理解,希望给菜鸟一些帮助。

<?xml version="1.0" encoding="UTF-8"?>
<Keyboard android:keyWidth="9.55%p" android:keyHeight="@dimen/key_height2"
	android:horizontalGap="1px" android:verticalGap="3px"
	xmlns:android="http://schemas.android.com/apk/res/android">
	<Row>
		<Key android:codes="49"  android:keyEdgeFlags="left" android:keyLabel="1" />
		<Key android:codes="50" android:keyLabel="2" />
		<Key android:codes="51" android:keyLabel="3" />
		<Key android:codes="52" android:keyLabel="4" />
		<Key android:codes="53" android:keyLabel="5" />
		<Key android:codes="54" android:keyLabel="6" />
		<Key android:codes="55" android:keyLabel="7" />
		<Key android:codes="56" android:keyLabel="8" />
		<Key android:codes="57" android:keyLabel="9" />	
		<Key android:codes="48" android:keyLabel="0" android:keyEdgeFlags="right" />
    </Row>
</Keyboard>
     下面是各个属性的解释:
    (1)android:keyWidth="9.55%p":该属性表示每个键盘上的单个按键占据的宽度百分比,举个例子是:键盘总共有3行,每行有10个的话,那么每个按键就是
10%。

  (2)android:keyHeight="@dimen/key_height2":该属性用来设置每个单个按键所占的高度,具体的就不细说了,可以用dimen进行灵活配置。
  (3)android:horizontalGap="1px" android:verticalGap="3px":这两个属性表示:每个按键之间在水平和竖直方向的间距,为了美观,该属性是必须设置的否则你会发现你的键盘丑死了,都挤到一块去了。
  (4)android:keyEdgeFlags="left":表示对于整个键盘这一行来说,这个按键是居于最左边的,也可以设置成最右边,这个属性我发现如果不设置的话,也不影响键盘的正常显示。
  (5android:keyLabel="3":该属性表示按键显示的文本,可以随意填,但如果碰到一些xml文件中不能直接显示的字符如&、@、‘等需要转义,如何转义可以参考上面的第一条建议。
      
  (6)android:codes="48":这个对于该自定义键盘来说是非常重要的一个属表示对于一些数字、字母、标点符号等所有能在键盘找到的,必须用ascii码来对应,对于这些char字符对应的ascii的对应关系,好吧,我就告诉你们,链接如下:ascii码转换表ascii转换对应表当然了,如果想输入一些奇怪的东西,建议你的codes值不要与ascii码相同,可以取得很大,就不会有冲突了。
  (7)android:keyIcon="@drawable/sym_keyboard_shift":该属性表示对于该按键,你可以自定义自己的图片放上去。      
  (8)android:isRepeatable="true":表示对于该按键长按是否会连续输入,这个属性对于删除键来说极其有效。
  如果你用心的阅读完上述的内容,你肯定也可以设计出自己的自定义键盘,有问题随时与我交流,可以在下方评论,我会及时给与解答。


        真的要放大福利了,我的android 自定义键盘(包含字母、标点符号)的完善版本已经上传到csdn,链接如下:android 自定义键盘 (nihaoqiulinhe所有)


==================================分割线,更新日期2015年12月21日11:13:55==========================================

当输入自定义的键盘上的数字时,比如说如果是300000,有这样一个需求,当点击300000时,要清除掉之前的数据,切换时也需要清除掉,如下键盘代码:

package client.verbank.mtp.allone.util;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;

import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Rect;
import android.inputmethodservice.Keyboard;
import android.inputmethodservice.Keyboard.Key;
import android.inputmethodservice.KeyboardView;
import android.inputmethodservice.KeyboardView.OnKeyboardActionListener;
import android.os.Build;
import android.os.SystemClock;
import android.text.Editable;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.ActionMode;
import android.view.Display;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.PopupWindow;
import android.widget.PopupWindow.OnDismissListener;
import client.verbank.mtp.allone.R;
import client.verbank.mtp.allone.consts.ISystemCommData;

/**
 * 数字键盘:专门针对金额的键盘,不能输入小数位
 * 
 * @Project: FEIB_AndroidStation 
 * @Title: MyKeyboardDigital.java 
 * @Package client.verbank.mtp.allone.util 
 * @Description: TODO 
 * @author qiulinhe qiu.linhe@allone.cn 
 * @date 2015年10月14日 上午11:04:48 
 * @Copyright: 2015 www.allone.cn Inc. All rights reserved. 
 * @version V3.0.0   
 */
public class MyKeyboardDigitalAmount extends EditText implements
		OnKeyboardActionListener, ISystemCommData {

	private Keyboard k1;// 字母键盘
	private Keyboard k2;// 标点符号键盘
	private Keyboard k3;// 数字键盘
	public boolean isnun = false;// 是否标点符号键盘
	public boolean isupper = false;// 是否大写

	private KeyboardView mKeyboardView;
	private Keyboard mKeyboard;

	private Window mWindow;
	private View mDecorView;
	private View mContentView;

	private PopupWindow mKeyboardWindow;

	private boolean needcustomkeyboard = true; // 是否启用自定义键盘
	private boolean randomkeys = false; // 数字按键是否随机

	private int scrolldis = 100; // 输入框在键盘被弹出时,要被推上去的距离

	public static int screenw = -1;// 未知宽高
	public static int screenh = -1;
	public static int screenh_nonavbar = -1; // 不包含导航栏的高度
	public static int real_scontenth = -1; // 实际内容高度, 计算公式:屏幕高度-导航栏高度-电量栏高度

	public static float density = 1.0f;
	public static int densityDpi = 160;

	// 接收用户在系统设定界面的自定义金额
	String selfdig20 = "200,000";
	String orgindi20 = "200,000";
	// 接收用户在系统设定界面的自定义金额
	String selfdig50 = "500,000";
	String orgindi50 = "500,000";
	// 接收用户在系统设定界面的自定义金额
	String selfdig100 = "1,000,000";
	String orgindi100 = "1,000,000";

	/**
	 * @param context
	 * 
	 * @param attrs
	 */
	public MyKeyboardDigitalAmount(Context context, AttributeSet attrs) {
		super(context, attrs);
		initAttributes(context);
		initKeyboard(context, attrs);

		// TODO Auto-generated constructor stub
	}

	/**
	 * @param context
	 * @param attrs
	 * @param defStyle
	 */
	public MyKeyboardDigitalAmount(Context context, AttributeSet attrs,
			int defStyle) {
		super(context, attrs, defStyle);

		selfdig20 = SharepreferencesUtilSystemSettings.getValue(getContext(),
				System_key_SelfAmout2, "200,000");
		selfdig50 = SharepreferencesUtilSystemSettings.getValue(getContext(),
				System_key_SelfAmout5, "500,000");
		selfdig100 = SharepreferencesUtilSystemSettings.getValue(getContext(),
				System_key_SelfAmout10, "1,000,000");
		initAttributes(context);
		initKeyboard(context, attrs);
		// TODO Auto-generated constructor stub
	}

	private void initKeyboard(Context context, AttributeSet attrs) {
		selfdig20 = SharepreferencesUtilSystemSettings.getValue(getContext(),
				System_key_SelfAmout2, "200,000");
		selfdig50 = SharepreferencesUtilSystemSettings.getValue(getContext(),
				System_key_SelfAmout5, "500,000");
		selfdig100 = SharepreferencesUtilSystemSettings.getValue(getContext(),
				System_key_SelfAmout10, "1,000,000");
		TypedArray a = context.obtainStyledAttributes(attrs,
				R.styleable.keyboard);

		if (a.hasValue(R.styleable.keyboard_xml)) {
			needcustomkeyboard = true;

			int xmlid = a.getResourceId(R.styleable.keyboard_xml, 0);

			mKeyboard = new Keyboard(context, xmlid);

			mKeyboardView = (KeyboardView) LayoutInflater.from(context)
					.inflate(R.layout.mykeyboardviewdigit, null);
			if (a.hasValue(R.styleable.keyboard_randomkeys)) {
				boolean random = a.getBoolean(R.styleable.keyboard_randomkeys,
						false);
				randomkeys = random;

				if (random) {
					randomdigkey(mKeyboard);
				}
			}
			selfdig20 = SharepreferencesUtilSystemSettings.getValue(
					getContext(), System_key_SelfAmout2, "200,000");
			selfdig50 = SharepreferencesUtilSystemSettings.getValue(
					getContext(), System_key_SelfAmout5, "500,000");
			selfdig100 = SharepreferencesUtilSystemSettings.getValue(
					getContext(), System_key_SelfAmout10, "1,000,000");
			selfdigkey();
			// mKeyboardView.setKeyboard(mKeyboard);
			mKeyboardView.setEnabled(true);
			mKeyboardView.setPreviewEnabled(false);
			mKeyboardView.setOnKeyboardActionListener(this);

			mKeyboardWindow = new PopupWindow(mKeyboardView,
					ViewGroup.LayoutParams.MATCH_PARENT,
					ViewGroup.LayoutParams.WRAP_CONTENT);
			mKeyboardWindow.setAnimationStyle(R.style.AnimationFade);
			// mKeyboardWindow.setBackgroundDrawable(new BitmapDrawable());
			// mKeyboardWindow.setOutsideTouchable(true);
			mKeyboardWindow.setOnDismissListener(new OnDismissListener() {

				@Override
				public void onDismiss() {
					// TODO Auto-generated method stub
					if (scrolldis > 0) {
						int temp = scrolldis;
						// scrolldis = 0;
						if (null != mContentView) {
							mContentView.scrollBy(0, -temp);
						}
					}
				}
			});
		} else {
			needcustomkeyboard = false;
		}

		a.recycle();

	}

	private void showKeyboard() {
		if (null != mKeyboardWindow) {
			if (!mKeyboardWindow.isShowing()) {
				if (randomkeys) {
					randomdigkey(mKeyboard);
				}

				selfdig20 = SharepreferencesUtilSystemSettings.getValue(
						getContext(), System_key_SelfAmout2, "200,000");
				selfdig50 = SharepreferencesUtilSystemSettings.getValue(
						getContext(), System_key_SelfAmout5, "500,000");
				selfdig100 = SharepreferencesUtilSystemSettings.getValue(
						getContext(), System_key_SelfAmout10, "1,000,000");
				selfdigkey();
				// mKeyboardView.setKeyboard(mKeyboard);

				mKeyboardWindow.setAnimationStyle(R.style.AnimBottom);
				mKeyboardWindow.showAtLocation(this.mDecorView, Gravity.RIGHT
						| Gravity.BOTTOM, 0, 0);
				mKeyboardWindow.update();

				if (null != mDecorView && null != mContentView) {
					int[] pos = new int[2];
					// 计算弹出的键盘的尺寸
					getLocationOnScreen(pos);
					float height = dpToPx(getContext(), 240);

					// int []hsmlpos=new int[2];
					// mDecorView.getLocationOnScreen(hsmlpos);

					Rect outRect = new Rect();
					// 然后该View有个getWindowVisibleDisplayFrame()方法可以获取到程序显示的区域,
					// * 包括标题栏,但不包括状态栏。
					mDecorView.getWindowVisibleDisplayFrame(outRect);// 获得view空间,也就是除掉标题栏
					// outRect.top表示状态栏(通知栏)
					int screen = real_scontenth;
					// scrolldis = (int) ((pos[1] + getMeasuredHeight() -
					// outRect.top)
					// - (screen - height) + 500);

					if (scrolldis > 0) {
						mContentView.scrollBy(0, scrolldis);
					}
				}

			}
		}
	}

	private void hideKeyboard() {
		if (null != mKeyboardWindow) {
			if (mKeyboardWindow.isShowing()) {
				mKeyboardWindow.dismiss();
			}
		}
	}

	private void hideSysInput() {
		if (this.getWindowToken() != null) {
			InputMethodManager imm = (InputMethodManager) getContext()
					.getSystemService(Context.INPUT_METHOD_SERVICE);
			imm.hideSoftInputFromWindow(this.getWindowToken(), 0);
		}
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		super.onTouchEvent(event);
		requestFocus();
		requestFocusFromTouch();

		if (needcustomkeyboard) {
			hideSysInput();
			showKeyboard();
		}

		return true;
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (keyCode == KeyEvent.KEYCODE_BACK) {
			if (null != mKeyboardWindow) {
				if (mKeyboardWindow.isShowing()) {
					mKeyboardWindow.dismiss();
					return true;
				}
			}
		}

		return super.onKeyDown(keyCode, event);

	}

	@Override
	public void onAttachedToWindow() {
		super.onAttachedToWindow();

		this.mWindow = ((Activity) getContext()).getWindow();
		this.mDecorView = this.mWindow.getDecorView();
		this.mContentView = this.mWindow
				.findViewById(Window.ID_ANDROID_CONTENT);

		hideSysInput();
	}

	@Override
	public void onDetachedFromWindow() {
		super.onDetachedFromWindow();

		hideKeyboard();

		mKeyboardWindow = null;
		mKeyboardView = null;
		mKeyboard = null;

		mDecorView = null;
		mContentView = null;
		mWindow = null;
	}

	@Override
	public void onPress(int primaryCode) {
		// TODO Auto-generated method stub

	}

	@Override
	public void onRelease(int primaryCode) {
		// TODO Auto-generated method stub

	}

	@Override
	public void onKey(int primaryCode, int[] keyCodes) {
		// TODO Auto-generated method stub
		Editable editable = this.getText();
		int start = this.getSelectionStart();
		if (primaryCode == Keyboard.KEYCODE_CANCEL) {// 隐藏键盘
			hideKeyboard();
		} else if (primaryCode == Keyboard.KEYCODE_DELETE) {// 回退
			if (editable != null && editable.length() > 0) {
				if (start > 0) {
					editable.delete(start - 1, start);
				}
			}
		} else if (primaryCode == Keyboard.KEYCODE_SHIFT) {// 大小写切换
			changeKey();
			mKeyboardView.setKeyboard(k1);

		}

		else if (primaryCode == Keyboard.KEYCODE_DONE) {// 标点符号键盘切换
			if (isnun) {
				isnun = false;
				mKeyboardView.setKeyboard(k1);
			} else {
				isnun = true;
				mKeyboardView.setKeyboard(k2);
			}
		}
		// else if (primaryCode == 46) {
		//
		// // 当用户输入.3的时候自动转换为0.3
		// if (editable != null && editable.length() > 0) {
		// if (start > 0) {
		// editable.insert(start, ".");
		// }
		// } else {
		// editable.insert(start, "0.");
		// }
		//
		// }

		else if (primaryCode == -110) {
			editable.insert(start, "00");
		} else if (primaryCode == -20000) {
			editable.clear();
			editable.insert(0, selfdig20);
		} else if (primaryCode == -50000) {
			editable.clear();
			editable.insert(0, selfdig50);
		} else if (primaryCode == -10000) {
			editable.clear();
			editable.insert(0, selfdig100);
		} else if (0x0 <= primaryCode && primaryCode <= 0x7f) {
			// 可以直接输入的字符(如0-9,.),他们在键盘映射xml中的keycode值必须配置为该字符的ASCII码
			editable.insert(start, Character.toString((char) primaryCode));
		} else if (primaryCode > 0x7f) {
			Key mkey = getKeyByKeyCode(primaryCode);
			// 可以直接输入的字符(如0-9,.),他们在键盘映射xml中的keycode值必须配置为该字符的ASCII码
			editable.insert(start, mkey.label);

		} else {
			// 其他一些暂未开放的键指令,如next到下一个输入框等指令
		}
	}

	// 数字键盘测试是否改变200,000和500,000让用户自定义

	private void selfdigkey() {
		if (mKeyboard == null) {
			return;
		}

		List<Key> keyList = k3.getKeys();

		// 查找出0-9的数字键
		for (int i = 0, size = keyList.size(); i < size; i++) {
			Key key = keyList.get(i);

			CharSequence label = key.label;
			// if (label != null && label.toString().equals(orgindi20)) {
			// keyList.get(i).label = selfdig;
			// orgindi20 = selfdig;
			// }

			if (label != null && label.toString().equals(orgindi20)) {
				keyList.get(i).label = selfdig20;
				keyList.get(i).codes[0] = -20000;
				orgindi20 = selfdig20;
			}
			if (label != null && label.toString().equals(orgindi50)) {
				keyList.get(i).label = selfdig50;
				keyList.get(i).codes[0] = -50000;
				orgindi50 = selfdig50;
			}
			if (label != null && label.toString().equals(orgindi100)) {
				keyList.get(i).label = selfdig100;
				keyList.get(i).codes[0] = -10000;
				orgindi100 = selfdig100;
			}
		}

		mKeyboardView.setKeyboard(k3);
	}

	/**
	 * 键盘大小写切换
	 */
	private void changeKey() {
		List<Key> keylist = k1.getKeys();
		if (isupper) {// 大写切换小写
			isupper = false;
			for (Key key : keylist) {
				if (key.label != null && isword(key.label.toString())) {
					key.label = key.label.toString().toLowerCase();
					key.codes[0] = key.codes[0] + 32;
				}
			}
		} else {// 小写切换大写
			isupper = true;
			for (Key key : keylist) {
				if (key.label != null && isword(key.label.toString())) {
					key.label = key.label.toString().toUpperCase();
					key.codes[0] = key.codes[0] - 32;
				}
			}
		}
	}

	private boolean isword(String str) {
		String wordstr = "abcdefghijklmnopqrstuvwxyz";
		if (wordstr.indexOf(str.toLowerCase()) > -1) {
			return true;
		}
		return false;
	}

	@Override
	public void onText(CharSequence text) {
		// TODO Auto-generated method stub

	}

	@Override
	public void swipeLeft() {
		// TODO Auto-generated method stub

	}

	@Override
	public void swipeRight() {
		// TODO Auto-generated method stub

	}

	@Override
	public void swipeDown() {
		// TODO Auto-generated method stub

	}

	@Override
	public void swipeUp() {
		// TODO Auto-generated method stub

	}

	private Key getKeyByKeyCode(int keyCode) {
		if (null != mKeyboard) {
			List<Key> mKeys = mKeyboard.getKeys();
			for (int i = 0, size = mKeys.size(); i < size; i++) {
				Key mKey = mKeys.get(i);

				int codes[] = mKey.codes;

				if (codes[0] == keyCode) {
					return mKey;
				}
			}
		}

		return null;
	}

	private void initAttributes(Context context) {

		k1 = new Keyboard(context, R.xml.qwerty);
		k2 = new Keyboard(context, R.xml.qwerty2);
		k3 = new Keyboard(context, R.xml.amountinputkeyboard);

		initScreenParams(context);
		this.setLongClickable(false);
		this.setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI);
		removeCopyAbility();

		if (this.getText() != null) {
			this.setSelection(this.getText().length());
		}

		this.setOnFocusChangeListener(new OnFocusChangeListener() {

			@Override
			public void onFocusChange(View v, boolean hasFocus) {
				// TODO Auto-generated method stub
				if (!hasFocus) {
					hideKeyboard();
				}
			}
		});

	}

	@TargetApi(11)
	private void removeCopyAbility() {
		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
			this.setCustomSelectionActionModeCallback(new ActionMode.Callback() {

				@Override
				public boolean onCreateActionMode(ActionMode mode, Menu menu) {
					return false;
				}

				@Override
				public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
					return false;
				}

				@Override
				public void onDestroyActionMode(ActionMode mode) {

				}

				@Override
				public boolean onActionItemClicked(ActionMode mode,
						MenuItem item) {
					return false;
				}
			});
		}
	}

	private boolean isNumber(String str) {
		String wordstr = "0123456789";
		if (wordstr.indexOf(str) > -1) {
			return true;
		}
		return false;
	}

	private void randomdigkey(Keyboard mKeyboard) {
		if (mKeyboard == null) {
			return;
		}

		List<Key> keyList = mKeyboard.getKeys();

		// 查找出0-9的数字键
		List<Key> newkeyList = new ArrayList<Key>();
		for (int i = 0, size = keyList.size(); i < size; i++) {
			Key key = keyList.get(i);
			CharSequence label = key.label;
			if (label != null && isNumber(label.toString())) {
				newkeyList.add(key);
			}
		}

		int count = newkeyList.size();

		List<KeyModel> resultList = new ArrayList<KeyModel>();

		LinkedList<KeyModel> temp = new LinkedList<KeyModel>();

		for (int i = 0; i < count; i++) {
			temp.add(new KeyModel(48 + i, i + ""));
		}

		Random rand = new SecureRandom();
		rand.setSeed(SystemClock.currentThreadTimeMillis());

		for (int i = 0; i < count; i++) {
			int num = rand.nextInt(count - i);
			KeyModel model = temp.get(num);
			resultList.add(new KeyModel(model.getCode(), model.getLable()));
			temp.remove(num);
		}

		for (int i = 0, size = newkeyList.size(); i < size; i++) {
			Key newKey = newkeyList.get(i);
			KeyModel resultmodle = resultList.get(i);
			newKey.label = resultmodle.getLable();
			newKey.codes[0] = resultmodle.getCode();
		}

	}

	class KeyModel {

		private Integer code;
		private String label;

		public KeyModel(Integer code, String lable) {
			this.code = code;
			this.label = lable;
		}

		public Integer getCode() {
			return code;
		}

		public void setCode(Integer code) {
			this.code = code;
		}

		public String getLable() {
			return label;
		}

		public void setLabel(String lable) {
			this.label = lable;
		}

	}

	/**
	 * 密度转换为像素值
	 * 
	 * @param dp
	 * @return
	 */
	public static int dpToPx(Context context, float dp) {
		final float scale = context.getResources().getDisplayMetrics().density;
		return (int) (dp * scale + 0.5f);
	}

	private void initScreenParams(Context context) {
		DisplayMetrics dMetrics = new DisplayMetrics();
		WindowManager windowManager = (WindowManager) context
				.getSystemService(Context.WINDOW_SERVICE);
		Display display = windowManager.getDefaultDisplay();
		display.getMetrics(dMetrics);

		screenw = dMetrics.widthPixels;
		screenh = dMetrics.heightPixels;
		density = dMetrics.density;
		densityDpi = dMetrics.densityDpi;

		screenh_nonavbar = screenh;

		int ver = Build.VERSION.SDK_INT;

		// 新版本的android 系统有导航栏,造成无法正确获取高度
		if (ver == 13) {
			try {
				Method mt = display.getClass().getMethod("getRealHeight");
				screenh_nonavbar = (Integer) mt.invoke(display);
			} catch (Exception e) {
			}
		} else if (ver > 13) {
			try {
				Method mt = display.getClass().getMethod("getRawHeight");
				screenh_nonavbar = (Integer) mt.invoke(display);
			} catch (Exception e) {
			}
		}

		real_scontenth = screenh_nonavbar - getStatusBarHeight(context);

	}

	/**
	 * 电量栏高度
	 * 
	 * @return
	 */
	public static int getStatusBarHeight(Context context) {
		Class<?> c = null;
		Object obj = null;
		Field field = null;
		int x = 0, sbar = 0;
		try {
			c = Class.forName("com.android.internal.R$dimen");
			obj = c.newInstance();
			field = c.getField("status_bar_height");
			x = Integer.parseInt(field.get(obj).toString());
			sbar = context.getResources().getDimensionPixelSize(x);
		} catch (Exception e1) {
			e1.printStackTrace();
		}

		return sbar;
	}

}


           

android软键盘设置

阅读数 176

没有更多推荐了,返回首页