Android 自定义的数字键盘 支持随意拖动 和稳定的字符输入的控件

java 同时被 3 个专栏收录
9 篇文章 0 订阅
42 篇文章 0 订阅
1 篇文章 0 订阅


经过 研究 实现了自定义 键盘 ,支持随意拖动 和数字及其他字符输入 

下面是主要的代码 和使用方法


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;
}


  • 1
    点赞
  • 6
    评论
  • 0
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

评论 6 您还未登录,请先 登录 后发表或查看评论
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页

打赏作者

龙哥1997

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值