ปิด / ซ่อนคีย์บอร์ดนุ่มของ Android


3819

ฉันมีEditTextและButtonในรูปแบบของฉัน

หลังจากเขียนในฟิลด์แก้ไขและคลิกที่Buttonฉันต้องการซ่อนแป้นพิมพ์เสมือนจริง ฉันคิดว่านี่เป็นโค้ดง่าย ๆ แต่ฉันจะหาตัวอย่างได้ที่ไหน

เมื่อสัมผัสภายนอกแป้นพิมพ์


13
ถ้าคุณมี EditText เพียงปุ่มเดียวและมีหลายปุ่มเช่นเช็คบ็อกซ์และวิทยุ ที่เดียวที่คุณต้องการแป้นพิมพ์อยู่ใน EditText เดียว คุณจะลงทะเบียนเพื่อทราบว่ามีการเลือก / คลิกอย่างอื่นเพื่อซ่อนแป้นพิมพ์ได้อย่างไร
AlikElzin-kilaka

14
ฉันรู้สึกโง่. ฉันไม่สามารถซ่อนแป้นพิมพ์บน ICS พยายามทุกวิธีที่นี่และการรวมกันของพวกเขา ไม่มีทาง. วิธีการแสดงให้เห็นว่าใช้ได้ผล แต่ฉันไม่สามารถซ่อนมันได้ไม่ว่าจะมีสิ่งใดที่ซ่อนเร้นซ่อนธงการตั้งค่าที่ชัดแจ้งหรือแสงเทียนให้กับนักบุญใด ๆ ในการแสดงแป้นพิมพ์ฉันจะเห็นสิ่งนี้เสมอ: I / LatinIME (396): InputType.TYPE_NULL ถูกระบุ W / LatinIME (396): คลาสอินพุตที่ไม่คาดคิด: inputType = 0x00000000 imeOptions = 0x00000000
rupps

4
/ ** * วิธีนี้ใช้เพื่อซ่อนคีย์บอร์ดอ่อน * @param activity * / public void hideSoftKeyboard (กิจกรรมกิจกรรม) {InputMethodManager inputMethodManager = (InputMethodManager) activity.getSystemService (Activity.INPUT_METHOD_SERVICE); inputMethodManager.hideSoftInputFromWindow (activity.getCurrentFocus (). getWindowToken (), 0); }
Harshal Benake

สิ่งนี้ใช้ได้กับฉัน
nmxprime

ด้วยอุปกรณ์ที่เพิ่มขนาดหน้าจอและความละเอียดการซ่อนคีย์บอร์ดเสมือนจึงมีความสำคัญน้อย
Al-Kathiri Khalid

คำตอบ:


2036

เพื่อช่วยชี้แจงความบ้าคลั่งนี้ฉันขอเริ่มต้นด้วยการขอโทษในนามของผู้ใช้ Android ทุกคนสำหรับการใช้คีย์บอร์ดนุ่มอย่างไร้เดียงสาของ Google เหตุผลที่มีคำตอบมากมายสำหรับคำถามง่ายๆแบบเดียวกันก็คือเพราะ API นี้เช่นเดียวกับคนอื่น ๆ ใน Android นั้นได้รับการออกแบบมาอย่างน่ากลัว ฉันสามารถคิดได้ว่าไม่มีวิธีที่สุภาพในการระบุ

ฉันต้องการซ่อนแป้นพิมพ์ ผมคาดว่าจะให้ Android Keyboard.hide()ที่มีคำสั่งดังต่อไปนี้: ตอนจบ. ขอบคุณมาก. แต่ Android มีปัญหา คุณต้องใช้ปุ่มInputMethodManagerเพื่อซ่อนแป้นพิมพ์ ตกลงดีนี่คือ API ของ Android สำหรับแป้นพิมพ์ แต่! คุณจะต้องมีContextเพื่อที่จะเข้าถึง IMM ตอนนี้เรามีปัญหา Contextฉันอาจต้องการที่จะซ่อนแป้นพิมพ์จากแบบคงที่หรือยูทิลิตี้ระดับที่ไม่มีการใช้งานหรือความจำเป็นในการใด ๆ หรือยิ่งแย่ไปกว่านั้น IMM ต้องการให้คุณระบุสิ่งที่View(หรือแย่กว่านั้นคืออะไรWindow) ที่คุณต้องการซ่อนคีย์บอร์ดจาก

นี่คือสิ่งที่ทำให้การซ่อนคีย์บอร์ดเป็นสิ่งที่ท้าทาย เรียน Google: เมื่อฉันค้นหาสูตรเค้กไม่มีRecipeProviderบนโลกที่จะปฏิเสธที่จะจัดหาสูตรให้ฉันเว้นแต่ฉันจะตอบ WHO ก่อนเค้กจะถูกกินโดยและที่จะกิน !!

นี้เศร้าเรื่องจบลงด้วยความจริงที่น่าเกลียดที่จะซ่อนแป้นพิมพ์ Android ของคุณจะต้องให้ 2 รูปแบบบัตรประจำตัว: กContextและทั้งหรือViewWindow

Activityผมได้สร้างวิธีการที่ยูทิลิตี้แบบคงที่ซึ่งสามารถทำผลงานได้อย่างสมบูรณ์มากให้คุณเรียกมันว่าจาก

public static void hideKeyboard(Activity activity) {
    InputMethodManager imm = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
    //Find the currently focused view, so we can grab the correct window token from it.
    View view = activity.getCurrentFocus();
    //If no view currently has focus, create a new one, just so we can grab a window token from it
    if (view == null) {
        view = new View(activity);
    }
    imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}

โปรดทราบว่าวิธีการยูทิลิตี้นี้จะทำงานเฉพาะเมื่อถูกเรียกจากActivity! วิธีการดังกล่าวเรียกgetCurrentFocusเป้าหมายActivityเพื่อดึงโทเค็นหน้าต่างที่เหมาะสม

แต่สมมติว่าคุณต้องการซ่อนแป้นพิมพ์จากนั้นEditTextเจ้าภาพในDialogFragment? คุณไม่สามารถใช้วิธีการด้านบนสำหรับสิ่งนั้น:

hideKeyboard(getActivity()); //won't work

สิ่งนี้จะไม่ทำงานเพราะคุณจะผ่านการอ้างอิงไปยังFragmentโฮสต์ของActivityซึ่งจะไม่มีการควบคุมที่มุ่งเน้นในขณะที่Fragmentแสดง! ว้าว! ดังนั้นเพื่อซ่อนแป้นพิมพ์จากเศษเล็กเศษน้อยฉันหันไปที่ระดับต่ำกว่าที่พบบ่อยและน่าเกลียด:

