經過 研究 實現了自定義 鍵盤 ,支持隨意拖動 和數字及其他字符輸入
下面是主要的代碼 和使用方法
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
* 作者:yldu
* 自定義鍵盤接口 實現 editText 文字的插入 刪除 結束輸入 以及長按清除
* 創建日期 2014年-06-11
*/
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 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;
}