Android에서 소프트웨어 (일명 "소프트") 키보드가 화면에 표시되는지 감지하는 방법이 있습니까?
Android에서 소프트웨어 (일명 "소프트") 키보드가 화면에 표시되는지 감지하는 방법이 있습니까?
답변:
직접적인 방법은 없습니다 . Android 팀의 Dianne Hackborn이 응답 한 http://groups.google.com/group/android-platform/browse_thread/thread/1728f26f2334c060/5e4910f0d9eb898a를 참조하십시오 . 그러나 #onMeasure에서 창 크기가 변경되었는지 확인하여 간접적으로이를 감지 할 수 있습니다. Android에서 소프트웨어 키보드의 가시성을 확인하는 방법을 참조하십시오 . .
이것은 나를 위해 작동합니다. 아마도 이것이 항상 모든 버전에 가장 적합한 방법 일 것 입니다 .
키보드 가시성의 속성을 만들고 onGlobalLayout 메소드가 여러 번 호출되므로 이러한 변경이 지연되는 것을 관찰하는 것이 효과적입니다. 또한 장치 회전을 확인하는 것이 좋지만 windowSoftInputMode
그렇지 않습니다 adjustNothing
.
boolean isKeyboardShowing = false;
void onKeyboardVisibilityChanged(boolean opened) {
print("keyboard " + opened);
}
// ContentView is the root view of the layout of this activity/fragment
contentView.getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
Rect r = new Rect();
contentView.getWindowVisibleDisplayFrame(r);
int screenHeight = contentView.getRootView().getHeight();
// r.bottom is the position above soft keypad or device button.
// if keypad is shown, the r.bottom is smaller than that before.
int keypadHeight = screenHeight - r.bottom;
Log.d(TAG, "keypadHeight = " + keypadHeight);
if (keypadHeight > screenHeight * 0.15) { // 0.15 ratio is perhaps enough to determine keypad height.
// keyboard is opened
if (!isKeyboardShowing) {
isKeyboardShowing = true
onKeyboardVisibilityChanged(true)
}
}
else {
// keyboard is closed
if (isKeyboardShowing) {
isKeyboardShowing = false
onKeyboardVisibilityChanged(false)
}
}
}
});
contentView
선언됩니까?
이 시도:
InputMethodManager imm = (InputMethodManager) getActivity()
.getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm.isAcceptingText()) {
writeToLog("Software Keyboard was shown");
} else {
writeToLog("Software Keyboard was not shown");
}
https://github.com/ravindu1024/android-keyboardlistener에 사용할 수있는 간단한 클래스를 만들었습니다 . 프로젝트에 복사하여 다음과 같이 사용하십시오.
KeyboardUtils.addKeyboardToggleListener(this, new KeyboardUtils.SoftKeyboardToggleListener()
{
@Override
public void onToggleSoftKeyboard(boolean isVisible)
{
Log.d("keyboard", "keyboard visible: "+isVisible);
}
});
rootView
이 경우 내 루트보기를 가리키는보기 일뿐입니다 relative layout
.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/addresses_confirm_root_view"
android:background="@color/WHITE_CLR">
RelativeLayout rootView = (RelativeLayout) findViewById(R.id.addresses_confirm_root_view);
getViewTreeObserver()
rootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
int heightDiff = rootView.getRootView().getHeight() - rootView.getHeight();
if (heightDiff > 100) {
Log.e("MyActivity", "keyboard opened");
} else {
Log.e("MyActivity", "keyboard closed");
}
}
});
1
. 문제 없어. 키보드의 실제 길이보다 작아야합니다
나는 이것을 기본으로 사용했습니다 : http://www.ninthavenue.com.au/how-to-check-if-the-software-keyboard-is-shown-in-android
/**
* To capture the result of IMM hide/show soft keyboard
*/
public class IMMResult extends ResultReceiver {
public int result = -1;
public IMMResult() {
super(null);
}
@Override
public void onReceiveResult(int r, Bundle data) {
result = r;
}
// poll result value for up to 500 milliseconds
public int getResult() {
try {
int sleep = 0;
while (result == -1 && sleep < 500) {
Thread.sleep(100);
sleep += 100;
}
} catch (InterruptedException e) {
Log.e("IMMResult", e.getMessage());
}
return result;
}
}
그런 다음이 방법을 썼습니다.
public boolean isSoftKeyboardShown(InputMethodManager imm, View v) {
IMMResult result = new IMMResult();
int res;
imm.showSoftInput(v, 0, result);
// if keyboard doesn't change, handle the keypress
res = result.getResult();
if (res == InputMethodManager.RESULT_UNCHANGED_SHOWN ||
res == InputMethodManager.RESULT_UNCHANGED_HIDDEN) {
return true;
}
else
return false;
}
그런 다음이를 사용하여 소프트 키보드를 열었을 수있는 모든 필드 (EditText, AutoCompleteTextView 등)를 테스트 할 수 있습니다.
InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
if(isSoftKeyboardShown(imm, editText1) | isSoftKeyboardShown(imm, autocompletetextview1))
//close the softkeyboard
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
물론 이상적인 솔루션은 아니지만 작업이 완료됩니다.
showSoftInput () 및 hideSoftInput ()의 콜백 결과를 사용하여 키보드 상태를 확인할 수 있습니다. 자세한 내용 및 예제 코드
http://www.ninthavenue.com.au/how-to-check-if-the-software-keyboard-is-shown-in-android
이 답변을 참조 할 수 있습니다-https : //.com/a/24105062/3629912
매번 나를 위해 일했습니다.
adb shell dumpsys window InputMethod | grep "mHasSurface"
소프트웨어 키보드가 표시되면 true를 반환합니다.
그래서 AccessibilityServices, 창 삽입물, 화면 높이 감지 등을 오랫동안 사용 해본 결과이 방법을 찾았습니다.
면책 조항 : Android에서는 숨겨진 방법을 사용하므로 일관성이 없을 수 있습니다. 그러나 내 테스트에서 작동하는 것 같습니다.
이 메소드는 InputMethodManager # getInputMethodWindowVisibleHeight () 이며 Lollipop (5.0)부터 존재합니다.
호출하면 현재 키보드의 높이를 픽셀 단위로 반환합니다. 이론적으로 키보드의 높이는 0 픽셀이 아니어야하므로 Kotlin에서 간단한 높이 검사를 수행했습니다.
val imm by lazy { context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager }
if (imm.inputMethodWindowVisibleHeight > 0) {
//keyboard is shown
else {
//keyboard is hidden
}
숨겨진 메소드를 호출 할 때 리플렉션을 피하기 위해 Android Hidden API 를 사용 합니다.
val imm by lazy { context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager }
val windowHeightMethod = InputMethodManager::class.java.getMethod("getInputMethodWindowVisibleHeight")
val height = windowHeightMethod.invoke(imm) as Int
//use the height val in your logic
이것은 내가 필요한 요구 사항에 비해 훨씬 덜 복잡했습니다. 이것이 도움이되기를 바랍니다.
MainActivity에서 :
public void dismissKeyboard(){
InputMethodManager imm =(InputMethodManager)this.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(mSearchBox.getWindowToken(), 0);
mKeyboardStatus = false;
}
public void showKeyboard(){
InputMethodManager imm =(InputMethodManager)this.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);
mKeyboardStatus = true;
}
private boolean isKeyboardActive(){
return mKeyboardStatus;
}
mKeyboardStatus의 기본 기본 부울 값은 false 로 초기화됩니다 .
그런 다음 다음과 같이 값을 확인하고 필요한 경우 조치를 수행하십시오.
mSearchBox.requestFocus();
if(!isKeyboardActive()){
showKeyboard();
}else{
dismissKeyboard();
}
키보드 상태를 확인해야하는 경우 작동합니다.
fun Activity.isKeyboardOpened(): Boolean {
val r = Rect()
val activityRoot = getActivityRoot()
val visibleThreshold = dip(UiUtils.KEYBOARD_VISIBLE_THRESHOLD_DP)
activityRoot.getWindowVisibleDisplayFrame(r)
val heightDiff = activityRoot.rootView.height - r.height()
return heightDiff > visibleThreshold;
}
fun Activity.getActivityRoot(): View {
return (findViewById<ViewGroup>(android.R.id.content)).getChildAt(0);
}
여기서 UiUtils.KEYBOARD_VISIBLE_THRESHOLD_DP
= 100 및 dip ()는 dpToPx를 변환하는 anko func입니다.
fun dip(value: Int): Int {
return (value * Resources.getSystem().displayMetrics.density).toInt()
}
다음과 같이 GlobalLayoutListener를 설정하여이 작업을 수행했습니다.
final View activityRootView = findViewById(R.id.activityRoot);
activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(
new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
int heightView = activityRootView.getHeight();
int widthView = activityRootView.getWidth();
if (1.0 * widthView / heightView > 3) {
//Make changes for Keyboard not visible
} else {
//Make changes for keyboard visible
}
}
});
KeyboardShown이 Shown이면이 코드를 사용해보십시오.이 함수는 true value ...를 반환합니다.
private final String TAG = "TextEditor";
private TextView mTextEditor;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_editor);
mTextEditor = (TextView) findViewById(R.id.text_editor);
mTextEditor.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
isKeyboardShown(mTextEditor.getRootView());
}
});
}
private boolean isKeyboardShown(View rootView) {
/* 128dp = 32dp * 4, minimum button height 32dp and generic 4 rows soft keyboard */
final int SOFT_KEYBOARD_HEIGHT_DP_THRESHOLD = 128;
Rect r = new Rect();
rootView.getWindowVisibleDisplayFrame(r);
DisplayMetrics dm = rootView.getResources().getDisplayMetrics();
/* heightDiff = rootView height - status bar height (r.top) - visible frame height (r.bottom - r.top) */
int heightDiff = rootView.getBottom() - r.bottom;
/* Threshold size: dp to pixels, multiply with display density */
boolean isKeyboardShown = heightDiff > SOFT_KEYBOARD_HEIGHT_DP_THRESHOLD * dm.density;
Log.d(TAG, "isKeyboardShown ? " + isKeyboardShown + ", heightDiff:" + heightDiff + ", density:" + dm.density
+ "root view height:" + rootView.getHeight() + ", rect:" + r);
return isKeyboardShown;
}
내 경우에는 내가 하나가 있었다 EditText
내가 오순절 와서, 그래서 내 레이아웃 관리 이 솔루션을. 기본적으로 EditText
초점을 듣고 초점이 변경되거나 뒤로 / 완료 단추를 누르면 로컬 브로드 캐스트를 보내는 사용자 지정 입니다. 당신이 더미를 배치해야하려면 View
귀하의 레이아웃 android:focusable="true"
과 android:focusableInTouchMode="true"
전화 할 때 때문에 clearFocus()
초점이 첫 번째 포커스보기로 재 할당됩니다. 더미 뷰의 예 :
<View
android:layout_width="1dp"
android:layout_height="1dp"
android:focusable="true"
android:focusableInTouchMode="true"/>
추가 정보
레이아웃 변경의 차이를 감지하는 솔루션은 화면 밀도에 크게 의존하기 때문에 잘 작동하지 않습니다 .100px는 특정 장치에서는 많을 수 있고 다른 장치에서는 오 탐지가 될 수 없기 때문입니다. 또한 벤더마다 키보드가 다릅니다.
안드로이드에서는 ADB 쉘을 통해 탐지 할 수 있습니다. 이 방법을 작성하고 사용했습니다.
{
JSch jsch = new JSch();
try {
Session session = jsch.getSession("<userName>", "<IP>", 22);
session.setPassword("<Password>");
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.connect();
ChannelExec channel = (ChannelExec)session.openChannel("exec");
BufferedReader in = new BufferedReader(new
InputStreamReader(channel.getInputStream()));
channel.setCommand("C:/Android/android-sdk/platform-tools/adb shell dumpsys window
InputMethod | findstr \"mHasSurface\"");
channel.connect();
String msg = null;
String msg2 = " mHasSurface=true";
while ((msg = in.readLine()) != null) {
Boolean isContain = msg.contains(msg2);
log.info(isContain);
if (isContain){
log.info("Hiding keyboard...");
driver.hideKeyboard();
}
else {
log.info("No need to hide keyboard.");
}
}
channel.disconnect();
session.disconnect();
} catch (JSchException | IOException | InterruptedException e) {
e.printStackTrace();
}
}
}
final View activityRootView = findViewById(R.id.rootlayout);
activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
Rect r = new Rect();
activityRootView.getWindowVisibleDisplayFrame(r);
int screenHeight = activityRootView.getRootView().getHeight();
Log.e("screenHeight", String.valueOf(screenHeight));
int heightDiff = screenHeight - (r.bottom - r.top);
Log.e("heightDiff", String.valueOf(heightDiff));
boolean visible = heightDiff > screenHeight / 3;
Log.e("visible", String.valueOf(visible));
if (visible) {
Toast.makeText(LabRegister.this, "I am here 1", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(LabRegister.this, "I am here 2", Toast.LENGTH_SHORT).show();
}
}
});
@ iWantScala의 답변은 훌륭하지만 저
rootView.getRootView().getHeight()
에게는 효과가 없습니다. 항상 동일한 값을 갖습니다.
한 가지 방법은 두 가지 변수를 정의하는 것입니다
private int maxRootViewHeight = 0;
private int currentRootViewHeight = 0;
글로벌 리스너 추가
rootView.getViewTreeObserver()
.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
currentRootViewHeight = rootView.getHeight();
if (currentRootViewHeight > maxRootViewHeight) {
maxRootViewHeight = currentRootViewHeight;
}
}
});
그런 다음 확인
if (currentRootViewHeight >= maxRootViewHeight) {
// Keyboard is hidden
} else {
// Keyboard is shown
}
잘 작동합니다
이제 Kotlin을 기반으로 Android R에서 시작하는 직접적인 방법이 있습니다.
val imeInsets = view.rootWindowInsets.getInsets(Type.ime())
if (imeInsets.isVisible) {
//Ime is visible
//Lets move our view by the height of the IME
view.translationX = imeInsets.bottom }
나는 비슷한 문제가 있었다. 화면의 Enter 버튼 (키보드를 숨겼습니다)에 반응해야했습니다. 이 경우 키보드가 열린 텍스트보기의 OnEditorAction을 편집 할 수 있습니다. 편집 가능한 상자가 여러 개인 경우 모든 상자를 구독하십시오.
활동에서 키보드를 완벽하게 제어 할 수 있으므로 모든 개폐 이벤트를 듣는 경우 키보드가 열렸는지 여부에 관계없이 어떤 시점에서도 문제에 직면하지 않습니다.
이것을 알아내는 직접적인 방법이 있습니다. 또한 레이아웃을 변경할 필요가 없습니다.
몰입 형 전체 화면 모드에서도 작동합니다.
그러나 불행히도 모든 장치에서 작동하지는 않습니다. 따라서 장치로 테스트해야합니다.
요령은 소프트 키보드를 숨기거나 표시하고 시도 결과를 캡처하는 것입니다.
올바르게 작동하면 키보드가 실제로 표시되거나 숨겨지지 않습니다. 우리는 단지 국가를 요구합니다.
최신 상태를 유지하려면 처리기를 사용하여 예를 들어 200 밀리 초마다이 작업을 반복하면됩니다.
아래 구현은 단일 검사 만 수행합니다.
여러 번 검사를 수행하는 경우 모든 (_keyboardVisible) 테스트를 활성화해야합니다.
public interface OnKeyboardShowHide
{
void onShowKeyboard( Object param );
void onHideKeyboard( Object param );
}
private static Handler _keyboardHandler = new Handler();
private boolean _keyboardVisible = false;
private OnKeyboardShowHide _keyboardCallback;
private Object _keyboardCallbackParam;
public void start( OnKeyboardShowHide callback, Object callbackParam )
{
_keyboardCallback = callback;
_keyboardCallbackParam = callbackParam;
//
View view = getCurrentFocus();
if (view != null)
{
InputMethodManager imm = (InputMethodManager) getSystemService( Activity.INPUT_METHOD_SERVICE );
imm.hideSoftInputFromWindow( view.getWindowToken(), InputMethodManager.HIDE_IMPLICIT_ONLY, _keyboardResultReceiver );
imm.showSoftInput( view, InputMethodManager.SHOW_IMPLICIT, _keyboardResultReceiver );
}
else // if (_keyboardVisible)
{
_keyboardVisible = false;
_keyboardCallback.onHideKeyboard( _keyboardCallbackParam );
}
}
private ResultReceiver _keyboardResultReceiver = new ResultReceiver( _keyboardHandler )
{
@Override
protected void onReceiveResult( int resultCode, Bundle resultData )
{
switch (resultCode)
{
case InputMethodManager.RESULT_SHOWN :
case InputMethodManager.RESULT_UNCHANGED_SHOWN :
// if (!_keyboardVisible)
{
_keyboardVisible = true;
_keyboardCallback.onShowKeyboard( _keyboardCallbackParam );
}
break;
case InputMethodManager.RESULT_HIDDEN :
case InputMethodManager.RESULT_UNCHANGED_HIDDEN :
// if (_keyboardVisible)
{
_keyboardVisible = false;
_keyboardCallback.onHideKeyboard( _keyboardCallbackParam );
}
break;
}
}
};
다음은 소프트 키보드가 표시되는지 확인하는 해결 방법입니다.
인기있는 키보드 중 일부는 classNames에 특정 키워드가 있습니다.
ActivityManager.RunningServiceInfo의 ClassNames에서 위 패턴을 확인하십시오. 또한 ActivityManager.RunningServiceInfo의 clientPackage = android는 키보드가 시스템에 바인딩되어 있음을 나타냅니다.
위에서 언급 한 정보를 결합하여 소프트 키보드가 보이는지 엄격하게 알 수 있습니다.
아시다시피 안드로이드 소프트웨어 키보드는 입력이 가능한 경우에만 표시됩니다. 다시 말해 키보드는 EditText에 포커스가있을 때만 표시됩니다. 즉, OnFocusChangeListener 를 사용하여 키보드가 보이는 날씨를 얻을 수 있습니다 .
//Declare this Globally
public boolean isKeyBoardVisible = false;
//In OnCreate *[For Activity]*, OnCreateView *[For Fragment]*
text_send.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if(hasFocus)
isKeyBoardVisible = true;
else
isKeyBoardVisible = false;
}
});
이제 클래스의 어느 곳에서나 isKeyBoardVisible 변수 를 사용 하여 키보드가 열려 있거나없는 날씨를 얻을 수 있습니다. 그것은 나를 위해 잘 작동했습니다.
참고 : 이 프로세스는 OnFocusChangeListener를 호출하지 않기 때문에 InputMethodManager를 사용하여 프로그래밍 방식으로 키보드를 열면 작동 하지 않습니다.
답변을 kotlin으로 변환했습니다. 이것이 kotlin 사용자에게 도움이되기를 바랍니다.
private fun checkKeyboardVisibility() {
var isKeyboardShowing = false
binding.coordinator.viewTreeObserver.addOnGlobalLayoutListener {
val r = Rect()
binding.coordinator.getWindowVisibleDisplayFrame(r)
val screenHeight = binding.coordinator.rootView.height
// r.bottom is the position above soft keypad or device button.
// if keypad is shown, the r.bottom is smaller than that before.
val keypadHeight = screenHeight - r.bottom
if (keypadHeight > screenHeight * 0.15) { // 0.15 ratio is perhaps enough to determine keypad height.
// keyboard is opened
if (!isKeyboardShowing) {
isKeyboardShowing = true
}
} else {
// keyboard is closed
if (isKeyboardShowing) {
isKeyboardShowing = false
}
}
}
}
adjustNothing 플래그와 함께 작동하며 수명주기 이벤트가 사용됩니다. Kotlin과 함께 :
/**
* This class uses a PopupWindow to calculate the window height when the floating keyboard is opened and closed
*
* @param activity The parent activity
* The root activity that uses this KeyboardManager
*/
class KeyboardManager(private val activity: AppCompatActivity) : PopupWindow(activity), LifecycleObserver {
private var observerList = mutableListOf<((keyboardTop: Int) -> Unit)>()
/** The last value of keyboardTop */
private var keyboardTop: Int = 0
/** The view that is used to calculate the keyboard top */
private val popupView: View?
/** The parent view */
private var parentView: View
var isKeyboardShown = false
private set
/**
* Create transparent view which will be stretched over to the full screen
*/
private fun createFullScreenView(): View {
val view = LinearLayout(activity)
view.layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT)
view.background = ColorDrawable(Color.TRANSPARENT)
return view
}
init {
this.popupView = createFullScreenView()
contentView = popupView
softInputMode = LayoutParams.SOFT_INPUT_ADJUST_RESIZE or LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE
inputMethodMode = INPUT_METHOD_NEEDED
parentView = activity.findViewById(android.R.id.content)
width = 0
height = LayoutParams.MATCH_PARENT
popupView.viewTreeObserver.addOnGlobalLayoutListener {
val rect = Rect()
popupView.getWindowVisibleDisplayFrame(rect)
val keyboardTop = rect.bottom
if (this.keyboardTop != keyboardTop) {
isKeyboardShown = keyboardTop < this.keyboardTop
this.keyboardTop = keyboardTop
observerList.forEach { it(keyboardTop) }
}
}
activity.lifecycle.addObserver(this)
}
/**
* This must be called after the onResume of the Activity or inside view.post { } .
* PopupWindows are not allowed to be registered before the onResume has finished
* of the Activity
*/
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
fun start() {
parentView.post {
if (!isShowing && parentView.windowToken != null) {
setBackgroundDrawable(ColorDrawable(0))
showAtLocation(parentView, Gravity.NO_GRAVITY, 0, 0)
}
}
}
/**
* This manager will not be used anymore
*/
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
fun close() {
activity.lifecycle.removeObserver(this)
observerList.clear()
dismiss()
}
/**
* Set the keyboard top observer. The observer will be notified when the keyboard top has changed.
* For example when the keyboard is opened or closed
*
* @param observer The observer to be added to this provider
*/
fun registerKeyboardTopObserver(observer: (keyboardTop: Int) -> Unit) {
observerList.add(observer)
}
}
항상 키보드 위에서 볼 수있는 유용한 방법
fun KeyboardManager.updateBottomMarginIfKeyboardShown(
view: View,
activity: AppCompatActivity,
// marginBottom of view when keyboard is hide
marginBottomHideKeyboard: Int,
// marginBottom of view when keybouard is shown
marginBottomShowKeyboard: Int
) {
registerKeyboardTopObserver { bottomKeyboard ->
val bottomView = ViewUtils.getFullViewBounds(view).bottom
val maxHeight = ScreenUtils.getFullScreenSize(activity.windowManager).y
// Check that view is within the window size
if (bottomView < maxHeight) {
if (bottomKeyboard < bottomView) {
ViewUtils.updateMargin(view, bottomMargin = bottomView - bottomKeyboard +
view.marginBottom + marginBottomShowKeyboard)
} else ViewUtils.updateMargin(view, bottomMargin = marginBottomHideKeyboard)
}
}
}
getFullViewBounds
fun getLocationOnScreen(view: View): Point {
val location = IntArray(2)
view.getLocationOnScreen(location)
return Point(location[0], location[1])
}
fun getFullViewBounds(view: View): Rect {
val location = getLocationOnScreen(view)
return Rect(location.x, location.y, location.x + view.width,
location.y + view.height)
}
어디서 getFullScreenSize
fun getFullScreenSize(wm: WindowManager? = null) =
getScreenSize(wm) { getRealSize(it) }
private fun getScreenSize(wm: WindowManager? = null, block: Display.(Point) -> Unit): Point {
val windowManager = wm ?: App.INSTANCE.getSystemService(Context.WINDOW_SERVICE)
as WindowManager
val point = Point()
windowManager.defaultDisplay.block(point)
return point
}
여기서 updateMargin
fun updateMargin(
view: View,
leftMargin: Int? = null,
topMargin: Int? = null,
rightMargin: Int? = null,
bottomMargin: Int? = null
) {
val layoutParams = view.layoutParams as ViewGroup.MarginLayoutParams
if (leftMargin != null) layoutParams.leftMargin = leftMargin
if (topMargin != null) layoutParams.topMargin = topMargin
if (rightMargin != null) layoutParams.rightMargin = rightMargin
if (bottomMargin != null) layoutParams.bottomMargin = bottomMargin
view.layoutParams = layoutParams
}
나는 이것을 다음과 같이했지만, 당신의 목표가 keyboad를 닫고 여는 것이라면 만 가능합니다.
닫기 예 : (키보드가 이미 닫혀 있는지 확인-닫지 않은 경우)
imm.showSoftInput(etSearch, InputMethodManager.HIDE_IMPLICIT_ONLY, new ResultReceiver(null) {
@Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
super.onReceiveResult(resultCode, resultData);
if (resultCode != InputMethodManager.RESULT_UNCHANGED_HIDDEN)
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
}
});
a를 사용 중일 수 있습니다.
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Log.d(
getClass().getSimpleName(),
String.format("conf: %s", newConfig));
if (newConfig.hardKeyboardHidden != hardKeyboardHidden) {
onHardwareKeyboardChange(newConfig.hardKeyboardHidden);
hardKeyboardHidden = newConfig.hardKeyboardHidden;
}
if (newConfig.keyboardHidden != keyboardHidden) {
onKeyboardChange(newConfig.keyboardHidden);
keyboardHidden = newConfig.hardKeyboardHidden;
}
}
public static final int KEYBOARDHIDDEN_UNDEFINED = 0;
public static final int KEYBOARDHIDDEN_NO = 1;
public static final int KEYBOARDHIDDEN_YES = 2;
public static final int KEYBOARDHIDDEN_SOFT = 3;
//todo
private void onKeyboardChange(int keyboardHidden) {
}
//todo
private void onHardwareKeyboardChange(int hardKeyboardHidden) {
}