public static void hideKeyboardFrom(Context context, View view) {
    InputMethodManager imm = (InputMethodManager) context.getSystemService(Activity.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}

ด้านล่างเป็นข้อมูลเพิ่มเติมที่รวบรวมมาจากการสูญเสียเวลาในการไล่แก้ปัญหานี้:

เกี่ยวกับ windowSoftInputMode

ยังมีอีกประเด็นของการต่อสู้ที่ต้องระวัง โดยค่าเริ่มต้นของ Android โดยอัตโนมัติจะกำหนดจุดเริ่มต้นที่จะเป็นครั้งแรกที่การควบคุมหรือที่สามารถโฟกัสในของคุณEditText Activityเป็นไปตามธรรมชาติที่ InputMethod (โดยทั่วไปคือคีย์บอร์ดอ่อน) จะตอบสนองต่อเหตุการณ์โฟกัสโดยการแสดงตัวเอง windowSoftInputModeแอตทริบิวต์ในAndroidManifest.xmlเมื่อตั้งค่าที่จะstateAlwaysHiddenแนะแป้นพิมพ์เพื่อละเว้นนี้จุดเริ่มต้นโดยอัตโนมัติที่ได้รับมอบหมาย

<activity
    android:name=".MyActivity"
    android:windowSoftInputMode="stateAlwaysHidden"/>

แทบไม่น่าเชื่อดูเหมือนว่าจะไม่ทำอะไรเลยเพื่อป้องกันไม่ให้คีย์บอร์ดเปิดเมื่อคุณสัมผัสตัวควบคุม (ยกเว้นfocusable="false"และ / หรือfocusableInTouchMode="false"ถูกกำหนดให้กับตัวควบคุม) เห็นได้ชัดว่าการตั้งค่า windowSoftInputMode ใช้กับเหตุการณ์การโฟกัสอัตโนมัติเท่านั้นไม่ใช่การโฟกัสเหตุการณ์ที่เกิดขึ้นจากเหตุการณ์การสัมผัส

ดังนั้นจึงstateAlwaysHiddenมีชื่อไม่ดีมากอย่างแน่นอน มันควรจะถูกเรียกignoreInitialFocusแทน

หวังว่านี่จะช่วยได้


อัปเดต: วิธีเพิ่มเติมในการรับโทเค็นหน้าต่าง

หากไม่มีมุมมองที่มุ่งเน้น (เช่นสามารถเกิดขึ้นได้หากคุณเพิ่งเปลี่ยนชิ้นส่วน) มีมุมมองอื่น ๆ ที่จะให้โทเค็นหน้าต่างที่มีประโยชน์

สิ่งเหล่านี้เป็นทางเลือกสำหรับรหัสด้านบนสิ่งif (view == null) view = new View(activity); เหล่านี้ไม่ได้อ้างถึงกิจกรรมของคุณอย่างชัดเจน

ภายในคลาสแฟรกเมนต์:

view = getView().getRootView().getWindowToken();

รับแฟรกเมนต์fragmentเป็นพารามิเตอร์:

view = fragment.getView().getRootView().getWindowToken();

เริ่มต้นจากเนื้อหาเนื้อหาของคุณ:

view = findViewById(android.R.id.content).getRootView().getWindowToken();

อัปเดต 2: ล้างโฟกัสเพื่อหลีกเลี่ยงการแสดงแป้นพิมพ์อีกครั้งหากคุณเปิดแอปจากพื้นหลัง

เพิ่มบรรทัดนี้ในตอนท้ายของวิธีการ:

view.clearFocus();


2
เขียนได้ดีมาก อย่างไรก็ตามสิ่งหนึ่งที่ถ้าคุณเริ่มต้นกิจกรรมอื่นที่อยู่ด้านบนของมันซึ่งเป็นตัวกระตุ้นแป้นพิมพ์แป้นพิมพ์จะยังคงปรากฏเมื่อคุณกลับมา แก้ไขว่าโดยการเอาคีย์บอร์ดออกโดยใช้วิธีการของคุณเมื่อออกจากกิจกรรมบนสุด
Oyvind

3
@rmirabelle Fragmentดูเหมือนว่าคุณสามารถใช้getActivity().getWindow().getDecorView()
McX

1
โพสต์นี้ยอดเยี่ยม แต่คุณขาดสองส่วนที่สำคัญมาก การเปลี่ยนแปลงที่ละเอียดทำต่อรุ่นและทำได้ต่อการผลิต ตัวอย่างเช่นบน Samsung galaxy s6 เราจำเป็นต้องใช้. clearFocus () ก่อนที่จะซ่อนแป้นพิมพ์ ... หากไม่มีแป้นพิมพ์จะยังคงปรากฏขึ้นในการคลิกครั้งที่สองของ edittext: S
Warpzit

17
google ควรจัดหาKeyboard.hide();ยูทิลิตี้นั้นจริงๆ
HendraWD

1
[someView] .getContext () << สามารถใช้กับกิจกรรมได้ มันเป็นวัตถุเดียวกันเสมอ (ยกเว้นบริการภายใน ... )
Oliver Dixon

4418

คุณสามารถบังคับให้ Android ซ่อนแป้นพิมพ์เสมือนโดยใช้InputMethodManagerโทรhideSoftInputFromWindowผ่านโทเค็นของหน้าต่างที่มีมุมมองโฟกัสของคุณ

// Check if no view has focus:
View view = this.getCurrentFocus();
if (view != null) {  
    InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}

สิ่งนี้จะบังคับให้แป้นพิมพ์ถูกซ่อนอยู่ในทุกสถานการณ์ ในบางกรณีคุณจะต้องผ่านInputMethodManager.HIDE_IMPLICIT_ONLYเป็นพารามิเตอร์ที่สองเพื่อให้แน่ใจว่าคุณซ่อนแป้นพิมพ์เมื่อผู้ใช้ไม่ได้บังคับให้ปรากฏอย่างชัดเจน (โดยกดเมนูค้างไว้)

หมายเหตุ:หากคุณต้องการทำสิ่งนี้ใน Kotlin ให้ใช้: context?.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager

ไวยากรณ์ Kotlin

// Check if no view has focus:
 val view = this.currentFocus
 view?.let { v ->
  val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as? InputMethodManager 
  imm?.hideSoftInputFromWindow(v.windowToken, 0)
 }

14
ขอบคุณดูเหมือนว่าจะใช้งานได้ดีหากใช้ 0 เป็นพารามิเตอร์ที่สอง แต่ถ้าฉันใช้ InputMethodManager.HIDE_IMPLICIT_ONLY แป้นพิมพ์จะไม่ถูกซ่อน (แม้ว่าฉันจะไม่ถือเมนู) คำใบ้ใด ๆ
RoflcoptrException

27
เย็น. เพื่ออธิบายให้ชัดเจนสิ่งนี้จะยกเลิกหากมีอยู่ แต่จะไม่ป้องกันไม่ให้เกิดขึ้นใช่ไหม
Cheezmeister

15
อาจเป็นประโยชน์ในการโทร editText.clearFocus () ก่อนที่จะซ่อน softInput
user2224350

111
การโทรeditText.clearFocus()นั้นInputMethodManager.HIDE_IMPLICIT_ONLYสามารถใช้งานได้4.1
sprocket12

11
สิ่งที่ทำงานสำหรับฉันใน 4.4 / HTC ได้รับการดำเนินการView focused = getCurrentFocus()ที่จะได้รับสิ่งที่เป็นแน่นอนมุมมองที่มุ่งเน้นในขณะนี้เรียกfocused.clearFocus()แล้วinputMethodManager.hideSoftInputFromWindow(focused.getWindowToken(), 0)(มีธงที่ชัดเจน)
Ionoclast Brigham

806

นอกจากนี้ยังมีประโยชน์สำหรับการซ่อนคีย์บอร์ดอ่อนคือ:

getWindow().setSoftInputMode(
    WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN
);

สิ่งนี้สามารถใช้ในการระงับแป้นพิมพ์นุ่ม ๆ จนกว่าผู้ใช้จะสัมผัสกับมุมมองแก้ไขข้อความ


116
นอกจากนี้คุณยังสามารถบรรลุผลเดียวกันโดยเพิ่ม Android: windowSoftInputMode = "stateHidden" ในกิจกรรมของคุณในรายการ
BoD

7
พยายามทำสิ่งนี้ใน Fragment (อ้างอิงกิจกรรมการเป็นเจ้าของ) บน API ระดับ 9 และไม่ได้ทำงานอย่างน่าเสียดาย พยายามเรียกมันใน onResume และ onActivityCreated - ไม่มีผลกระทบ
AgentKnopf

2
ฉันกำลังทำงานในกล่องโต้ตอบและสิ่งนี้ได้ผล ฉันใช้ Android 3.2 ฉันวางไว้ในวิธี onCreateDialog (Bundle) มันไม่ทำงานในวิธีการ onCreate กล่องโต้ตอบโต้ตอบ = super.onCreateDialog (hiddenInstanceState); dialog.getWindow (). setSoftInputMode (WindowManager.LayoutParams SOFT_INPUT_STATE_ALWAYS_HIDDEN); ผลลัพธ์ก็คือมุมมองของฉันที่มี EditTexts อยู่ในนั้นจะปรากฏขึ้นโดยไม่มีแป้นพิมพ์ เมื่อผู้ใช้สัมผัสกับข้อความแก้ไขคีย์บอร์ดจะปรากฏขึ้น
flobacca

4
สิ่งนี้ไม่ทำงานเมื่อโฟกัสยังอยู่ใน EditText (เช่นหลังจากกดปุ่ม) ใช้วิธีแก้ปัญหาของ Reto
Noumenon

4
เหตุใดการเอาชนะการตั้งค่ารายการจึงเป็นความคิดที่ไม่ดี ฉันกำลังเรียกสิ่งนี้จากชิ้นส่วน ไม่มีการตั้งค่าอย่างชัดแจ้งว่าจะนำไปใช้ส่วนใหญ่แล้ว ... คือ
เกร็กเอนนิส

349

ฉันมีวิธีแก้ปัญหาเพิ่มเติมเพื่อซ่อนแป้นพิมพ์:

InputMethodManager imm = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0);

