300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > 史上最全:安卓监听软键盘打开或者关闭

史上最全:安卓监听软键盘打开或者关闭

时间:2024-01-23 02:40:15

相关推荐

史上最全:安卓监听软键盘打开或者关闭

史上最全:安卓监听软键盘打开或者关闭

SoftKeyboard open and close listener in an activity in Android?

问题:我有一个Activity,里面有5个EditText。当用户点击第一个EditText,软键盘打来,然后可以输入一些值。我翔在软件版打开的时候,设置其他View的不可见,当软键盘关闭的时候其他View课件。

说白了就是对软键盘的事件进行更新。

到底安卓立有没有类似的listener或者callback甚至是一些技巧呢?

我总结了一下一共有3中方法,期中又简单也有复杂的。

方法1

对于某些场景,可以使用一些比较丑陋的代码,但也可以算是黑科技。

可能为你的EditText**设置焦点监听**就足够了

yourEditText.setOnFocusChangeListener(new OnFocusChangeListener() {@Overridepublic void onFocusChange(View v, boolean hasFocus) {if (hasFocus) {//got focus} else {//lost focus}}});

方法2

下面的方法只有在你的清单文件中,把Activity的android:windowSoftInputMode属性设置为adjustResize才有用。你可以使用Layout listener去观察你的根布局的大小是否改变。

首先你要创建一个BaseAvtivity

public class BaseActivity extends Activity {private ViewTreeObserver.OnGlobalLayoutListener keyboardLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener() {@Overridepublic void onGlobalLayout() {int heightDiff = rootLayout.getRootView().getHeight() - rootLayout.getHeight();int contentViewTop = getWindow().findViewById(Window.ID_ANDROID_CONTENT).getTop();LocalBroadcastManager broadcastManager = LocalBroadcastManager.getInstance(BaseActivity.this);if(heightDiff <= contentViewTop){onHideKeyboard();Intent intent = new Intent("KeyboardWillHide");broadcastManager.sendBroadcast(intent);} else {int keyboardHeight = heightDiff - contentViewTop;onShowKeyboard(keyboardHeight);Intent intent = new Intent("KeyboardWillShow");intent.putExtra("KeyboardHeight", keyboardHeight);broadcastManager.sendBroadcast(intent);}}};private boolean keyboardListenersAttached = false;private ViewGroup rootLayout;protected void onShowKeyboard(int keyboardHeight) {}protected void onHideKeyboard() {}protected void attachKeyboardListeners() {if (keyboardListenersAttached) {return;}rootLayout = (ViewGroup) findViewById(R.id.rootLayout);rootLayout.getViewTreeObserver().addOnGlobalLayoutListener(keyboardLayoutListener);keyboardListenersAttached = true;}@Overrideprotected void onDestroy() {super.onDestroy();if (keyboardListenersAttached) {rootLayout.getViewTreeObserver().removeGlobalOnLayoutListener(keyboardLayoutListener);}}}

让你的Activity继承BaseActivity

public class TestActivity extends BaseActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.test_activity);attachKeyboardListeners();}@Overrideprotected void onShowKeyboard(int keyboardHeight) {// do things when keyboard is shownbottomContainer.setVisibility(View.GONE);}@Overrideprotected void onHideKeyboard() {// do things when keyboard is hiddenbottomContainer.setVisibility(View.VISIBLE);} }

方法3

Android给你提供的大量的api,这些api提供的大量可以重写的方法,这些方法涵盖了你可能遇到的大量的时间。所以说大部分时间你都不用去担心。但soft ketyboard并不是这样。它可以轻松的展示或者隐藏,但没有方法去监听它。下面是一个解决方案。

创建一个SoftKeyboard

import java.util.ArrayList;import java.util.List;import java.util.concurrent.atomic.AtomicBoolean;import android.os.Handler;import android.os.Message;import android.view.View;import android.view.ViewGroup;import android.view.inputmethod.InputMethodManager;import android.widget.EditText;public class SoftKeyboard implements View.OnFocusChangeListener{private static final int CLEAR_FOCUS = 0;private ViewGroup layout;private int layoutBottom;private InputMethodManager im;private int[] coords;private boolean isKeyboardShow;private SoftKeyboardChangesThread softKeyboardThread;private List<EditText> editTextList;private View tempView; // reference to a focused EditTextpublic SoftKeyboard(ViewGroup layout, InputMethodManager im){this.layout = layout;keyboardHideByDefault();initEditTexts(layout);this.im = im;this.coords = new int[2];this.isKeyboardShow = false;this.softKeyboardThread = new SoftKeyboardChangesThread();this.softKeyboardThread.start();}public void openSoftKeyboard(){if(!isKeyboardShow){layoutBottom = getLayoutCoordinates();im.toggleSoftInput(0, InputMethodManager.SHOW_IMPLICIT);softKeyboardThread.keyboardOpened();isKeyboardShow = true;}}public void closeSoftKeyboard(){if(isKeyboardShow){im.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0);isKeyboardShow = false;}}public void setSoftKeyboardCallback(SoftKeyboardChanged mCallback){softKeyboardThread.setCallback(mCallback);}public void unRegisterSoftKeyboardCallback(){softKeyboardThread.stopThread();}public interface SoftKeyboardChanged {public void onSoftKeyboardHide();public void onSoftKeyboardShow(); }private int getLayoutCoordinates(){layout.getLocationOnScreen(coords);return coords[1] + layout.getHeight();}private void keyboardHideByDefault(){layout.setFocusable(true);layout.setFocusableInTouchMode(true);}/** InitEditTexts 处理嵌套在view里的edittext* 感谢 Francesco Verheye (verheye.francesco@)*/private void initEditTexts(ViewGroup viewgroup) {if(editTextList == null)editTextList = new ArrayList<EditText>();int childCount = viewgroup.getChildCount();for(int i=0; i<= childCount-1;i++) {View v = viewgroup.getChildAt(i);if(v instanceof ViewGroup) {initEditTexts((ViewGroup) v);}if(v instanceof EditText) {EditText editText = (EditText) v;editText.setOnFocusChangeListener(this);editText.setCursorVisible(true);editTextList.add(editText);}}}/** 当keyboard展示的时候,OnFocusChange 更新 tempView * Thanks to Israel Dominguez (dominguez.israel@)*/@Overridepublic void onFocusChange(View v, boolean hasFocus) {if(hasFocus) {tempView = v;if(!isKeyboardShow) {layoutBottom = getLayoutCoordinates();softKeyboardThread.keyboardOpened();isKeyboardShow = true;}}}// 将会取消Edittext的焦点private final Handler mHandler = new Handler(){@Overridepublic void handleMessage(Message m){switch(m.what){case CLEAR_FOCUS:if(tempView != null){tempView.clearFocus();tempView = null;}break;}}};private class SoftKeyboardChangesThread extends Thread{private AtomicBoolean started;private SoftKeyboardChanged mCallback;public SoftKeyboardChangesThread(){started = new AtomicBoolean(true);}public void setCallback(SoftKeyboardChanged mCallback){this.mCallback = mCallback;}@Overridepublic void run(){while(started.get()){// 等待,知道软键盘请求打卡synchronized(this){try {wait();} catch (InterruptedException e) {e.printStackTrace();}}int currentBottomLocation = getLayoutCoordinates();// 在调用打开软键盘函数和真正显示,有一些时间差while(currentBottomLocation == layoutBottom && started.get()){currentBottomLocation = getLayoutCoordinates();}if(started.get())mCallback.onSoftKeyboardShow();// 当键盘打开,出事下底部的位置比layoutBottom更好 // 在有些情况下等价于layoutBottom// 这会破坏之前的逻辑,所以我加上新的循环while(currentBottomLocation >= layoutBottom && started.get()){currentBottomLocation = getLayoutCoordinates();}// 现在键盘已经显示,继续检查Layout的尺寸,直到键盘关闭while(currentBottomLocation != layoutBottom && started.get()){synchronized(this){try {wait(500);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}currentBottomLocation = getLayoutCoordinates();}if(started.get())mCallback.onSoftKeyboardHide();// 如果 keyboard 已经打开if(isKeyboardShow && started.get())isKeyboardShow = false;// 如果一个EditText获得焦点,移除它焦点(在UI县城中)if(started.get())mHandler.obtainMessage(CLEAR_FOCUS).sendToTarget();} }public void keyboardOpened(){synchronized(this){notify();}}public void stopThread(){synchronized(this){started.set(false);notify();}}}}

下面是简单的一个例子

RelativeLayout mainLayout = findViewById(R.layout.main_layout); // You must use the layout rootInputMethodManager im = (InputMethodManager) getSystemService(Service.INPUT_METHOD_SERVICE);/*Instantiate and pass a callback*/SoftKeyboard softKeyboard;softKeyboard = new SoftKeyboard(mainLayout, im);softKeyboard.setSoftKeyboardCallback(new SoftKeyboard.SoftKeyboardChanged(){@Overridepublic void onSoftKeyboardHide() {// Code here}@Overridepublic void onSoftKeyboardShow() {// Code here} });/*Open or close the soft keyboard easily*/softKeyboard.openSoftKeyboard();softKeyboard.closeSoftKeyboard();/* Prevent memory leaks:*/@Overridepublic void onDestroy(){super.onDestroy();softKeyboard.unRegisterSoftKeyboardCallback();}

希望对你有帮助

参考自stackoverflow,以及felhr

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。