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...");
}
}
一、软键盘显隐问题
定义一个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...");
}
}
相关文章推荐
- android自动弹出软键盘(输入法)
- Android 点击屏幕空白处收起输入法软键盘(手动打开)
- 【转】Android点击空白区域,隐藏输入法软键盘
- Android机型适配
- android 双卡 双待机型适配
- 【Android适配问题集锦-文件类】获取Android机型设备信息的适配差异问题
- 【移动开发】 Android隐藏输入法软键盘的一些说明
- android:windowSoftInputMode 属性(输入法软键盘的那点事)
- android 多分辨率机型适配文件夹命名规则
- android开发(45) 自定义软键盘(输入法)
- Android机型适配之痛
- Android软键盘(输入法)使用大杂烩:避免进入页面EditText自动弹出软键盘-2013.11.08更新
- android如何在activity启动的时候隐藏输入法软键盘?
- android安卓屏蔽禁用系统输入法,自定义软键盘,解决EditText光标问题demo
- Android项目:输入法软键盘显示/隐藏的监听和控制,InputMethodManager用法研究
- Android图片剪裁-调用系统实现,完美适配魅族等机型
- Android上常见度量单位【xdpi、hdpi、mdpi、ldpi】解读,Android分辨率,Android多机型适配,Android屏幕分类,Android像素单位
- Android 拍照和图库功能(适配Android 6.0和7.0系统和华为机型问题)
- android5.X新特性--适配5.0以下的机型
- Android碎片化难题:手游兼容性测试应该适配哪些机型?