您的位置:首页 > 移动开发 > Android开发

Android机型适配之软键盘和输入法

2013-06-10 17:16 288 查看
Android机型适配问题是不少Android开发人员转ios开发的原因,因为,Android机型实在是太多了,各大门派纷纷定制rom,碎片化相当严重。以下是我总结的一些些资料

一、软键盘显隐问题

定义一个mIMManager = (InputMethodManager) mDescEt.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);

// 隐藏键盘
private void hideKeyboard() {
mIMManager.hideSoftInputFromWindow(this.mDescEt.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}

// 显示键盘
private void showKeyboard() {
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
if (getActivity() != null) {
((InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE)).showSoftInput(
mDescEt, InputMethodManager.SHOW_IMPLICIT);
}
}

}, 100);

因为有时候用了((InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE)).showSoftInput(mDescEt, InputMethodManager.SHOW_IMPLICIT)不一定会跟预料中一样弹出软键盘,所以可以把这段代码放到handler里面

有时候还是不能解决,可以对某个view(一般是EditText类型)绑定OnFocusChangeListener,然后override onFocusChange方法

public void onFocusChange(View v, boolean hasFocus) {
// TODO Auto-generated method stub
if (hasFocus) {
showKeyboard();
} else {
// close keyboard
if (getActivity() != null) {
((InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE))
.hideSoftInputFromWindow(v.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}

}
}

这段代码意思是,当该view有焦点时,弹出软键盘,失去焦点时,收起软键盘,

如果一进来需要弹出来,可以在onResume里面这样写

mDescEt.clearFocus();

mDescEt.requestFocus();

即先清除焦点,然后获得焦点,这样肯定触发onFocusChange方法,所以弹出软键盘。如果你的程序是用Fragment写的而不是Activity,在Fragment跳转时,会有一个bug,即软件盘死活弹不出来,那么上面的代码很有效

二、判断软键盘的收起还是弹出?

自定义一个布局DbIMERelativeLayout,like this

<com.example.view.DbIMERelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

<--! your code--!>

</com.example.view.DbIMERelativeLayout>

DbIMERelativeLayout 类继承自RelativeLayout,定义了一个接口SoftInputMethodStatusListener ,里面有两个抽象方法,即onSoftInputMethodHidden表示收起状态,onSoftInputMethodShown表示弹出状态。其中total参数表示当前屏幕高度,current是除了软键盘之外的view的高度(如果软键盘弹出来,current = total-height,如果没弹出来,current = total, height是软键盘高度,根据不同输入法和手机不一样,有的
输入法很高)

public class DbIMERelativeLayout extends RelativeLayout {

private static final String TAG = "DbIMERelativeLayout";

private WindowManager mWindowManager = null;

private SoftInputMethodStatusListener mSoftInputMethodStatusListener;

private int mStatusBarHeight = 0;

public interface SoftInputMethodStatusListener {
void onSoftInputMethodHidden(int total, int current);

void onSoftInputMethodShown(int total, int current);
}

public DbIMERelativeLayout(Context context, AttributeSet attrs) {
super(context, attrs);
mWindowManager = (WindowManager) context.getApplicationContext()
.getSystemService(Context.WINDOW_SERVICE);
}

public void setSoftKeyboardStatusListener(SoftInputMethodStatusListener l) {
mSoftInputMethodStatusListener = l;
}

@Override
public void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
// get the available height
int screenHeight = mWindowManager.getDefaultDisplay().getHeight();
if(mStatusBarHeight == 0) {
Rect outRect = new Rect();
this.getWindowVisibleDisplayFrame(outRect);
mStatusBarHeight = outRect.top;
}

int availableHeight = screenHeight - mStatusBarHeight;

// check whether the virtual keyboard is showing
if (h < availableHeight) {
if (mSoftInputMethodStatusListener != null) {
LOGD("SoftInputMethod is Shown >>>>>>");
mSoftInputMethodStatusListener.onSoftInputMethodShown(availableHeight, h);
}
} else {
if (mSoftInputMethodStatusListener != null) {
LOGD("SoftInputMethod is Hidden <<<<<<");
mSoftInputMethodStatusListener.onSoftInputMethodHidden(availableHeight, h);
}
}
}

private void LOGD(String message) {
if(!TextUtils.isEmpty(message)) {
DebugLog.d(TAG, message);
}
}

}

在activity中继承SoftInputMethodStatusListener 接口,然后override 这两个方法

@Override
public void onSoftInputMethodHidden(int total, int current) {
//do something
}

public void onSoftInputMethodShown(int total, int current) {

               //do something
}

三、判断输入法的类型,以三星输入法为例

private static final String SUFFIX_SAMSUNG_KEYBORAD = ".SamsungKeypad".toLowerCase();

if (mIMManager != null) {
try {
Field field = InputMethodManager.class.getDeclaredField("mCurId");
if (field != null) {
field.setAccessible(true);
String curId = (String) field.get(mIMManager);
if (curId != null && curId.toLowerCase().endsWith(SUFFIX_SAMSUNG_KEYBORAD)) {
// 对三星键盘做适配,在onTextChanged处理
return;
}
}
} catch (Exception e) {
LOGD("Get mCurId failed...");
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息