Computer >> 컴퓨터 >  >> 프로그래밍 >> Android

Android에서 가상 키보드(소프트 키보드) 표시 여부를 확인하는 방법

Android 앱을 개발하다 보면 특정 액티비티에서 키보드가 현재 화면에 표시되어 있는지 확인해야 하는 경우가 종종 있습니다. 예를 들어 키보드가 열릴 때 UI 요소 위치를 조정하거나, 특정 동작을 수행하기 전에 키보드 상태를 파악해야 할 수 있습니다.

이 글에서는 ViewTreeObservergetWindowVisibleDisplayFrame() 메서드를 활용하여 Android에서 가상 키보드(소프트 키보드)의 표시 여부를 감지하는 방법을 단계별로 살펴보겠습니다.

1단계: 새 프로젝트 생성

Android Studio에서 File → New Project를 선택한 후, 필요한 정보를 모두 입력하여 새 프로젝트를 생성합니다.

2단계: 레이아웃 파일 작성

다음 코드를 res/layout/activity_main.xml에 추가합니다. 화면 상단에는 EditText, 중앙에는 키보드를 숨기는 버튼이 배치됩니다.

<?xml version = "1.0" encoding = "utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android = "https://schemas.android.com/apk/res/android"
    xmlns:app = "https://schemas.android.com/apk/res-auto"
    xmlns:tools = "https://schemas.android.com/tools"
    android:layout_width = "match_parent"
    android:layout_height = "match_parent"
    android:id = "@+id/rootview"
    tools:context = ".MainActivity">
    <EditText
        android:id = "@+id/editext"
        android:layout_width = "match_parent"
        android:layout_height = "wrap_content">
    </EditText>
    <Button
        android:id = "@+id/button"
        android:layout_width = "wrap_content"
        android:layout_height = "wrap_content"
        android:text = "Click here to hide"
        app:layout_constraintBottom_toBottomOf = "parent"
        app:layout_constraintLeft_toLeftOf = "parent"
        app:layout_constraintRight_toRightOf = "parent"
        app:layout_constraintTop_toTopOf = "parent" />
</android.support.constraint.ConstraintLayout>

3단계: MainActivity 작성

다음 코드를 src/MainActivity.java에 추가합니다. 핵심은 루트 뷰에 OnGlobalLayoutListener를 등록하여 뷰 계층 구조 변화를 실시간으로 감지하는 것입니다.

import android.graphics.Rect;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.RequiresApi;
import android.support.constraint.ConstraintLayout;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    ConstraintLayout constraintLayout;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button = findViewById(R.id.button);
        EditText editText=findViewById(R.id.editext);
        editText.requestFocus();
        constraintLayout=findViewById(R.id.rootview);
        constraintLayout.getViewTreeObserver().addOnGlobalLayoutListener(new                 ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                Rect r = new Rect();
                constraintLayout.getWindowVisibleDisplayFrame(r);
                int screenHeight = constraintLayout.getRootView().getHeight();
                int keypadHeight = screenHeight - r.bottom;
                if (keypadHeight > screenHeight * 0.15) {
                    Toast.makeText(MainActivity.this,"Keyboard is showing",Toast.LENGTH_LONG).show();
                } else {
                    Toast.makeText(MainActivity.this,"keyboard closed",Toast.LENGTH_LONG).show();
                }
            }
        });
        button.setOnClickListener(this);
    }
    @RequiresApi(api = Build.VERSION_CODES.O)
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.button:
            hideSoftkeybard(v);
            break;
        }
    }
    private void hideSoftkeybard(View v) {
        InputMethodManager inputMethodManager = (InputMethodManager)         getSystemService(INPUT_METHOD_SERVICE);
        inputMethodManager.hideSoftInputFromWindow(v.getWindowToken(), 0);
    }
}

코드 핵심 로직 설명

위 코드에서는 ViewTreeObserver 리스너를 사용하여 해당 액티비티에서 발생하는 뷰 그룹의 변화를 감지합니다. 이 옵저버 안에서 다음 코드로 루트 엘리먼트의 전체 높이를 구할 수 있습니다.

int screenHeight = constraintLayout.getRootView().getHeight();

그다음, 아래와 같이 키보드 높이를 계산합니다. 화면에서 실제로 보이는 영역의 하단 좌표를 전체 화면 높이에서 빼면 키보드가 차지하는 높이가 나옵니다.

Rect r = new Rect();
constraintLayout.getWindowVisibleDisplayFrame(r);
int keypadHeight = screenHeight - r.bottom;

마지막으로 계산된 키보드 높이를 화면 전체 높이와 비교합니다. 일반적으로 키보드는 화면 높이의 15% 이상을 차지하므로, 이 값을 기준으로 표시 여부를 판단합니다.

if (keypadHeight > screenHeight * 0.15) {
    Toast.makeText(MainActivity.this,"Keyboard is showing",Toast.LENGTH_LONG).show();
} else {
    Toast.makeText(MainActivity.this,"keyboard closed",Toast.LENGTH_LONG).show();
}

4단계: AndroidManifest.xml 설정

아래와 같이 AndroidManifest.xml 파일에 코드를 추가합니다.

<?xml version = "1.0" encoding = "utf-8"?>
<manifest xmlns:android = "https://schemas.android.com/apk/res/android"
package = "com.example.andy.myapplication">
    <application
        android:allowBackup = "true"
        android:icon = "@mipmap/ic_launcher"
        android:label = "@string/app_name"
        android:roundIcon = "@mipmap/ic_launcher_round"
        android:supportsRtl = "true"
        android:theme = "@style/AppTheme">
        <activity android:name = ".MainActivity"
            android:windowSoftInputMode = "stateAlwaysVisible">
            <intent-filter>
                <action android:name = "android.intent.action.MAIN" />
                <category android:name = "android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

위 코드에서는 windowSoftInputMode 속성을 stateAlwaysVisible로 설정했습니다. 이렇게 하면 EditText가 포커스를 받는 즉시 키보드가 자동으로 나타나므로, 키보드 감지 기능을 바로 테스트하기에 좋습니다.

앱 실행 및 결과 확인

이제 애플리케이션을 실행해 보겠습니다. 실제 Android 모바일 기기가 컴퓨터에 연결되어 있다고 가정합니다. Android Studio에서 프로젝트의 액티비티 파일 중 하나를 연 뒤, 툴바에서 Android에서 가상 키보드(소프트 키보드) 표시 여부를 확인하는 방법 실행 아이콘을 클릭하세요. 목록에서 본인의 모바일 기기를 선택하면, 기기 화면에 앱의 기본 화면이 표시됩니다.

Android에서 가상 키보드(소프트 키보드) 표시 여부를 확인하는 방법

위 출력 결과에서 키보드가 화면에 표시되면 "Keyboard is showing"(키보드가 표시 중입니다)이라는 메시지가 토스트로 나타납니다.

Android에서 가상 키보드(소프트 키보드) 표시 여부를 확인하는 방법

반대로 버튼을 눌러 키보드를 숨기면 위 화면과 같이 "Keyboard closed"(키보드가 닫혔습니다)라는 메시지가 표시되는 것을 확인할 수 있습니다.

마무리

이처럼 ViewTreeObserver.OnGlobalLayoutListenergetWindowVisibleDisplayFrame()을 조합하면 Android에서 소프트 키보드의 표시 여부를 간단하게 감지할 수 있습니다. 이 방법은 키보드 등장 시 화면 요소를 재배치하거나, 채팅 앱처럼 키보드 상태에 따라 UI를 동적으로 조정해야 하는 경우에 매우 유용하게 활용됩니다.