นี่ผ่านHIDE_IMPLICIT_ONLYที่ตำแหน่งของshowFlagและที่ตำแหน่งของ0 hiddenFlagมันจะปิดคีย์บอร์ดอ่อนแรง


4
คุณกำลังใช้การซ่อนธงในพารามิเตอร์ showflags ใช้งานได้เพียงเพราะค่าคงที่ใช้จำนวนเต็มเดียวกัน ตัวอย่างการใช้ธงที่ถูกต้อง
Alex

ทดสอบกับ Android 4.0 ฉันชอบวิธีนี้เพราะฉันมีข้อความแก้ไขหลายปุ่มปุ่มในกิจกรรมนั้นซึ่งสามารถโฟกัสได้

32
@ Mark: เพราะวิธีการที่เรียกว่า "toggleSoftInput" ไม่ "hideSoftInput" :)
Sver

19
วิธีนี้จะแสดงแป้นพิมพ์หากถูกซ่อนอยู่ มันไม่ถูกต้อง
Michael Katkov

1
@AkashAggarwal - มัน "ได้ผล" ถ้าคุณเพิกเฉยต่อความจริงที่ว่ามันได้ผลสำหรับคุณเท่านั้นเพราะแป้นพิมพ์กำลังแสดงอยู่ (มันเป็นการแสดงผลของคีย์บอร์ด: มันซ่อนเมื่อมันถูกแสดง แต่มันจะแสดงมันเมื่อมันถูกซ่อน !!) คุณสามารถรับประกันได้ว่าภายใต้สถานการณ์ทั้งหมดบนอุปกรณ์ทั้งหมดสำหรับ Android รุ่นอนาคตทั้งหมดว่าแป้นพิมพ์จะไม่ แสดงในเวลาที่คุณเรียกสิ่งนี้? ถ้าเป็นเช่นนั้นไปข้างหน้าและใช้งาน!
ToolmakerSteve

149

โซลูชันของ Meier ก็เหมาะกับฉันเช่นกัน ในกรณีของฉันระดับบนสุดของแอพของฉันคือ tabHost และฉันต้องการซ่อนคำหลักเมื่อเปลี่ยนแท็บ - ฉันได้รับโทเค็นหน้าต่างจากมุมมอง tabHost

