最近工作中有一个批量录入的功能,使用的是ListView + EditText组合。由于业务的需要,所以需要自己编写一个符合我们业务需求的软键盘。
刚好Android 中也提供了自定义键盘。经过一些案例,自定义键盘ok啦!但是ListView上的edittext使用自定义键盘,那么焦点输入没法像系统软键盘一样快速定位显示输入的文本。此时有一种方案,那就是ListView对应的适配器提供一个回调接口,将我们点击触发的edittext对象传递给KeyboardView(自定义键盘)对象。这个是否就可以将自定义键盘输入的文本快速显示到点击触发的edittext文本框上。这里思路就介绍到这里了,下面就请大家看代码吧!
main.xml :
<?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" >
<ListView
android:id="@+id/lv_demo"
android:layout_weight="1"
android:layout_width="match_parent"
android:dividerHeight="1dp"
android:divider="@android:color/white"
android:layout_height="match_parent"
/>
<android.inputmethodservice.KeyboardView
android:id="@+id/keyboard_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/keyboard_bg"
android:focusable="true"
android:focusableInTouchMode="true"
android:keyBackground="@drawable/new_keyboard_bg"
android:keyTextColor="#000000"
android:layout_weight="0"
android:visibility="gone" />
</LinearLayout>
KeydemoActivity :
public class KeydemoActivity extends Activity{
private static final String TAG = KeydemoActivity.class.getSimpleName();
private Context ctx;
private Activity act;
private ListView lvDemo;
private ListEditorAdapter adapter;
private KeyboardView keyboard_view;
/**
* 上一个edittext
*/
private EditText preEdit;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
lvDemo = (ListView) findViewById(R.id.lv_demo);
keyboard_view = (KeyboardView) findViewById(R.id.keyboard_view);
ctx = this;
act = this;
KeyObj ko1 = new KeyObj();
ko1.setName("crystal1");
ko1.setValue("1");
ko1.setValue2("2");
KeyObj ko2 = new KeyObj();
ko2.setName("crystal2");
ko2.setValue("2");
ko2.setValue2("4");
KeyObj ko3 = new KeyObj();
ko3.setName("crystal3");
ko3.setValue("3");
ko3.setValue2("6");
KeyObj ko4 = new KeyObj();
ko4.setName("crystal4");
ko4.setValue("4");
ko4.setValue2("8");
KeyObj ko5 = new KeyObj();
ko5.setName("crystal5");
ko5.setValue("5");
ko5.setValue2("10");
KeyObj ko6 = new KeyObj();
ko6.setName("crystal6");
ko6.setValue("6");
ko6.setValue2("12");
KeyObj ko7 = new KeyObj();
ko7.setName("crystal7");
ko7.setValue("7");
ko7.setValue2("14");
Map<String,Object> map = new HashMap<String, Object>();
map.put("crystal1", ko1);
map.put("crystal2", ko2);
map.put("crystal3", ko3);
map.put("crystal4", ko4);
map.put("crystal5", ko5);
map.put("crystal6", ko6);
map.put("crystal7", ko7);
List<String> list = new ArrayList<String>();
list.add("crystal1");
list.add("crystal2");
list.add("crystal3");
list.add("crystal4");
list.add("crystal5");
list.add("crystal6");
list.add("crystal7");
adapter = new ListEditorAdapter(KeydemoActivity.this, map,list);
lvDemo.setAdapter(adapter);
adapter.setItemListener(new ListEditorAdapter.ItemOnClickListener() {
@Override
public void itemOnClickListener(View view) {
if(preEdit != null) preEdit.setBackgroundDrawable(getResources().getDrawable(R.drawable.bg_edittext_normal));
}EditText edit = (EditText) view;edit.setBackgroundDrawable(getResources().getDrawable(R.drawable.bg_edittext_focused));new KeyboardUtil(keyboard_view, KeydemoActivity.this, edit).showKeyboard();
preEdit = edit;
}
});
}
}
KeyObj:
public class KeyObj {
private String name;
private String value;
private String value2;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getValue2() {
return value2;
}
public void setValue2(String value2) {
this.value2 = value2;
}
}
ListEditorAdapter :
public class ListEditorAdapter extends BaseAdapter {
private static final String TAG = ListEditorAdapter.class.getSimpleName();
private Context mContext;
private LayoutInflater mInflater;
private ViewHolder holder = null;
private Map<String,Object> map;
private List<String> list;
public ListEditorAdapter(Context context, Map<String,Object> paramMap,List<String> paramList) {
this.mContext = context;
this.map = paramMap;
this.list = paramList;
mInflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
private Integer index = -1;
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.listview_item, null);
holder.name = (TextView) convertView
.findViewById(R.id.name);
holder.value = (EditText) convertView
.findViewById(R.id.value);
holder.value2 = (EditText) convertView
.findViewById(R.id.value2);
holder.value.setTag(position);
holder.value2.setTag(position);
class MyTextWatcher implements TextWatcher {
public MyTextWatcher(ViewHolder holder) {
mHolder = holder;
}
private ViewHolder mHolder;
@Override
public void onTextChanged(CharSequence s, int start,
int before, int count) {
}
@Override
public void beforeTextChanged(CharSequence s, int start,
int count, int after) {
}
@Override
public void afterTextChanged(Editable s) {
if (s != null && !"".equals(s.toString())) {
int position = (Integer) mHolder.value.getTag();
String key = list.get(position);
if(map.containsKey(key)){
((KeyObj)map.get(key)).setValue(s.toString());
}else{
KeyObj ko = new KeyObj();
ko.setName(key);
ko.setValue(s.toString());
map.put(key, ko);
}
}
}
}
class MyTextWatcher2 implements TextWatcher {
public MyTextWatcher2(ViewHolder holder) {
mHolder = holder;
}
private ViewHolder mHolder;
@Override
public void onTextChanged(CharSequence s, int start,
int before, int count) {
}
@Override
public void beforeTextChanged(CharSequence s, int start,
int count, int after) {
}
@Override
public void afterTextChanged(Editable s) {
if (s != null && !"".equals(s.toString())) {
int position = (Integer) mHolder.value2.getTag();
String key = list.get(position);
if(map.containsKey(key)){
((KeyObj)map.get(key)).setValue2(s.toString());
}else{
KeyObj ko = new KeyObj();
ko.setName(key);
ko.setValue2(s.toString());
map.put(key, ko);
}
}
}
}
holder.value.addTextChangedListener(new MyTextWatcher(holder));
holder.value2.addTextChangedListener(new MyTextWatcher2(holder));
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
holder.value.setTag(position);
holder.value2.setTag(position);
}
String name = ((KeyObj)map.get(list.get(position))).getName();
if (name != null) {
holder.name.setText((String) name);
}
String value = ((KeyObj)map.get(list.get(position))).getValue();
if (value != null) {
holder.value.setText((String) value);
}
String value2 = ((KeyObj)map.get(list.get(position))).getValue2();
if (value2 != null) {
holder.value2.setText((String) value2);
}
holder.value.setOnClickListener(IClicklistener);
holder.value2.setOnClickListener(IClicklistener);
return convertView;
}
//此处定义接口,提供给activity回调,获取点击的edittext对象,传递给自定义键盘KeyboardView
private OnClickListener IClicklistener = new OnClickListener() {
@Override
public void onClick(View v) {
mOnClickListener.itemOnClickListener(v);
}
};
private ItemOnClickListener mOnClickListener;
public void setItemListener(ItemOnClickListener listener) {
mOnClickListener = listener;
}
public interface ItemOnClickListener {
void itemOnClickListener(View view);
}
public class ViewHolder {
public TextView name;
public EditText value; // ListView中的输入
public EditText value2; // ListView中的输入
}
}
KeyboardUtil :
public class KeyboardUtil {
/*private Activity mActivity;*/
@SuppressWarnings("unused")
private Context mContext;
@SuppressWarnings("unused")
private KeyboardView keyboardView;
private Keyboard keyAlp;// 字母键盘
private Keyboard keyDig;// 数字键盘
private Keyboard k3;// 符号键盘
public boolean isnun = false;// 是否数字键盘
public boolean isupper = false;// 是否大写
private EditText ed;
public KeyboardUtil(KeyboardView kbView,Context mContext, EditText edit) {
this.mContext = mContext;
this.ed = edit;
keyAlp = new Keyboard(mContext, R.xml.qwerty);
keyDig = new Keyboard(mContext, R.xml.symbols);
k3 = new Keyboard(mContext, R.xml.sign);
this.keyboardView = kbView;
keyboardView.setKeyboard(keyDig);
keyboardView.setEnabled(true);
keyboardView.setPreviewEnabled(true);
keyboardView.setOnKeyboardActionListener(listener);
}
private OnKeyboardActionListener listener = new OnKeyboardActionListener() {
@Override
public void swipeUp() {
}
@Override
public void swipeRight() {
}
@Override
public void swipeLeft() {
}
@Override
public void swipeDown() {
}
@Override
public void onText(CharSequence text) {
}
@Override
public void onRelease(int primaryCode) {
}
@Override
public void onPress(int primaryCode) {
}
@Override
public void onKey(int primaryCode, int[] keyCodes) {
Editable editable = ed.getText();
ed.setSelection(editable.length());
int start = ed.getSelectionStart();
if (primaryCode == Keyboard.KEYCODE_CANCEL) {// 完成
ed.setBackgroundDrawable(mContext.getResources().getDrawable(R.drawable.bg_edittext_normal));
hideKeyboard();
} else if (primaryCode == Keyboard.KEYCODE_DELETE) {// 回退
if (!TextUtils.isEmpty(editable)) {
if (start > 0) {
editable.delete(start - 1, start);
}
}
} else if (primaryCode == Keyboard.KEYCODE_SHIFT) {// 大小写切换
changeKey();
keyboardView.setKeyboard(keyAlp);
} else if (primaryCode == Keyboard.KEYCODE_MODE_CHANGE) {// 数字键盘切换
if (isnun) {
isnun = false;
keyboardView.setKeyboard(keyAlp);
} else {
isnun = true;
randomdigkey();
}
}else if(primaryCode == -999){
keyboardView.setKeyboard(k3);
}else {
editable.insert(start, Character.toString((char) primaryCode));
}
}
};
/**
* 键盘大小写切换
*/
private void changeKey() {
List<Key> keylist = keyAlp.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;
}
}
}
}
public void showKeyboard() {
int visibility = keyboardView.getVisibility();
if (visibility == View.GONE || visibility == View.INVISIBLE) {
keyboardView.setVisibility(View.VISIBLE);
}
}
public void hideKeyboard() {
int visibility = keyboardView.getVisibility();
if (visibility == View.VISIBLE) {
keyboardView.setVisibility(View.GONE);
}
}
private boolean isNumber(String str) {
String wordstr = "0123456789";
if (wordstr.indexOf(str) > -1) {
return true;
}
return false;
}
private boolean isword(String str) {
String wordstr = "abcdefghijklmnopqrstuvwxyz";
if (wordstr.indexOf(str.toLowerCase()) > -1) {
return true;
}
return false;
}
private void randomdigkey(){
List<Key> keyList = keyDig.getKeys();
// 查找出0-9的数字键
List<Key> newkeyList = new ArrayList<Key>();
for (int i = 0; i < keyList.size(); i++) {
if (keyList.get(i).label != null
&& isNumber(keyList.get(i).label.toString())) {
newkeyList.add(keyList.get(i));
}
}
// 数组长度
int count = newkeyList.size();
// 结果集
List<KeyModel> resultList = new ArrayList<KeyModel>();
// 用一个LinkedList作为中介
LinkedList<KeyModel> temp = new LinkedList<KeyModel>();
// 初始化temp
for (int i = 0; i < count; i++) {
temp.add(new KeyModel(48 + i, i + ""));
}
// 取数
Random rand = new Random();
for (int i = 0; i < count; i++) {
int num = rand.nextInt(count - i);
resultList.add(new KeyModel(temp.get(num).getCode(),
temp.get(num).getLable()));
temp.remove(num);
}
for (int i = 0; i < newkeyList.size(); i++) {
newkeyList.get(i).label = resultList.get(i).getLable();
newkeyList.get(i).codes[0] = resultList.get(i)
.getCode();
}
keyboardView.setKeyboard(keyDig);
}
private void randomalpkey(){
List<Key> keyList = keyAlp.getKeys();
// 查找出a-z的数字键
List<Key> newkeyList = new ArrayList<Key>();
for (int i = 0; i < keyList.size(); i++) {
if (keyList.get(i).label != null
&& isword(keyList.get(i).label.toString())) {
newkeyList.add(keyList.get(i));
}
}
// 数组长度
int count = newkeyList.size();
// 结果集
List<KeyModel> resultList = new ArrayList<KeyModel>();
// 用一个LinkedList作为中介
LinkedList<KeyModel> temp = new LinkedList<KeyModel>();
// 初始化temp
for (int i = 0; i < count; i++) {
temp.add(new KeyModel(97 + i, "" + (char) (97 + i)));
}
// 取数
Random rand = new Random();
for (int i = 0; i < count; i++) {
int num = rand.nextInt(count - i);
resultList.add(new KeyModel(temp.get(num).getCode(),
temp.get(num).getLable()));
temp.remove(num);
}
for (int i = 0; i < newkeyList.size(); i++) {
newkeyList.get(i).label = resultList.get(i).getLable();
newkeyList.get(i).codes[0] = resultList.get(i)
.getCode();
}
keyboardView.setKeyboard(keyAlp);
}
}
源码: