ฉันมีEditText
และButton
ในรูปแบบของฉัน
หลังจากเขียนในฟิลด์แก้ไขและคลิกที่Button
ฉันต้องการซ่อนแป้นพิมพ์เสมือนจริง ฉันคิดว่านี่เป็นโค้ดง่าย ๆ แต่ฉันจะหาตัวอย่างได้ที่ไหน
เมื่อสัมผัสภายนอกแป้นพิมพ์
ฉันมีEditText
และButton
ในรูปแบบของฉัน
หลังจากเขียนในฟิลด์แก้ไขและคลิกที่Button
ฉันต้องการซ่อนแป้นพิมพ์เสมือนจริง ฉันคิดว่านี่เป็นโค้ดง่าย ๆ แต่ฉันจะหาตัวอย่างได้ที่ไหน
เมื่อสัมผัสภายนอกแป้นพิมพ์
คำตอบ:
เพื่อช่วยชี้แจงความบ้าคลั่งนี้ฉันขอเริ่มต้นด้วยการขอโทษในนามของผู้ใช้ Android ทุกคนสำหรับการใช้คีย์บอร์ดนุ่มอย่างไร้เดียงสาของ Google เหตุผลที่มีคำตอบมากมายสำหรับคำถามง่ายๆแบบเดียวกันก็คือเพราะ API นี้เช่นเดียวกับคนอื่น ๆ ใน Android นั้นได้รับการออกแบบมาอย่างน่ากลัว ฉันสามารถคิดได้ว่าไม่มีวิธีที่สุภาพในการระบุ
ฉันต้องการซ่อนแป้นพิมพ์ ผมคาดว่าจะให้ Android Keyboard.hide()
ที่มีคำสั่งดังต่อไปนี้: ตอนจบ. ขอบคุณมาก. แต่ Android มีปัญหา คุณต้องใช้ปุ่มInputMethodManager
เพื่อซ่อนแป้นพิมพ์ ตกลงดีนี่คือ API ของ Android สำหรับแป้นพิมพ์ แต่! คุณจะต้องมีContext
เพื่อที่จะเข้าถึง IMM ตอนนี้เรามีปัญหา Context
ฉันอาจต้องการที่จะซ่อนแป้นพิมพ์จากแบบคงที่หรือยูทิลิตี้ระดับที่ไม่มีการใช้งานหรือความจำเป็นในการใด ๆ หรือยิ่งแย่ไปกว่านั้น IMM ต้องการให้คุณระบุสิ่งที่View
(หรือแย่กว่านั้นคืออะไรWindow
) ที่คุณต้องการซ่อนคีย์บอร์ดจาก
นี่คือสิ่งที่ทำให้การซ่อนคีย์บอร์ดเป็นสิ่งที่ท้าทาย เรียน Google: เมื่อฉันค้นหาสูตรเค้กไม่มีRecipeProvider
บนโลกที่จะปฏิเสธที่จะจัดหาสูตรให้ฉันเว้นแต่ฉันจะตอบ WHO ก่อนเค้กจะถูกกินโดยและที่จะกิน !!
นี้เศร้าเรื่องจบลงด้วยความจริงที่น่าเกลียดที่จะซ่อนแป้นพิมพ์ Android ของคุณจะต้องให้ 2 รูปแบบบัตรประจำตัว: กContext
และทั้งหรือView
Window
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();
Fragment
ดูเหมือนว่าคุณสามารถใช้getActivity().getWindow().getDecorView()
Keyboard.hide();
ยูทิลิตี้นั้นจริงๆ
คุณสามารถบังคับให้ 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)
}
editText.clearFocus()
นั้นInputMethodManager.HIDE_IMPLICIT_ONLY
สามารถใช้งานได้4.1
View focused = getCurrentFocus()
ที่จะได้รับสิ่งที่เป็นแน่นอนมุมมองที่มุ่งเน้นในขณะนี้เรียกfocused.clearFocus()
แล้วinputMethodManager.hideSoftInputFromWindow(focused.getWindowToken(), 0)
(มีธงที่ชัดเจน)
นอกจากนี้ยังมีประโยชน์สำหรับการซ่อนคีย์บอร์ดอ่อนคือ:
getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN
);
สิ่งนี้สามารถใช้ในการระงับแป้นพิมพ์นุ่ม ๆ จนกว่าผู้ใช้จะสัมผัสกับมุมมองแก้ไขข้อความ
ฉันมีวิธีแก้ปัญหาเพิ่มเติมเพื่อซ่อนแป้นพิมพ์:
InputMethodManager imm = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0);
นี่ผ่านHIDE_IMPLICIT_ONLY
ที่ตำแหน่งของshowFlag
และที่ตำแหน่งของ0
hiddenFlag
มันจะปิดคีย์บอร์ดอ่อนแรง
โซลูชันของ 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);
}
}
โปรดลองรหัสด้านล่างใน onCreate()
EditText edtView=(EditText)findViewById(R.id.editTextConvertValue);
edtView.setInputType(0);
editView.setInputType(InputType.TYPE_NULL);
อัปเดต: ฉันไม่รู้ว่าทำไมโซลูชันนี้จึงไม่ทำงานอีกต่อไป (ฉันเพิ่งทดสอบกับ 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);
I don't know why this solution is not work any more
- เพราะมันเป็นAndroidทุกอย่างจะสามารถเปลี่ยนแปลงได้อาจเป็นส่วนหนึ่งของการออกแบบที่ไม่ดี ... เราเขียนอย่างไม่ระมัดระวังจากนั้นเราก็จัดการทั้งหมดและเขียนใหม่ทุกอย่าง
protected void hideSoftKeyboard(EditText input) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(input.getWindowToken(), 0);
}
input.getContext().getSystemService(Context.INPUT_METHOD_SERVICE)
ไปได้
input.setInputType(0);
จากรหัสนี้ มันเปลี่ยนพฤติกรรมแป้นพิมพ์และสำหรับinputType
EditText
หากคำตอบอื่น ๆ ทั้งหมดที่นี่ไม่ได้ผลสำหรับคุณตามที่คุณต้องการมีวิธีอื่นในการควบคุมคีย์บอร์ดด้วยตนเอง
สร้างฟังก์ชั่นที่จะจัดการคุณสมบัติบางอย่างของ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);
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 ... */
}
fragment.getActivity().getSystemService();
จากการค้นหาดังนั้นที่นี่ฉันพบคำตอบที่เหมาะกับฉัน
// 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);
ในคุณ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"
พฤติกรรมอย่างไรคุณต้องการบรรลุพฤติกรรมเดียวกันด้วยวิธีการเดียวกัน
ตรวจสอบคำตอบที่เกี่ยวข้องนี้
สิ่งนี้น่าจะใช้ได้:
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);
hide()
และshow()
วิธีการที่จะมีการควบคุมมากขึ้นเมื่อมันควรจะแสดงและเมื่อไม่ ได้ผลสำหรับฉันฉันก็ทำเช่นกัน :) ฉันจะแก้ไขตัวอย่าง
KeyBoard.toggle(fragment.getActivity())
Fragment
เช่นความเห็น เรียนรู้วิธีการใช้วิธีโปรดแล้วกลับมา คุณกำลังทำให้ผู้คนสับสนกับคำตอบที่โง่ของคุณ
ฉันใช้แป้นพิมพ์แบบกำหนดเองเพื่อป้อนหมายเลข 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);
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);
}
}
ฉันใช้เวลาทำงานมากกว่าสองวันในการแก้ปัญหาทั้งหมดที่โพสต์ในเธรดและพบว่าพวกเขาขาดวิธีใดวิธีหนึ่ง ความต้องการที่แน่นอนของฉันคือการมีปุ่มที่จะแสดงความน่าเชื่อถือ 100% หรือซ่อนแป้นพิมพ์บนหน้าจอ เมื่อคีย์บอร์ดอยู่ในสถานะที่ซ่อนอยู่ไม่ควรปรากฏขึ้นอีกครั้งไม่ว่าผู้ใช้จะคลิกที่ใดก็ตาม เมื่ออยู่ในสถานะที่มองเห็นแป้นพิมพ์ไม่ควรหายไปไม่ว่าผู้ใช้จะคลิกปุ่มใด สิ่งนี้ต้องใช้กับ Android 2.2 ขึ้นไปจนถึงอุปกรณ์รุ่นล่าสุด
คุณสามารถดูการดำเนินการทำงานนี้ใน app ของฉันRPN สะอาด
หลังจากทดสอบคำตอบที่แนะนำจำนวนมากบนโทรศัพท์หลายรุ่น (รวมถึงอุปกรณ์ froyo และ Gingerbread) มันก็เห็นได้ชัดว่าแอพ Android สามารถเชื่อถือได้:
สำหรับฉันการซ่อนแป้นพิมพ์ชั่วคราวไม่เพียงพอ ในอุปกรณ์บางอย่างมันจะปรากฏขึ้นอีกครั้งทันทีที่ฟิลด์ข้อความใหม่เน้น เนื่องจากแอพของฉันใช้ช่องข้อความหลายช่องในหนึ่งหน้าการโฟกัสที่ช่องข้อความใหม่จะทำให้คีย์บอร์ดที่ซ่อนอยู่ปรากฏขึ้นอีก
น่าเสียดายที่รายการ 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 () และกลับไปที่หน้าจอหลักของอุปกรณ์
อีกวิธีหนึ่งในการแก้ปัญหานี้หากคุณต้องการปิดคีย์บอร์ดนุ่มจากที่ใดก็ได้โดยไม่ต้องมีการอ้างอิงไปยังฟิลด์ (EditText) ที่ใช้ในการเปิดแป้นพิมพ์ แต่ยังต้องการที่จะทำถ้าฟิลด์ถูกโฟกัสคุณสามารถใช้ สิ่งนี้ (จากกิจกรรม):
if (getCurrentFocus() != null) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
}
ขอบคุณคำตอบ 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);
}
}
คำตอบข้างต้นสามารถใช้ได้กับสถานการณ์ที่แตกต่างกัน แต่ ถ้าคุณต้องการซ่อนแป้นพิมพ์ในมุมมองและพยายามดิ้นรนเพื่อให้ได้บริบทที่เหมาะสมลองทำสิ่งนี้:
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();
}
หากคุณต้องการปิดแป้นพิมพ์อ่อนระหว่างการทดสอบหน่วยหรือการใช้งานคุณสามารถทำได้โดยคลิกที่ปุ่ม "ย้อนกลับ" จากการทดสอบของคุณ:
// Close the soft keyboard from a Test
getInstrumentation().sendKeyDownUpSync(KeyEvent.KEYCODE_BACK);
ฉันใส่ปุ่ม "ย้อนกลับ" ในเครื่องหมายคำพูดเนื่องจากข้อความด้านบนไม่ได้ทำให้เกิดปัญหาonBackPressed()
สำหรับกิจกรรมที่เป็นปัญหา มันเพิ่งปิดคีย์บอร์ด
ตรวจสอบให้แน่ใจว่าได้หยุดชั่วคราวสักครู่ก่อนที่จะดำเนินการต่อเนื่องจากมันใช้เวลาสักครู่ในการปิดปุ่มย้อนกลับดังนั้นการคลิกที่ตามมาเพื่อชม ฯลฯ จะไม่ถูกลงทะเบียนจนกว่าจะหยุดชั่วคราวในระยะสั้น (1 วินาทีมีความยาวพอ )
นี่คือวิธีที่คุณทำใน Mono สำหรับ Android (AKA MonoDroid)
InputMethodManager imm = GetSystemService (Context.InputMethodService) as InputMethodManager;
if (imm != null)
imm.HideSoftInputFromWindow (searchbox.WindowToken , 0);
searchbox
ในตัวอย่างหรือไม่
สิ่งนี้ใช้ได้สำหรับฉันสำหรับพฤติกรรมคีย์บอร์ดที่แปลกประหลาดทั้งหมด
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);
}
}
เพิ่มในกิจกรรมของคุณ android:windowSoftInputMode="stateHidden"
ในไฟล์มานิเฟสต์ ตัวอย่าง:
<activity
android:name=".ui.activity.MainActivity"
android:label="@string/mainactivity"
android:windowSoftInputMode="stateHidden"/>
วิธีการที่ง่ายและใช้งานง่ายเพียงแค่เรียก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);
}
เพียงใช้รหัสที่ได้รับการปรับปรุงให้ดีที่สุดในกิจกรรมของคุณ:
if (this.getCurrentFocus() != null) {
InputMethodManager inputManager = (InputMethodManager) this.getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}
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;
}
});
ใช้สิ่งนี้
this.getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
สำหรับกรณีของฉันฉันใช้ SearchView ใน actionbar หลังจากผู้ใช้ทำการค้นหาแป้นพิมพ์จะเปิดขึ้นอีกครั้ง
การใช้ InputMethodManager ไม่ได้ปิดแป้นพิมพ์ ฉันต้องล้างโฟกัสและตั้งค่าโฟกัสของมุมมองการค้นหาเป็นเท็จ:
mSearchView.clearFocus();
mSearchView.setFocusable(false);
clearFocus()
ในหน้า Android API ดังนั้นสิ่งนี้ไม่ได้ผลสำหรับฉัน แต่มีวิธีแก้ไขปัญหาอื่น (ดูคำตอบของฉันด้านล่าง)
ฉันมีกรณีที่ฉัน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 );
}
ฉันได้ลองคำตอบทั้งหมดเหล่านี้แล้วฉันมีปัญหาแบบสุ่มโดยเฉพาะกับ 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);
}