tabHost.setOnTabChangedListener(new OnTabChangeListener() {
    public void onTabChanged(String tabId) {
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(tabHost.getApplicationWindowToken(), 0);
    }
}

ฉันได้รับสิ่งนี้เพื่อทำงานกับ SearchView ด้วย ดูด้านล่างสำหรับคำตอบของฉัน ขอบคุณ mckoss!
Azurespot

139

โปรดลองรหัสด้านล่างใน onCreate()

EditText edtView=(EditText)findViewById(R.id.editTextConvertValue);
edtView.setInputType(0);

2
วิธีนี้ใช้เป็นวิธีแก้ปัญหาข้อผิดพลาด "ไม่สามารถซ่อนซอฟต์คีย์บอร์ด" ใน 2.0 และ 2.1 ตามที่อธิบายไว้ในcode.google.com/p/android/issues/detail?id=7115 ... วิธีการ hideSoftInputFromWindow รายการด้านบนไม่ทำงานเมื่อฉันลอง แต่ editView.setInputType (0) ทำ
Spike Williams

18
นี่เป็น Legit ต่อ Javadoc (ไม่ใช่แฮ็ค) แม้ว่าฉันจะเขียนวิธีเป็นeditView.setInputType(InputType.TYPE_NULL);
Bostone

3
ใช้งานได้ แต่มันซ่อน android: hint ฉันใช้ Android 1.5
Tirtha

สิ่งนี้เป็นสิ่งที่ดีสำหรับเมื่อคุณต้องการปิดแป้นพิมพ์จากกล่องโต้ตอบไม่จำเป็นต้องมีอินสแตนซ์หรืออะไรและสามารถกำหนดสิ่งนี้ให้กับข้อความแก้ไขทั้งหมดเมื่อผู้ใช้กดปุ่มที่ปิดกล่องโต้ตอบ
I'm_With_Stupid

มันใช้งานได้ แต่มันก็ซ่อนเคอร์เซอร์ด้วย ฉันต้องการเคอร์เซอร์ แต่ไม่มีคีย์บอร์ดระบบ
Stefan Brendle

129

อัปเดต: ฉันไม่รู้ว่าทำไมโซลูชันนี้จึงไม่ทำงานอีกต่อไป (ฉันเพิ่งทดสอบกับ Android 23) โปรดใช้วิธีแก้ปัญหาของSaurabh Pareekแทน นี่มันคือ:

InputMethodManager imm = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE);
//Hide:
imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0);
//Show
imm.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, 0);

คำตอบเก่า:

//Show soft-keyboard:
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
//hide keyboard :
 getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

8
ฉันควรวางรหัสนี้ที่ไหน ฉันพยายามวาง getWindow (). setSoftInputMode (WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); ใน onCreate () แต่แป้นพิมพ์ไม่เคยถูกซ่อน
user2236096

ไม่ทำงานทดสอบใน radioGroup.setOnCheckedChangeListener, API 23
Christian Schäfer

หากคุณมองใกล้กว่านั้น InputMethodManager.HIDE_IMPLICIT_ONLY และ InputMethodManager.SHOW_IMPLICIT จะมีค่าเหมือนกันซึ่งก็คือ "1" ดังนั้นจึงไม่มีความแตกต่างระหว่างการโทรเหล่านี้ => ไม่ทำงาน
Palejandro

ถ้าการเรียก imm.toggleSoftInput (InputMethodManager.HIDE_IMPLICIT_ONLY, 0); คีย์บอร์ดจะแสดงบนหน้าจอ :) การใช้งานที่ดีที่สุดคือ: github.com/ravindu1024/android-keyboardlistener Shame บน Android SDK
Duna

I don't know why this solution is not work any more- เพราะมันเป็นAndroidทุกอย่างจะสามารถเปลี่ยนแปลงได้อาจเป็นส่วนหนึ่งของการออกแบบที่ไม่ดี ... เราเขียนอย่างไม่ระมัดระวังจากนั้นเราก็จัดการทั้งหมดและเขียนใหม่ทุกอย่าง
King King

89
protected void hideSoftKeyboard(EditText input) {
    InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(input.getWindowToken(), 0);    
}

5
สิ่งนี้ได้ผลสำหรับฉัน! แต่ทำไมคุณใส่input.setInputType (0) ? ฉันไม่สามารถโต้ตอบกับEditTextViewเมื่อฉันมีบรรทัดของรหัสนั้น (มันทำงานเมื่อฉันลบมัน)
ymerdrengene

อาจเป็นinput.getContext().getSystemService(Context.INPUT_METHOD_SERVICE)ไปได้
CoolMind

ฉันลบออกinput.setInputType(0);จากรหัสนี้ มันเปลี่ยนพฤติกรรมแป้นพิมพ์และสำหรับinputType EditText
CoolMind

74

หากคำตอบอื่น ๆ ทั้งหมดที่นี่ไม่ได้ผลสำหรับคุณตามที่คุณต้องการมีวิธีอื่นในการควบคุมคีย์บอร์ดด้วยตนเอง

สร้างฟังก์ชั่นที่จะจัดการคุณสมบัติบางอย่างของEditText:

public void setEditTextFocus(boolean isFocused) {
    searchEditText.setCursorVisible(isFocused);
    searchEditText.setFocusable(isFocused);
    searchEditText.setFocusableInTouchMode(isFocused);

    if (isFocused) {
        searchEditText.requestFocus();
    }
}

จากนั้นตรวจสอบให้แน่ใจว่า onFocus ของEditTextคุณเปิด / ปิดคีย์บอร์ด:

searchEditText.setOnFocusChangeListener(new OnFocusChangeListener() {
    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if (v == searchEditText) {
            if (hasFocus) {
                // Open keyboard
                ((InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE)).showSoftInput(searchEditText, InputMethodManager.SHOW_FORCED);
            } else {
                // Close keyboard
                ((InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(searchEditText.getWindowToken(), 0);
            }
        }
    }
});

ตอนนี้เมื่อใดก็ตามที่คุณต้องการเปิดแป้นพิมพ์ด้วยตนเองโทร:

setEditTextFocus(true);

และสำหรับการปิดการโทร:

setEditTextFocus(false);

+1 - หากคุณต้องการเริ่มต้นกิจกรรมด้วยแป้นพิมพ์แบบปิดให้ใช้โซลูชันนี้และเพิ่ม onclicklistener ซึ่งตั้งค่า setEditTextFocus (จริง) ทำงานเหมือน charme!
schlingel

ฉันได้รับ 'ไม่สามารถแก้ไขบริบทสัญลักษณ์' ในบรรทัดที่ 7 และ 10 ของโค้ดบล็อกที่สอง
gimmegimme

ใช้ getContext () แทน
Rotemmiz

61

Saurabh Pareekมีคำตอบที่ดีที่สุดจนถึงตอนนี้

อาจใช้ธงที่ถูกต้องเช่นกัน

/* hide keyboard */
((InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE))
    .toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, 0);

/* show keyboard */
((InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE))
    .toggleSoftInput(0, InputMethodManager.HIDE_IMPLICIT_ONLY);

ตัวอย่างการใช้งานจริง

/* click button */
public void onClick(View view) {      
  /* hide keyboard */
  ((InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE))
      .toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, 0);

  /* start loader to check parameters ... */
}

/* loader finished */
public void onLoadFinished(Loader<Object> loader, Object data) {
    /* parameters not valid ... */

    /* show keyboard */
    ((InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE))
        .toggleSoftInput(0, InputMethodManager.HIDE_IMPLICIT_ONLY);

    /* parameters valid ... */
}

1
นี่คือประสิทธิภาพสูงสุดสำหรับเวอร์ชันล่าสุด หนึ่งจะต้องปรับแต่งสำหรับรุ่นเก่า โดยเฉพาะอย่างยิ่งก่อน v3
อเล็กซ์

2
@Mazen: ใช้งานfragment.getActivity().getSystemService();
Johan S

นี่เป็นคำตอบที่ครอบคลุมที่สุดครอบคลุมทั้งการแสดงและการซ่อน
André Staltz

4
ไม่บนแท็บ Samsung, Android 5.0 ของฉันรหัสเรียกว่า "hide keyboard" ด้านบนจะสลับคีย์บอร์ดอ่อน - หากซ่อนอยู่แล้วจะแสดงขึ้นมา มีเหตุผลที่ฟังก์ชั่นนี้มี TOGGLE ในชื่อ
ToolmakerSteve

57

จากการค้นหาดังนั้นที่นี่ฉันพบคำตอบที่เหมาะกับฉัน

// Show soft-keyboard:
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);

// Hide soft-keyboard:
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

คนเดียวที่ทำงานให้ฉันสำหรับโมโตโรล่ากับ Android 5.1
GMX

55

คำตอบสั้น ๆ

ในคุณOnClickฟังเรียกonEditorActionของEditTextด้วยIME_ACTION_DONE

button.setOnClickListener(new OnClickListener() {

    @Override
    public void onClick(View v) {
        someEditText.onEditorAction(EditorInfo.IME_ACTION_DONE)
    }
});

การเจาะลง

ฉันรู้สึกว่าวิธีนี้ดีกว่าง่ายขึ้นและสอดคล้องกับรูปแบบการออกแบบของ Android มากขึ้น ในตัวอย่างง่ายๆข้างต้น (และโดยทั่วไปในกรณีทั่วไปส่วนใหญ่) คุณจะมีปุ่มEditTextที่มี / มีโฟกัสและมันก็มักจะเป็นแป้นที่จะเรียกใช้แป้นพิมพ์ในครั้งแรก (มันแน่นอนสามารถเรียกใช้ในหลาย ๆ สถานการณ์ทั่วไป) ในลักษณะเดียวกับที่มันImeActionควรจะเป็นอย่างใดอย่างหนึ่งที่จะปล่อยแป้นพิมพ์ปกติที่สามารถทำได้โดย เพียงแค่ดูว่าEditTextมีandroid:imeOptions="actionDone"พฤติกรรมอย่างไรคุณต้องการบรรลุพฤติกรรมเดียวกันด้วยวิธีการเดียวกัน


ตรวจสอบคำตอบที่เกี่ยวข้องนี้


นี่คือคำตอบ วิธีการเฉพาะที่ทำงานข้ามรุ่น ฉันกลับมาที่คำถามนี้เพื่อโพสต์คำตอบนี้เพราะฉันไม่คิดว่าจะมีใครรู้
โนอาห์พาสซาลาควา

นี่ควรเป็นคำตอบที่ถูกต้อง แทนที่จะหลอก Android ให้ซ่อนแป้นพิมพ์เมื่อมันควรจะอยู่ตรงนั้นเราบอกว่าผู้ใช้เสร็จแล้วซึ่งจะกระตุ้นให้เกิด ImeAction เดียวกัน [ชื่อโง่ฉันยอมรับ] ราวกับว่าผู้ใช้คลิก "DONE" บนแป้นพิมพ์ . วิธีนี้จะไม่สร้างความแตกต่างหากผู้ใช้ยืนยันการป้อนข้อมูลบนแป้นพิมพ์หรือแตะปุ่ม UI
Oliver Hausler

46

สิ่งนี้น่าจะใช้ได้:

public class KeyBoard {

    public static void show(Activity activity){
        InputMethodManager imm = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
        imm.toggleSoftInput(0, InputMethodManager.HIDE_IMPLICIT_ONLY); // show
    }

    public static void hide(Activity activity){
        InputMethodManager imm = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
        imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0); // hide
    }

    public static void toggle(Activity activity){
        InputMethodManager imm = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
        if (imm.isActive()){
            hide(activity); 
        } else {
            show(activity); 
        }
    }
}

KeyBoard.toggle(activity);

ทำงานบางส่วนแม้ว่าแป้นพิมพ์จะถูกซ่อน "isActive ()" ส่งคืนค่าเท็จ!
xpto

แน่นอนมันควรจะเป็น หรือบางทีฉันไม่เข้าใจคุณ อย่างไรก็ตามคุณสามารถเสริมชั้นเรียนด้วยhide()และshow()วิธีการที่จะมีการควบคุมมากขึ้นเมื่อมันควรจะแสดงและเมื่อไม่ ได้ผลสำหรับฉันฉันก็ทำเช่นกัน :) ฉันจะแก้ไขตัวอย่าง
slinden77

@YoushaAleayoub ใช่มันจะ KeyBoard.toggle(fragment.getActivity())
slinden77

@ slinden77 ฮ่า ๆ ฉันกำลังพูดถึงคำตอบของคุณ ... ไม่ใช่คนที่คุณแสดงความคิดเห็น ดังนั้นคำตอบนั้นก็ยังคงทำงานอยู่
Yousha Aleayoub

@ YoushaAleayoub เอ่อใช่มันจะ คำถามดั้งเดิมไม่ได้พูดถึงชิ้นส่วนคุณเป็นคนที่พูดถึงชิ้นส่วน ดังนั้นคำตอบของฉันถูกต้องสมบูรณ์ หากต้องการใช้กับแฟรกเมนต์ให้เรียกเมธอดแตกต่างจาก a Fragmentเช่นความเห็น เรียนรู้วิธีการใช้วิธีโปรดแล้วกลับมา คุณกำลังทำให้ผู้คนสับสนกับคำตอบที่โง่ของคุณ
slinden77

43

ฉันใช้แป้นพิมพ์แบบกำหนดเองเพื่อป้อนหมายเลข Hex ดังนั้นฉันจึงไม่สามารถแสดงแป้นพิมพ์ IMM ...

ใน v3.2.4_r1 setSoftInputShownOnFocus(boolean show)ถูกเพิ่มเพื่อควบคุมสภาพอากาศหรือไม่ให้แสดงแป้นพิมพ์เมื่อ TextView ได้รับโฟกัส แต่ยังคงซ่อนอยู่ดังนั้นจึงต้องใช้การสะท้อน:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
    try {
        Method method = TextView.class.getMethod("setSoftInputShownOnFocus", boolean.class);
        method.invoke(mEditText, false);
    } catch (Exception e) {
        // Fallback to the second method
    }
}

สำหรับรุ่นเก่าฉันได้ผลลัพธ์ที่ดีมาก (แต่ไกลจากที่สมบูรณ์) ด้วย a OnGlobalLayoutListener, เพิ่มด้วยความช่วยเหลือViewTreeObserverจากมุมมองรูตของฉันแล้วตรวจสอบว่าแป้นพิมพ์แสดงดังนี้:

@Override
public void onGlobalLayout() {
    Configuration config = getResources().getConfiguration();

    // Dont allow the default keyboard to show up
    if (config.keyboardHidden != Configuration.KEYBOARDHIDDEN_YES) {
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(mRootView.getWindowToken(), 0);
    }
}

วิธีการแก้ปัญหาล่าสุดนี้อาจแสดงแป้นพิมพ์เป็นเสี้ยววินาทีและยุ่งเหยิงกับส่วนที่เลือก

เมื่ออยู่ในแป้นพิมพ์เข้าสู่เต็มหน้าจอ onGlobalLayout จะไม่ถูกเรียก เพื่อหลีกเลี่ยงปัญหานี้ให้ใช้TextView # setImeOptions (int)หรือในการประกาศ TextView XML:

android:imeOptions="actionNone|actionUnspecified|flagNoFullscreen|flagNoExtractUi"

อัปเดต:เพิ่งพบกล่องโต้ตอบที่ใช้ไม่แสดงแป้นพิมพ์และทำงานได้ในทุกรุ่น:

getWindow().setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
        WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);

ขอบคุณ. การตั้งค่าสถานะสองแบบ FLAG_ALT_FOCUSABLE_IM และ FLAG_ALT_FOCUSABLE_IM นั้นเป็นสิ่งเดียวที่ช่วยฉันได้ ฉันไม่ต้องการให้แป้นพิมพ์ปรากฏในกิจกรรมของฉัน - แม้กระทั่งเมื่อผู้ใช้คลิก edittext (ฉันสร้าง "ปุ่มกด" ของตัวเอง)
Daniel Novak

วิธีแก้ปัญหาที่ดีที่สุดหากกิจกรรมด้านหน้าของคุณไม่เต็มหน้าจอแป้นพิมพ์จะมองเห็นด้านหลังได้ นอกจากนี้ยังมีตัวช่วยการเลื่อนเคอร์เซอร์ของคีย์บอร์ด และมันไม่ได้เป็นผิวหนัง
halxinate

ฉันสองที่ จากวิธีที่เป็นไปได้ทั้งหมดเฉพาะเมธอด getWindow (). setFlags () ทำงานได้อย่างน้อยในสต็อก Android 5.1 โปรดทราบว่า setSoftInputShownOnFocus () ได้รับการตั้งค่าในขณะนี้ setShowSoftInputOnFocus () และไม่ถูกซ่อนอีกต่อไป แต่ใช้งานไม่ได้อย่างน้อยไม่เมื่อผู้ใช้สัมผัสกับฟิลด์
olefevre

"การอัปเดต" ของคุณเป็นเพียงทางออกเดียวสำหรับฉัน ฉันกำลังมองหาวิธีการแก้ปัญหาอย่างน้อยสองชั่วโมง :)
สเตฟาน Brendle

33
public void setKeyboardVisibility(boolean show) {
    InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
    if(show){
        imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
    }else{
        imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(),0);
    }
}

30

ฉันใช้เวลาทำงานมากกว่าสองวันในการแก้ปัญหาทั้งหมดที่โพสต์ในเธรดและพบว่าพวกเขาขาดวิธีใดวิธีหนึ่ง ความต้องการที่แน่นอนของฉันคือการมีปุ่มที่จะแสดงความน่าเชื่อถือ 100% หรือซ่อนแป้นพิมพ์บนหน้าจอ เมื่อคีย์บอร์ดอยู่ในสถานะที่ซ่อนอยู่ไม่ควรปรากฏขึ้นอีกครั้งไม่ว่าผู้ใช้จะคลิกที่ใดก็ตาม เมื่ออยู่ในสถานะที่มองเห็นแป้นพิมพ์ไม่ควรหายไปไม่ว่าผู้ใช้จะคลิกปุ่มใด สิ่งนี้ต้องใช้กับ Android 2.2 ขึ้นไปจนถึงอุปกรณ์รุ่นล่าสุด

คุณสามารถดูการดำเนินการทำงานนี้ใน app ของฉันRPN สะอาด

หลังจากทดสอบคำตอบที่แนะนำจำนวนมากบนโทรศัพท์หลายรุ่น (รวมถึงอุปกรณ์ froyo และ Gingerbread) มันก็เห็นได้ชัดว่าแอพ Android สามารถเชื่อถือได้:

  1. ซ่อนแป้นพิมพ์ชั่วคราว มันจะปรากฏขึ้นอีกครั้งเมื่อผู้ใช้เน้นฟิลด์ข้อความใหม่
  2. แสดงแป้นพิมพ์เมื่อกิจกรรมเริ่มต้นและตั้งค่าสถานะในกิจกรรมที่ระบุว่าแป้นพิมพ์ควรจะมองเห็นได้ตลอดเวลา ธงนี้สามารถตั้งค่าได้เมื่อกิจกรรมเริ่มต้น
  3. ทำเครื่องหมายกิจกรรมเพื่อไม่ให้แสดงหรืออนุญาตให้ใช้แป้นพิมพ์ ธงนี้สามารถตั้งค่าได้เมื่อกิจกรรมเริ่มต้น

สำหรับฉันการซ่อนแป้นพิมพ์ชั่วคราวไม่เพียงพอ ในอุปกรณ์บางอย่างมันจะปรากฏขึ้นอีกครั้งทันทีที่ฟิลด์ข้อความใหม่เน้น เนื่องจากแอพของฉันใช้ช่องข้อความหลายช่องในหนึ่งหน้าการโฟกัสที่ช่องข้อความใหม่จะทำให้คีย์บอร์ดที่ซ่อนอยู่ปรากฏขึ้นอีก

น่าเสียดายที่รายการ 2 และ 3 ในรายการจะทำงานได้อย่างน่าเชื่อถือเมื่อกิจกรรมเริ่มขึ้นเท่านั้น เมื่อกิจกรรมปรากฏให้เห็นคุณจะไม่สามารถซ่อนหรือแสดงคีย์บอร์ดอย่างถาวร เคล็ดลับคือการเริ่มต้นกิจกรรมของคุณใหม่เมื่อผู้ใช้กดปุ่มสลับของแป้นพิมพ์ ในแอพของฉันเมื่อผู้ใช้กดปุ่มสลับบนแป้นพิมพ์รหัสต่อไปนี้จะทำงาน:

private void toggleKeyboard(){

    if(keypadPager.getVisibility() == View.VISIBLE){
        Intent i = new Intent(this, MainActivity.class);
        i.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
        Bundle state = new Bundle();
        onSaveInstanceState(state);
        state.putBoolean(SHOW_KEYBOARD, true);
        i.putExtras(state);

        startActivity(i);
    }
    else{
        Intent i = new Intent(this, MainActivity.class);
        i.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
        Bundle state = new Bundle();
        onSaveInstanceState(state);
        state.putBoolean(SHOW_KEYBOARD, false);
        i.putExtras(state);

        startActivity(i);
    }
}

