حذف، نمایش و مدیریت کیبورد اندروید

در این جلسه از سری مباحث آموزش برنامه نویسی اندروید قصد دارم نحوه مخفی کردن و نمایش کیبورد (Keyboard) سیستم عامل اندروید را بررسی کنم. همچنین در ادامه آموزش از کتابخانه‌ای استفاده خواهیم کرد که علاوه بر مخفی کردن و نمایش کیبورد، رویداد مربوطه را به ما اعلام می‌کند.

مدیریت کیبورد اندروید

به نام خدا. اگر برنامه نویس و توسعه دهنده موبایل و بخصوص اندروید هستید به احتمال زیاد با چالش نمایش کیبورد هنگام عدم نیاز به آن، روبرو شده‌اید. یا اینکه بخشی از برنامه شما باید به صورتی پیاده سازی شود که یک یا چند عملیات بر اساس وضعیت کیبورد، یعنی مخفی یا نمایان بودن آن انجام شود.

مدیریت، حذف و نمایش کیبورد در برنامه نویسی اندروید

در این آموزش ابتدا نحوه حذف کیبورد توسط کلاس InputMethodManager را بررسی کرده و در قسمت بعد، با استفاده از کتابخانه KeyboardVisibilityEvent علاوه بر امکان حذف و نمایش کیبورد، یک شنونده (Listener) نیز برای شنود رویداد حذف و ظاهر شدن کیبورد تعریف می‌کنیم.
طبق مبحث آموزش ساخت پروژه در اندروید استودیو یک پروژه اندرویدی با نام KeyboardManagement می‌سازم. اکتیویتی را از نوع Empty Activity و زبان را Java انتخاب کردم.

حذف و نمایش کیبورد اندروید توسط کلاس InputMethodManager

برای مثال یک فرم عضویت را درنظر بگیرید. طبیعتا بعد از اینکه کاربر اطلاعات لازم را وارد کرده و روی دکمه ثبت نام ضربه بزند، نیازی به باز ماندن کیبورد نیست و عدم مخفی شدن آن، برای کاربر ایجاد مزاحمت کرده که از لحاظ تجربه کاربری (UX) یک آیتم منفی محسوب می‌گردد. بنابراین باید کاری کنیم تا به محض کلیک کردن کاربر روی Button ثبت نام، کیبورد مخفی شود.
در layout اکتیویتی سه ویجت از نوع TextView، EditText و Button تعریف می‌کنم:

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/txt_result"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:text="متن پیش فرض"
        android:textSize="22sp" />

    <EditText
        android:id="@+id/txt_input"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:id="@+id/submit_btn"
        android:text="ثبت" />

</LinearLayout>

در مرحله بعد یک Listener برای دکمه تعریف می‌کنم به صورتی که متن وارد شده در EditText را روی TextView ست می‌کند:

MainActivity.java

package ir.android_studio.keyboardmanagement;

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    TextView txtResult;
    EditText txtInput;
    Button btnSubmit;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        txtResult = findViewById(R.id.txt_result);
        txtInput = findViewById(R.id.txt_input);
        btnSubmit = findViewById(R.id.submit_btn);

        btnSubmit.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                String userText = txtInput.getText().toString();
                txtResult.setText(userText);

            }
        });

    }
}

پروژه را اجرا کرده و یک متن آزمایشی ثبت می‌کنم:

اجرای پروژه اندرویدی مخفی کردن و نمایش کیبورد نرم افزاری سیستم عامل اندروید

پروژه اندرویدی مخفی کردن و نمایش کیبورد نرم افزاری سیستم عامل اندروید

ملاحظه می‌کنید بعد از پایان کار همچنان کیبورد نمایش داده می‌شود.
برای مخفی کردن کیبورد یک متد با نام دلخواه closeKeyboard به اکتیویتی و بعد از متد onCreate اضافه می‌کنم:

private void closeKeyboard() {

    View focusView = this.getCurrentFocus();
    if (focusView != null) {
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(focusView.getWindowToken(), 0);
    }

}

در خط نخست، view ای که روی آن focus (تمرکز) شده را در یک متغیر از جنس View ذخیره می‌کنم. من نام این متغیر را focusView انتخاب کردم. بنابراین در پروژه فعلی ما، هنگامی که کاربر روی EditText کلیک می‌کند، این view ذخیره می‌شود. در ادامه یک شرط تعریف شده که ابتدا بررسی می‌کند focusView برابر با null نباشد. یعنی چنانچه هیچ view ای در حالت focus قرار نگرفته باشد، کدهای درون این شرط اجرا نخواهد شد.
درون این شرط یک نمونه از کلاس InputMethodManager با نام imm ساخته‌ام. در خط آخر، توسط متد hideSoftInputFromWindow این کلاس، SoftInput یا به عبارتی همان کیبورد (ورودی نرم افزاری) مخفی (hide) می‌شود.
در نهایت، متد را در Listener دکمه فراخوانی می‌کنم:

