经过 研究 实现了自定义 键盘 ,支持随意拖动 和数字及其他字符输入
下面是主要的代码 和使用方法
import android.content.Context;
import android.util.Log;import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.LinearLayout;
import com.only.onlybiapp.AppContext;
import com.only.onlybiapp.R;
import com.only.onlybiapp.interfaces.IKeyBoardListener;
// 这个是自定义的键盘控件
public class NumKeyBoardLinearLayout extends LinearLayout implements
View.OnClickListener, OnGestureListener {
private Context mContext;
private View v;
private Button button_numkeyboard_one;// 数字一
private Button button_numkeyboard_two;// 数字二
private Button button_numkeyboard_three;// 数字三
private Button button_numkeyboard_four;// 数字四
private Button button_numkeyboard_five;// 数字五
private Button button_numkeyboard_six;// 数字六
private Button button_numkeyboard_seven;// 数字七
private Button button_numkeyboard_eight;// 数字八
private Button button_numkeyboard_nine;// 数字九
private Button button_numkeyboard_comma;// 符号逗号
private Button button_numkeyboard_zero;// 数字零
private Button button_numkeyboard_point;// 符号点
private Button button_numkeyboard_scale;// 符号百分比
private Button button_numkeyboard_zeros;// 数字两个零
private Button button_numkeyboard_clear;// 清空
private Button button_numkeyboard_comfirm;// 确认
boolean isMoveEvent = false; // 是否是拖动输入法
private float startX = 0; // the first pointer index of x coordinate
private float startY = 0; // the first pointer index of Y coordinate
private float x;// the coordinate of X
private float y;// the coordinate of Y
private IKeyBoardListener iKeyBoardListener;
private final int fromLeft = -535; // 可以根据屏幕分辨率进行调整
private boolean isAdd = false;
GestureDetector detector;
public IKeyBoardListener getiKeyBoardListener() {
return iKeyBoardListener;
}
public void setiKeyBoardListener(IKeyBoardListener iKeyBoardListener) {
if (iKeyBoardListener != this.iKeyBoardListener) { // 换了一个editText
this.iKeyBoardListener = iKeyBoardListener;
}
}
private WindowManager wm = (WindowManager) getContext()
.getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
private WindowManager.LayoutParams wmlp = AppContext.getLayoutParams();
public NumKeyBoardLinearLayout(Context context) {
super(context);
this.mContext = context;
initView();
initData();
setListener();
}
private void initView() {
v = View.inflate(mContext, R.layout.layout_numkeyboardview_drafting,
this);
button_numkeyboard_one = (Button) v
.findViewById(R.id.button_numkeyboardview_one);
button_numkeyboard_two = (Button) v
.findViewById(R.id.button_numkeyboardview_two);
button_numkeyboard_three = (Button) v
.findViewById(R.id.button_numkeyboardview_three);
button_numkeyboard_four = (Button) v
.findViewById(R.id.button_numkeyboardview_four);
button_numkeyboard_five = (Button) v
.findViewById(R.id.button_numkeyboardview_five);
button_numkeyboard_six = (Button) v
.findViewById(R.id.button_numkeyboardview_six);
button_numkeyboard_seven = (Button) v
.findViewById(R.id.button_numkeyboardview_seven);
button_numkeyboard_eight = (Button) v
.findViewById(R.id.button_numkeyboardview_eight);
button_numkeyboard_nine = (Button) v
.findViewById(R.id.button_numkeyboardview_nine);
button_numkeyboard_comma = (Button) v
.findViewById(R.id.button_numkeyboardview_comma);
button_numkeyboard_zero = (Button) v
.findViewById(R.id.button_numkeyboardview_zero);
button_numkeyboard_point = (Button) v
.findViewById(R.id.button_numkeyboardview_point);
button_numkeyboard_scale = (Button) v
.findViewById(R.id.button_numkeyboardview_scale);
button_numkeyboard_zeros = (Button) v
.findViewById(R.id.button_numkeyboardview_zeros);
button_numkeyboard_clear = (Button) v
.findViewById(R.id.button_numkeyboardview_clear);
button_numkeyboard_comfirm = (Button) v
.findViewById(R.id.button_numkeyboardview_comfirm);
}
private void initData() {
detector = new GestureDetector(mContext, this);
}
private void setListener() {
button_numkeyboard_one.setOnClickListener(this);
button_numkeyboard_two.setOnClickListener(this);
button_numkeyboard_three.setOnClickListener(this);
button_numkeyboard_four.setOnClickListener(this);
button_numkeyboard_five.setOnClickListener(this);
button_numkeyboard_six.setOnClickListener(this);
button_numkeyboard_seven.setOnClickListener(this);
button_numkeyboard_eight.setOnClickListener(this);
button_numkeyboard_nine.setOnClickListener(this);
button_numkeyboard_comma.setOnClickListener(this);
button_numkeyboard_zero.setOnClickListener(this);
button_numkeyboard_point.setOnClickListener(this);
button_numkeyboard_scale.setOnClickListener(this);
button_numkeyboard_zeros.setOnClickListener(this);
button_numkeyboard_clear.setOnClickListener(this);
button_numkeyboard_clear
.setOnLongClickListener(new OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
if (iKeyBoardListener != null) {
iKeyBoardListener.onLongClick();
}
return false;
}
});
button_numkeyboard_comfirm.setOnClickListener(this);
}
@Override
public void onClick(View v) {
if (v == button_numkeyboard_comfirm) {
dissmiss();
} else if (v == button_numkeyboard_clear) {
delete();
} else {
setvalue(v);
}
}
private void delete() {
if (iKeyBoardListener != null) {
iKeyBoardListener.delete();
}
}
public void dissmiss() {
if (isAdd) {
isAdd = false;
wm.removeView(this);
if (iKeyBoardListener != null) {
iKeyBoardListener.onFilish();
}
}
}
private void setvalue(View view) {
String zifu = (String) view.getTag();
if (iKeyBoardListener != null) {
iKeyBoardListener.insert(zifu);
}
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
startX = ev.getX();
startY = ev.getY();
break;
case MotionEvent.ACTION_MOVE:
float x = ev.getX();
float y = ev.getY();
float dx = x - startX;
float dy = y - startY;
// 滑动大于一定距离才判定为用户的拖动意愿
if (Math.abs(dx) > 11 || Math.abs(dy) > 11) {
isMoveEvent = true;
return onTouchEvent(ev);
} else {
// 进入这里表明用户在点击时候的轻微拖动,我们不认为这是用户有意的移动
}
break;
case MotionEvent.ACTION_UP:
// 如果是用户的拖动行为,当用户提起手指时候,该行为结束
if (isMoveEvent) {
isMoveEvent = false;
return true;
}
break;
default:
break;
}
return super.dispatchTouchEvent(ev);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
return true;
case MotionEvent.ACTION_UP:
break;
default:
break;
}
return super.onInterceptTouchEvent(ev);
}
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_MOVE:
if (isMoveEvent) {
Log.v("onTouchEvent", "移动");
x = event.getRawX();
y = event.getRawY() - 25; // 25 the height of the status bar
updateViewPosition();
}
break;
case MotionEvent.ACTION_UP:
if (isMoveEvent) {
// updateViewPosition(); // 注释掉,未做仔细思考
startX = startY = 0;
}
break;
default:
break;
}
return false;
}
private void updateViewPosition() {
wmlp.x = (int) (fromLeft + (x - startX));
wmlp.y = (int) (y - startY);
wm.updateViewLayout(v, wmlp);
Log.v("updateViewPosition", "真的移动了 ");
}
public void addMySelfToWindow() {
wmlp.type = 2002;
wmlp.format = 1;
wmlp.flags |= 8;
wmlp.gravity = Gravity.CENTER | Gravity.TOP;
wmlp.x = 0;
wmlp.y = 0;
wmlp.width = 260;
wmlp.height = 355;
wm.addView(this, wmlp);
isAdd = true;
}
@Override
public boolean onDown(MotionEvent e) {
// TODO Auto-generated method stub
return false;
}
@Override
public void onShowPress(MotionEvent e) {
// TODO Auto-generated method stub
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
float distanceY) {
// TODO Auto-generated method stub
return false;
}
@Override
public void onLongPress(MotionEvent e) {
// TODO Auto-generated method stub
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
if (Math.abs(e1.getX() - e2.getX()) > 10
|| Math.abs(e1.getY() - e2.getY()) > 10) {
Log.e("TAG", "onFling");
return true;
}
return false;
}
}
// 这个是实现字符输入 及其他功能的接口
/**
* 接口名:IKeyBoardListener <br/>
* 作者:yldu <br/>
* 自定义键盘接口 实现 editText 文字的插入 删除 结束输入 以及长按清除<br/>
* 创建日期 2014年-06-11 <br/>
*/
public interface IKeyBoardListener {
/**
* 插入字符
*
* @param ch
* 要插入的字符
*/
public void insert(String ch);
/**
* 结束输入
*/
public void onFilish();
/**
* 删除一个字符
*/
public void delete();
/**
* 长按清除 editText 内文字
*/
public void onLongClick();
}
// 这个是 使用方式
给 需要实现自定义键盘支持的editText 设置 OnTouch 监听就行了 下面是 Ontouch 方法的具体实现
// 这个是添加自定义键盘到你所在的页面 其中keyboad 就是 NumKeyBoardLinearLayout 的实例
@Override
public boolean onTouch(View v, MotionEvent event) {
final EditText editText = (EditText) v;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: // 禁用系统的输入法
if (android.os.Build.VERSION.SDK_INT <= 10) {
editText.setInputType(InputType.TYPE_NULL);
} else {
((Activity) mContext)
.getWindow()
.setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
try {
Class<EditText> cls = EditText.class;
Method setShowSoftInputOnFocus;
setShowSoftInputOnFocus = cls.getMethod(
"setShowSoftInputOnFocus", boolean.class);
setShowSoftInputOnFocus.setAccessible(true);
setShowSoftInputOnFocus.invoke(editText, false);
} catch (Exception e) {
e.printStackTrace();
}
}
break;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
keyboad.setiKeyBoardListener(new IKeyBoardListener() {
@Override
public void insert(String text) {
int cursor = editText.getSelectionStart();
editText.getText().insert(cursor, text);
}
@Override
public void onFilish() {
hasInstance = false;
}
@Override
public void onLongClick() {
editText.getText().clear();
}
@Override
public void delete() {
int cursor = editText.getSelectionStart();
if (cursor > 0) {
editText.getText().delete(cursor - 1, cursor);
}
}
});
if (!hasInstance) { // 这个是添加自定义键盘到你所在的页面 keyboad 就是 NumKeyBoardLinearLayout 的实例
hasInstance = true;
keyboad.addMySelfToWindow();
}
break;
default:
break;
}
return false;
}