สิ่งนี้ทำให้กิจกรรมปัจจุบันถูกบันทึกสถานะเป็นบันเดิลและจากนั้นกิจกรรมก็เริ่มขึ้นโดยผ่านบูลีนซึ่งระบุว่าควรจะแสดงหรือซ่อนคีย์บอร์ดหรือไม่

ภายในเมธอด onCreate จะมีการเรียกใช้รหัสต่อไปนี้:

if(bundle.getBoolean(SHOW_KEYBOARD)){
    ((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE)).showSoftInput(newEquationText,0);
    getWindow().setSoftInputMode(LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
}
else{
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
            WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
}

หากควรแสดงคีย์บอร์ดอ่อนซอฟต์แวร์จะป้อนคำสั่ง InputMethodManager เพื่อแสดงแป้นพิมพ์และหน้าต่างได้รับคำแนะนำให้แสดงซอฟต์พุตให้มองเห็นได้เสมอ หากคีย์บอร์ดนุ่มควรถูกซ่อนไว้ WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM จะถูกตั้งค่า

วิธีนี้ใช้ได้กับทุกอุปกรณ์ที่ฉันทดสอบบน - ตั้งแต่โทรศัพท์ HTC อายุ 4 ปีที่ใช้ Android 2.2 ถึง Nexus 7 ที่ใช้ 4.2.2 ข้อเสียเพียงอย่างเดียวของวิธีนี้คือคุณต้องระมัดระวังในการใช้ปุ่มย้อนกลับ เนื่องจากแอพของฉันมีเพียงหน้าจอเดียว (เป็นเครื่องคิดเลข) ฉันสามารถแทนที่ onBackPressed () และกลับไปที่หน้าจอหลักของอุปกรณ์


1
วิธีแก้ปัญหาที่ซับซ้อน แต่ฉันคิดว่ามันมากเกินไปที่จะสร้างวัตถุหลายพันชิ้นเพียงเพื่อซ่อนแป้นพิมพ์ ฉันไม่รู้ว่าใครเป็นผู้ออกแบบ IMM สำหรับ Android แต่มันมีกลิ่นเหมือน Windows APi ในความคิดของฉัน IME ที่ดีควรมีสองวิธี: ซ่อนและแสดง :-)
rupps

มันเป็นความจริงทั้งหมด แต่การแก้ปัญหาของฉันมีข้อดีอย่างหนึ่ง - มันใช้ได้เสมอ! ไม่มีวิธีแก้ปัญหาอื่นที่ฉันสามารถหาได้ว่าจะสลับแป้นพิมพ์เสมอโดยไม่คำนึงถึงฟิลด์ใดใน UI ที่มีโฟกัสสิ่งที่ผู้ใช้ทำเพื่อสลับและแป้นพิมพ์และรุ่นใดที่ใช้ Android: - \
Luke Sleeman

ชายฉันหมดหวังอย่างยิ่งที่จะซ่อนแป้นพิมพ์ พยายามนับพันสิ่งและฟังก์ชั่น noooone แต่วิธีแก้ปัญหาของคุณมากเกินไปสำหรับฉันฉันต้องสร้างใหม่ 10 ชิ้นเริ่มต้นบริการลบ WeakReferences จำนวนมาก .... คุณรู้ไหม? GC เพิ่งจะทิ้งไปเช่น 25mb: S. ... ยังคงมองหาวิธีที่เชื่อถือได้ที่จะทำ :(
rupps

@ มิทรีดีมันไม่ได้เป็นโลกสวัสดี ... มันเป็นโปรแกรมที่ซับซ้อนสำหรับแท็บเล็ต ฉันปฏิเสธที่จะยกเลิกการโหลดโดยสิ้นเชิงจากหน่วยความจำเพียงเพื่อซ่อนแป้นพิมพ์โง่ ... อย่างไรก็ตามผมพบว่าสิ่งที่ผลงานรวมพันโซลูชั่นที่นำเสนอที่นี่ :)
rupps

27

อีกวิธีหนึ่งในการแก้ปัญหานี้หากคุณต้องการปิดคีย์บอร์ดนุ่มจากที่ใดก็ได้โดยไม่ต้องมีการอ้างอิงไปยังฟิลด์ (EditText) ที่ใช้ในการเปิดแป้นพิมพ์ แต่ยังต้องการที่จะทำถ้าฟิลด์ถูกโฟกัสคุณสามารถใช้ สิ่งนี้ (จากกิจกรรม):

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

25

ขอบคุณคำตอบ SO นี้ฉันได้รับสิ่งต่อไปนี้ซึ่งในกรณีของฉันทำงานได้ดีเมื่อเลื่อนดูส่วนของ ViewPager ...

private void hideKeyboard() {   
    // Check if no view has focus:
    View view = this.getCurrentFocus();
    if (view != null) {
        InputMethodManager inputManager = (InputMethodManager) this.getSystemService(Context.INPUT_METHOD_SERVICE);
        inputManager.hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
    }
}

private void showKeyboard() {   
    // Check if no view has focus:
    View view = this.getCurrentFocus();
    if (view != null) {
        InputMethodManager inputManager = (InputMethodManager) this.getSystemService(Context.INPUT_METHOD_SERVICE);
        inputManager.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT);
    }
}

21

คำตอบข้างต้นสามารถใช้ได้กับสถานการณ์ที่แตกต่างกัน แต่ ถ้าคุณต้องการซ่อนแป้นพิมพ์ในมุมมองและพยายามดิ้นรนเพื่อให้ได้บริบทที่เหมาะสมลองทำสิ่งนี้:

setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        hideSoftKeyBoardOnTabClicked(v);
    }
}

private void hideSoftKeyBoardOnTabClicked(View v) {
    if (v != null && context != null) {
        InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(v.getApplicationWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
    }
}

และรับบริบทดึงมันมาจากคอนสตรัค :)

public View/RelativeLayout/so and so (Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    this.context = context;
    init();
}

18

หากคุณต้องการปิดแป้นพิมพ์อ่อนระหว่างการทดสอบหน่วยหรือการใช้งานคุณสามารถทำได้โดยคลิกที่ปุ่ม "ย้อนกลับ" จากการทดสอบของคุณ:

// Close the soft keyboard from a Test
getInstrumentation().sendKeyDownUpSync(KeyEvent.KEYCODE_BACK);

ฉันใส่ปุ่ม "ย้อนกลับ" ในเครื่องหมายคำพูดเนื่องจากข้อความด้านบนไม่ได้ทำให้เกิดปัญหาonBackPressed()สำหรับกิจกรรมที่เป็นปัญหา มันเพิ่งปิดคีย์บอร์ด