btnSubmit.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {

        String userText = txtInput.getText().toString();
        txtResult.setText(userText);
        closeKeyboard();

    }
});

کد کامل اکتیویتی:

MainActivity.java

package ir.android_studio.keyboardmanagement;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    TextView txtResult;
    EditText txtInput;
    Button btnSubmit;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        txtResult = findViewById(R.id.txt_result);
        txtInput = findViewById(R.id.txt_input);
        btnSubmit = findViewById(R.id.submit_btn);

        btnSubmit.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                String userText = txtInput.getText().toString();
                txtResult.setText(userText);
                closeKeyboard();

            }
        });

    }

    private void closeKeyboard() {

        View focusView = this.getCurrentFocus();
        if (focusView != null) {
            InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(focusView.getWindowToken(), 0);
        }

    }

}

پروژه را دوباره اجرا می‌کنم:

مخفی یا حذف کردن کیبورد در اندروید توسط کلاس InputMethodManager

حالا بلافاصله بعد از کلیک روی دکمه ثبت، کیبوردی که به واسطه focus شدن روی EditText باز شده بود، مخفی شد.

مدیریت کیبورد اندروید توسط کتابخانه KeyboardVisibilityEvent

در قسمت قبل بدون استفاده از کتابخانه و صرفا توسط کلاس داخلی اندروید، کیبورد را مخفی کردیم. اما در این قسمت برای مدیریت کیبورد نرم افزاری اندروید از کتابخانه KeyboardVisibilityEvent استفاده می‌کنیم که علاوه بر امکان نمایش دادن یا مخفی کردن کیبورد، به رویداد باز یا بسته شدن کیبورد هم می‌توانیم گوش دهیم. یعنی این کتابخانه مخفی و ظاهر شدن کیبورد را گزارش می‌دهد که در برخی موارد ممکن است توسعه دهنده به آن نیاز داشته باشد.
آدرس معرفی کتابخانه در گیت هاب:

https://github.com/yshrsmz/KeyboardVisibilityEvent

طبق توضیحات صفحه گیت هاب کتابخانه برای افزودن آن به پروژه باید خط زیر را در build.gradle اضافه کنم:

implementation 'net.yslibrary.keyboardvisibilityevent:keyboardvisibilityevent:LATEST_VERSION'
نکته: بجای LATEST_VERSION باید عدد آخرین نسخه کتابخانه را جایگزین کنیم. نسخه فعلی کتابخانه (در زمان تهیه این آموزش) در قسمت The latest version نمایش داده شده است. یعنی ۳٫۰٫۰-RC2:

افزودن کتابخانه KeyboardVisibilityEvent به پروژه اندروید در اندروید استودیو

البته نیاز به نوشتن دستی ورژن کتابخانه نیست و با کلیک روی آن، به این لینک هدایت می‌شویم که در قسمت Maven build settings (گزینه Gradle) خط زیر نمایش داده می‌شود:

implementation 'net.yslibrary.keyboardvisibilityevent:keyboardvisibilityevent:3.0.0-RC2'

پروژه را سینک می‌کنم تا کتابخانه اضافه شود.

مخفی کردن و نمایش کیبورد

برای مخفی کردن کیبورد کافیست خط زیر را در متد Listener دکمه بجای متد closeKeyboard اضافه کنم:

UIUtil.hideKeyboard(MainActivity.this);

UIUtil یکی از کلاس‌های کتابخانه است. متد hideKeyboard این کتابخانه، کیبورد را مخفی می‌کند. علاوه بر این، متد showKeyboard عمل خلاف متد قبل، یعنی نمایش کیبورد را انجام می‌دهد. البته در حالت عادی، با focus شدن کاربر روی یک EditText کیبورد به طور خودکار نمایش داده می‌شود اما ممکن است استثنائاتی وجود داشته باشد که لازم باشد اندروید را وادار به نمایش کیبورد کنیم. این متد بر خلاف متد hideKeyboard که فقط یک پارامتر ورودی دارد، پارامتر دوم هم باید وارد شود که نام EditText مدنظر ماست. این متد را به onCreate اکتیویتی اضافه کردم:

UIUtil.showKeyboard(MainActivity.this, txtInput);

گوش دادن به رویداد حذف یا ظاهر شدن کیبورد

با استفاده از متد setEventListener کلاس KeyboardVisibilityEvent این کتابخانه، به صورت زیر یک متد با نام onVisibilityChanged ساخته می‌شود:

KeyboardVisibilityEvent.setEventListener(this, new KeyboardVisibilityEventListener() {
    @Override
    public void onVisibilityChanged(boolean b) {

    }
});