ตรวจสอบให้แน่ใจว่าได้หยุดชั่วคราวสักครู่ก่อนที่จะดำเนินการต่อเนื่องจากมันใช้เวลาสักครู่ในการปิดปุ่มย้อนกลับดังนั้นการคลิกที่ตามมาเพื่อชม ฯลฯ จะไม่ถูกลงทะเบียนจนกว่าจะหยุดชั่วคราวในระยะสั้น (1 วินาทีมีความยาวพอ )


16

นี่คือวิธีที่คุณทำใน Mono สำหรับ Android (AKA MonoDroid)

InputMethodManager imm = GetSystemService (Context.InputMethodService) as InputMethodManager;
if (imm != null)
    imm.HideSoftInputFromWindow (searchbox.WindowToken , 0);

1
คืออะไรsearchboxในตัวอย่างหรือไม่
PCoder

16

สิ่งนี้ใช้ได้สำหรับฉันสำหรับพฤติกรรมคีย์บอร์ดที่แปลกประหลาดทั้งหมด

private boolean isKeyboardVisible() {
    Rect r = new Rect();
    //r will be populated with the coordinates of your view that area still visible.
    mRootView.getWindowVisibleDisplayFrame(r);

    int heightDiff = mRootView.getRootView().getHeight() - (r.bottom - r.top);
    return heightDiff > 100; // if more than 100 pixels, its probably a keyboard...
}

protected void showKeyboard() {
    if (isKeyboardVisible())
        return;
    InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
    if (getCurrentFocus() == null) {
        inputMethodManager.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
    } else {
        View view = getCurrentFocus();
        inputMethodManager.showSoftInput(view, InputMethodManager.SHOW_FORCED);
    }
}

protected void hideKeyboard() {
    if (!isKeyboardVisible())
        return;
    InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
    View view = getCurrentFocus();
    if (view == null) {
        if (inputMethodManager.isAcceptingText())
            inputMethodManager.toggleSoftInput(InputMethodManager.HIDE_NOT_ALWAYS, 0);
    } else {
        if (view instanceof EditText)
            ((EditText) view).setText(((EditText) view).getText().toString()); // reset edit text bug on some keyboards bug
        inputMethodManager.hideSoftInputFromInputMethod(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
    }
}

1
คิดว่าฉันลอง 10 คำตอบก่อนหน้านี้ ได้หมดหวังไปแล้ว ขอบคุณชาย
Bolling

mRootView คืออะไร
justdan0227

14

เพิ่มในกิจกรรมของคุณ android:windowSoftInputMode="stateHidden"ในไฟล์มานิเฟสต์ ตัวอย่าง:

<activity
            android:name=".ui.activity.MainActivity"
            android:label="@string/mainactivity"
            android:windowSoftInputMode="stateHidden"/>

14

วิธีการที่ง่ายและใช้งานง่ายเพียงแค่เรียกhideKeyboardFrom (YourActivity.this); เพื่อซ่อนแป้นพิมพ์

/**
 * This method is used to hide keyboard
 * @param activity
 */
public static void hideKeyboardFrom(Activity activity) {
    InputMethodManager imm = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0);
}

13

เพียงใช้รหัสที่ได้รับการปรับปรุงให้ดีที่สุดในกิจกรรมของคุณ:

if (this.getCurrentFocus() != null) {
    InputMethodManager inputManager = (InputMethodManager) this.getSystemService(Context.INPUT_METHOD_SERVICE);
    inputManager.hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}

ทำงานได้ดี ขอบคุณ
ลิฟ

12
public static void hideSoftKeyboard(Activity activity) {
    InputMethodManager inputMethodManager = (InputMethodManager)  activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
    inputMethodManager.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0);
}

หลังจากโทรหา onTouchListener:

findViewById(android.R.id.content).setOnTouchListener(new OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        Utils.hideSoftKeyboard(activity);
        return false;
    }
});

ลองสิ่งนี้เช่นกัน - สิ่งนี้ใช้ได้กับฉัน: InputMethodManager imm = ((InputMethodManager) getSystemService (Activity.INPUT_METHOD_SERVICE)); imm.hideSoftInputFromWindow (getWindow (). getCurrentFocus (). getWindowToken (), 0);
zmicer


12

สำหรับกรณีของฉันฉันใช้ SearchView ใน actionbar หลังจากผู้ใช้ทำการค้นหาแป้นพิมพ์จะเปิดขึ้นอีกครั้ง

การใช้ InputMethodManager ไม่ได้ปิดแป้นพิมพ์ ฉันต้องล้างโฟกัสและตั้งค่าโฟกัสของมุมมองการค้นหาเป็นเท็จ:

mSearchView.clearFocus();
mSearchView.setFocusable(false);

1
ฉลาดมาก. หากผู้ใช้ต้องการค้นหาอีกครั้งเพียงคลิกค้นหาอีกครั้ง
Alex

SearchView ไม่มีclearFocus()ในหน้า Android API ดังนั้นสิ่งนี้ไม่ได้ผลสำหรับฉัน แต่มีวิธีแก้ไขปัญหาอื่น (ดูคำตอบของฉันด้านล่าง)
Azurespot


12

ฉันมีกรณีที่ฉันEditTextสามารถอยู่ในยังAlertDialogดังนั้นแป้นพิมพ์ควรจะปิดเมื่อยกเลิก รหัสต่อไปนี้ดูเหมือนว่าทำงานได้ทุกที่:

public static void hideKeyboard( Activity activity ) {
    InputMethodManager imm = (InputMethodManager)activity.getSystemService( Context.INPUT_METHOD_SERVICE );
    View f = activity.getCurrentFocus();
    if( null != f && null != f.getWindowToken() && EditText.class.isAssignableFrom( f.getClass() ) )
        imm.hideSoftInputFromWindow( f.getWindowToken(), 0 );
    else 
        activity.getWindow().setSoftInputMode( WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN );
}

1
วิธีนี้ดีกว่าเพราะคุณไม่ต้องควบคุมว่า EditText pass เป็นพารามิเตอร์สำหรับ HideSoftInputFromWindow () วิธีใด มันใช้งานได้ดี !!
Billyjoker

12

ฉันได้ลองคำตอบทั้งหมดเหล่านี้แล้วฉันมีปัญหาแบบสุ่มโดยเฉพาะกับ Samsung galaxy s5

สิ่งที่ฉันจบลงด้วยการบังคับให้แสดงและซ่อนและมันทำงานได้อย่างสมบูรณ์:

/**
 * Force show softKeyboard.
 */
public static void forceShow(@NonNull Context context) {
    InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
}

/**
 * Force hide softKeyboard.
 */
public static void forceHide(@NonNull Activity activity, @NonNull EditText editText) {
    if (activity.getCurrentFocus() == null || !(activity.getCurrentFocus() instanceof EditText)) {
        editText.requestFocus();
    }
    InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
    activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.