تغییر وضعیت کیبورد از طریق پارامتر b دریافت می‌شود. برای نمایش خروجی این متد، یک شرط تعریف می‌کنم که خروجی هر حالت در قالب یک Toast ظاهر می‌شود:
KeyboardVisibilityEvent.setEventListener(this, new KeyboardVisibilityEventListener() {
    @Override
    public void onVisibilityChanged(boolean b) {

        if (b) {
            Toast.makeText(MainActivity.this, "کیبورد ظاهر شد", Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(MainActivity.this, "کیبورد حذف شد", Toast.LENGTH_SHORT).show();
        }

    }
});

کد کامل اکتیویتی:

MainActivity.java

package ir.android_studio.keyboardmanagement;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import net.yslibrary.android.keyboardvisibilityevent.KeyboardVisibilityEvent;
import net.yslibrary.android.keyboardvisibilityevent.KeyboardVisibilityEventListener;
import net.yslibrary.android.keyboardvisibilityevent.util.UIUtil;

public class MainActivity extends AppCompatActivity {

    TextView txtResult;
    EditText txtInput;
    Button btnSubmit;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        txtResult = findViewById(R.id.txt_result);
        txtInput = findViewById(R.id.txt_input);
        btnSubmit = findViewById(R.id.submit_btn);

        UIUtil.showKeyboard(MainActivity.this, txtInput);

        btnSubmit.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                String userText = txtInput.getText().toString();
                txtResult.setText(userText);
                //closeKeyboard();
                UIUtil.hideKeyboard(MainActivity.this);

            }
        });

        KeyboardVisibilityEvent.setEventListener(this, new KeyboardVisibilityEventListener() {
            @Override
            public void onVisibilityChanged(boolean b) {

                if (b) {
                    Toast.makeText(MainActivity.this, "کیبورد ظاهر شد", Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(MainActivity.this, "کیبورد حذف شد", Toast.LENGTH_SHORT).show();
                }

            }
        });

    }

    private void closeKeyboard() {

        View focusView = this.getCurrentFocus();
        if (focusView != null) {
            InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(focusView.getWindowToken(), 0);
            imm.showSoftInput(focusView, 0);
        }

    }

}

پروژه را اجرا می‌کنم:

رویداد ظاهر شدن کیبورد اندروید در کتابخانه KeyboardVisibilityEvent

رویداد مخفی شدن کیبورد اندروید در کتابخانه KeyboardVisibilityEvent

مشاهده می‌کنید پیغام‌های “کیبورد ظاهر شد” و “کیبورد حذف شد” در زمان مناسب نمایش داده شده است.
موفق و پیروز باشید.

مطالعه‌ی بیشتر:

https://developer.android.com/reference/android/content/Context#INPUT_METHOD_SERVICE
https://developer.android.com/reference/android/app/Activity#getCurrentFocus()

توجه : سورس پروژه درون پوشه Exercises قرار دارد

دانلود نسخه PDF این آموزش به همراه سورس پروژه
تعداد صفحات : ۱۲
حجم : ۱ مگابایت
قیمت : رایگان
دانلود رایگان با حجم ۱ مگابایت لینک کمکی
این مطلب چقدر برایتان مفید بود؟ لطفا امتیاز دهید
3.8/5 - (62 امتیاز)
پرسش‌ها و دیدگاه‌های کاربران
دوره آموزش برنامه نویسی اندروید
دوره آموزش برنامه نویسی اندروید

با دریافت این دوره به تمامی آموزش‌های غیر رایگان و رایگان موجود در وب سایت دسترسی دارید که تخفیفی برای آموزش‌های غیر رایگان نیز درنظر گرفته شده. این پکیج به دو صورت دانلودی و ارسال پستی ارائه می‌گردد.
آموزش‌های اندروید استودیو در دو دسته «پایه» و «تکمیلی» منتشر می‌شوند.
آموزش‌های پایه شامل مباحث اصلی و ضروری و آموزش‌های تکمیلی مطالبی است که می‌بایست در کنار مطالب اصلی بررسی شود.
با خرید این دوره، به تمامی آموزش‌های غیر رایگانی که در آینده منتشر می‌شود نیز به صورت رایگان دسترسی خواهید داشت!

یک دیدگاه بنویسید

پرسش‌های زیر تایید و پاسخ داده نـــخواهند شد:
۱: جزء موارد مطرح شده در صفحات مشکلات و پرسش‌های رایج و بروزرسانی‌های محتوای آموزشی باشد
۲: سوال قبلا توسط کاربران در دیدگاه‌ها مطرح و پاسخ داده شده باشد
۳: پرسش خارج از مبحث آموزشی موجود در این صفحه باشد