I am adding this https://github.com/rockerhieu/emojicon lib to my app, Now this lib requires me to add a fragment view to my layout
<fragment
android:id="#+id/emojicons"
android:layout_width="match_parent"
android:layout_height="220dp"
class="com.rockerhieu.emojicon.EmojiconsFragment"/>
after adding this my app crashes, can you please help me solve this?
here is the logat
Caused by: android.view.InflateException: Binary XML file line #90:
Error inflating class fragment
You should use this for Edit Text
<github.ankushsachdeva.emojicon.EmojiconEditText
android:id="#+id/emojicon_edit_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_weight="8"
emojicon:emojiconSize="28sp" />
and then in class file after initialising emojitext, you will have to use these listeners
final EmojiconsPopup popup = new EmojiconsPopup(rootView, this);
//Will automatically set size according to the soft keyboard size
popup.setSizeForSoftKeyboard();
/*--------------------------------------------------------------------*/
popup.setOnDismissListener(new PopupWindow.OnDismissListener() {
#Override
public void onDismiss() {
changeEmojiKeyboardIcon(emojiButton, R.mipmap.smiley);
}
});
//If the text keyboard closes, also dismiss the emoji popup
popup.setOnSoftKeyboardOpenCloseListener(new EmojiconsPopup.OnSoftKeyboardOpenCloseListener() {
#Override
public void onKeyboardOpen(int keyBoardHeight) {
}
#Override
public void onKeyboardClose() {
if (popup.isShowing())
popup.dismiss();
}
});
/*On emoji clicked, add it to edittext*/
popup.setOnEmojiconClickedListener(new EmojiconGridView.OnEmojiconClickedListener() {
#Override
public void onEmojiconClicked(Emojicon emojicon) {
if (emojiconEditText == null || emojicon == null) {
return;
}
int start = emojiconEditText.getSelectionStart();
int end = emojiconEditText.getSelectionEnd();
if (start < 0) {
emojiconEditText.append(emojicon.getEmoji());
} else {
emojiconEditText.getText().replace(Math.min(start, end),
Math.max(start, end), emojicon.getEmoji(), 0,
emojicon.getEmoji().length());
}
}
});
//On backspace clicked, emulate the KEYCODE_DEL key event
popup.setOnEmojiconBackspaceClickedListener(new EmojiconsPopup.OnEmojiconBackspaceClickedListener() {
#Override
public void onEmojiconBackspaceClicked(View v) {
KeyEvent event = new KeyEvent(
0, 0, 0, KeyEvent.KEYCODE_DEL, 0, 0, 0, 0, KeyEvent.KEYCODE_ENDCALL);
emojiconEditText.dispatchKeyEvent(event);
}
});
// To toggle between text keyboard and emoji keyboard keyboard(Popup)
emojiButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//If popup is not showing => emoji keyboard is not visible, we need to show it
if (!popup.isShowing()) {
//If keyboard is visible, simply show the emoji popup
if (popup.isKeyBoardOpen()) {
popup.showAtBottom();
changeEmojiKeyboardIcon(emojiButton, R.mipmap.ic_action_keyboard);
}
//else, open the text keyboard first and immediately after that show the emoji popup
else {
emojiconEditText.setFocusableInTouchMode(true);
emojiconEditText.requestFocus();
popup.showAtBottomPending();
final InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
inputMethodManager.showSoftInput(emojiconEditText, InputMethodManager.SHOW_IMPLICIT);
changeEmojiKeyboardIcon(emojiButton, R.mipmap.ic_action_keyboard);
}
}
//If popup is showing, simply dismiss it to show the undelying text keyboard
else {
popup.dismiss();
}
}
});
Hope this will help you :)
I have always had trouble using the <fragment> tag in my xml. I would suggest switching to a <FrameLayout> and using the following method in your code:
FragmentManager manager = getSupportFragmentManager(); // or getFragmentManager() if you are not using android.support.v4.app.Fragment
manager.beginTransaction().replace(R.id.frame_layout, new EmojiconsFragment()).commit();
Your activity must implement this interfaces:
public class MainActivity extends Activity implements EmojiconGridFragment.OnEmojiconClickedListener, OnEmojiconBackspaceClickedListener{
and implement method (in your activity):
#Override
public void onEmojiconClicked(Emojicon emojicon) {
}
#Override
public void onEmojiconBackspaceClicked(View v) {
}
It is very strange why that was not written in library readme
Related
When i show comment facebook to my app, result below. But when i click to comment
filed, webview show background white when set keyboard android:windowSoftInputMode="adjustPan". Sometime, it is cause when scroll webview bottom.
I have to found solve with scroll parent view with bottom view when key board visible.
KeyboardVisibilityEvent.setEventListener(
getActivity(),
new KeyboardVisibilityEventListener() {
#Override
public void onVisibilityChanged(boolean isOpen) {
// some code depending on keyboard status
if ((isOpen) &&(getUserVisibleHint())) {
if (nestVPageDetail != null) {
nestVPageDetail.post(new Runnable() {
#Override
public void run() {
if ((nestVPageDetail != null) && (rvContentArrayDetail != null)) {
nestVPageDetail.scrollTo(0,
rvContentArrayDetail.getBottom());
}
}
});
}
}
}
});
This is lib check keyboard:
implementation 'net.yslibrary.keyboardvisibilityevent:keyboardvisibilityevent:2.1.0'
I implemented the ankushsachdeva emojicon project to display emojicons in my chat app. When i click on a specific chat i start my ChatActivity. If i then immediately click the emoji-imageButton which i made, without expanding the keyboard first, it looks like the left screenshot here
Afterwords, the emojicon-overlay is always displayed correctly. (right screenshot)
I want the overlay to always be like in the right screenshot. Any ideas? (thanks in advance)
ChatActivity:
private ListView listView; //contains the chatmessages and has a customAdapter
private EmojiconsPopup popUp; //emojicon-popUp
private EditText editText; //editText to capture text and emojicons
private InputMethodManager inputManager;
#Override
protected void onCreate(Bundle savedInstanceState){
listView = (ListView) findViewById(R.id.listView);
//...//
inputManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
popUp = new EmojiconsPopup(listView, getApplicationContext());
popUp.setSizeForSoftKeyboard();
popUp.setOnEmojiconClickedListener(new OnEmojiconClickedListener(){
#Override
public void onEmojiconClicked(Emojicon emojicon){
editText.append(emojicon.getEmoji());
}
});
popUp.setOnEmojiconBackspaceClickedListener(new OnEmojiconBackspaceClickedListener(){
#Override
public void onEmojiconBackspaceClicked(View v){
KeyEvent event = new KeyEvent(0, 0, 0, KeyEvent.KEYCODE_DEL, 0, 0, 0, 0, KeyEvent.KEYCODE_ENDCALL);
editText.dispatchKeyEvent(event);
}
});
popUp.setOnSoftKeyboardOpenCloseListener(new OnSoftKeyboardOpenCloseListener(){
#Override
public void onKeyboardOpen(int keyBoardHeight){
}
#Override
public void onKeyboardClose(){
if (popUp.isShowing())
popUp.dismiss();
}
});
}
//called when the emojicon button is clicked
public void onEmojiButtonClicked(View view){
if (!popUp.isShowing()){
inputManager.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT);
popUp.showAtBottom(); //show popUp with emojicons
}else if(popUp.isShowing()){
popUp.dismiss(); // hide popUp with emojicons
}
}
Since, there is no reliable way to know the soft keyboard height, the library calculates it by opening the keyboard and seeing how much the top most layout of the view heirarchy shrinks.
I have added a new function into the library showAtBottomPending() which should solve your problem.
Make the following two changes to your code.
Change your onEmojiButtonClicked function to
public void onEmojiButtonClicked(View view){
if (!popUp.isShowing()){
popUp.showAtBottomPending(); //show popUp with emojicons after the keyboard is visible
inputManager.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT);
}else if(popUp.isShowing()){
popUp.dismiss(); // hide popUp with emojicons
}
}
Instead of passing listView in the EmojiconsPopup constructor,
pass the top most layout of your view hierarchy.
use like this its working.
public void onEmojiButtonClicked(View view){
if (!popUp.isShowing()){
popUp.showAtBottomPending(); //show popUp with emojicons after the keyboard is visible
showKeyboard(ettext);
}else if(popUp.isShowing()){
popUp.dismiss(); // hide popUp with emojicons
}
}
public void showKeyboard(final EmojiconEditText ettext){
ettext.requestFocus();
ettext.postDelayed(new Runnable(){
#Override public void run(){
InputMethodManager keyboard=(InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
keyboard.showSoftInput(ettext,0);
}
}
,200);
}
How to show my layout in front off soft keyboard Android like whatsapp or facebook?
like this
thanks before
this my code, but when emoji layout show, soft keyboard close.
btn_pop_emot.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
if (listEmot.getVisibility() == View.VISIBLE) {
listEmot.setVisibility(View.GONE);
imm.toggleSoftInputFromWindow(
edt_pop_komen.getApplicationWindowToken(),
InputMethodManager.SHOW_FORCED, 0);
btn_pop_emot.setBackgroundResource(R.drawable.emot_anim);
} else {
listEmot.setVisibility(View.VISIBLE);
imm.hideSoftInputFromWindow(edt_pop_komen.getWindowToken(),
0);
btn_pop_emot.setBackgroundResource(R.drawable.keyboard);
}
}
});
You can use this library, it also contains sample code in README to get you started
https://github.com/ankushsachdeva/emojicon
I want to to have some validation for my EditText wherein I want to show "" icon (that comes when you put editText.setError("blah blah")) but don't want the text in the popup displaying that "blah blah".
Is there any way to do it? One way is to create a custom layout which will show the image icon in the EditText. But is there any better solution?
Problem solved after a lot of research and permutations- (Also thanks to #van)
Create a new class that will extend EditText something like this-
public class MyEditText extends EditText {
public MyEditText(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
public void setError(CharSequence error, Drawable icon) {
setCompoundDrawables(null, null, icon, null);
}
}
Use this class as a view in your xml like this-
<com.raj.poc.MyEditText
android:id="#+id/et_test"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
Now in the third step, just set a TextWatcher to your custom text view like this-
et = (MyEditText) findViewById(R.id.et_test);
errorIcon = getResources().getDrawable(R.drawable.ic_error);
errorIcon.setBounds(new Rect(0, 0, errorIcon.getIntrinsicWidth(), errorIcon.getIntrinsicHeight()));
et.setError(null,errorIcon);
et.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// TODO Auto-generated method stub
}
#Override
public void afterTextChanged(Editable s) {
if(s.toString().length()>6){
et.setError("", null);
}else{
et.setError("", errorIcon);
}
}
});
where R.drawable.ic_error =
Keeping text null solves the problem
But if we keep only null in setError(null), this won't show the validation error; it should be null along with second param.
You dont need to create a new EditText class or change xml. The solution is very simple:
Edittext editText= (EditText) rootView.findViewById(R.id.email);
String str= editText.getText().toString();
if(str.equalsIgnoreCase("") ){
Drawable dr = getResources().getDrawable(R.drawable.error);
//add an error icon to yur drawable files
dr.setBounds(0, 0, dr.getIntrinsicWidth(), dr.getIntrinsicHeight());
editText.setCompoundDrawables(null,null,dr,null);
}
Sorry Rajkiran, but your solution is not working on Android 4.2 version. If I am trying to set null value for error, it is not even displayed. The solution I came up was to extend EditText and override setError method. No I have only error indicator without popup.
#Override
public void setError(CharSequence pError, Drawable pIcon) {
setCompoundDrawables(null, null, pIcon, null);
}
I have been dealing with the same problem. I wanted to use .setError() to my EditText when user insert null input. But I think the pop-out message is annoying, especially when you have more EditTexts.
My solution was naive and simple, but it worked on all devices I've tried so far.
I created my own class myEditText and just #Override this method:
#Override
public void setError(CharSequence error, Drawable icon) {
setCompoundDrawables(null, null, icon, null);
}
then use in layout.xml
<cz.project.myEditText
...
/>
and finally in my code
I put onFocusChangeListener to myEditText, so when someone clicks-in, the icon disappears.
myEditText input = (myEditText) findViewById(R.id.input);
input.setOnFocusChangeListener(new OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
input.setError(null);
});
if(val == null) input.setError("");
It works Exactly how I want = no pop-up message when .setError() is called on EditText.
To get only the error-icon without an error-message-popup only when setError("") is called (i.e. set an empty String as error-message) I use a custom EditText-class where I override setError(CharSequence, Drawable) like this:
#Override
public void setError(CharSequence error, Drawable icon) {
if (error == null) {
super.setError(null, icon);
setCompoundDrawables(null, null, null, null);
}
else if (error.toString().equals("")) setCompoundDrawables(null, null, icon, null);
else super.setError(error, icon);
}
Everything else stays the same:
Use setError(null) to get neither the icon nor the message-popup.
Use setError(errorMessage), where errorMessage is a String with length 1 at least, to get the icon and message-popup.
This is the very useful when you want to show the error messages for the edittext field when the user enter wrong information.this is very simply program only you have to use serError() method in the edittext.
Step 1:
Create button and implement onclickListener.
btnLogin.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
});
Step 2:
Validate the input fields and set the error in the input field.
if(edName.length()>3){
if(edNumber.length()>3){
Toast.makeText(getApplicationContext(), "Login success", Toast.LENGTH_SHORT).show();
}else{
edNumber.setError("Number Mininum length is 4");
}
}else{
edName.setError("Name Mininum length is 4");
}
Refer this link for more:http://velmuruganandroidcoding.blogspot.in/2014/08/set-error-message-in-edittext-android.html
I have created a trivial application to test the following functionality. When my activity launches, it needs to be launched with the softkeyboard open.
My code does not work?!
I have tried various "state" settings in the manifest and different flags in the code to the InputMethodManager (imm).
I have included the setting in the AndroidManifest.xml and explicitly invoked in the onCreate of the only activity.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mycompany.android.studyIme"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="7" />
<application android:icon="#drawable/icon" android:label="#string/app_name">
<activity android:name=".StudyImeActivity"
android:label="#string/app_name"
android:windowSoftInputMode="stateAlwaysVisible">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
... the main layout (main.xml) ...
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/hello"
/>
<EditText
android:id="#+id/edit_sample_text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:hint="#string/hello"
android:inputType="textShortMessage"
/>
</LinearLayout>
... and the code ...
public class StudyImeActivity extends Activity {
private EditText mEditTextStudy;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mEditTextStudy = (EditText) findViewById(R.id.edit_study);
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(mEditTextStudy, InputMethodManager.SHOW_FORCED);
}
}
When the activity launches It seems that the keyboard is initially displayed but hidden by something else, because the following works (but is actually a dirty work-around):
First Method
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
editText.postDelayed(new Runnable()
{
#Override
public void run()
{
editText.requestFocus();
imm.showSoftInput(editText, 0);
}
}, 100);
Second method
in onCreate to launch it on activity create
new Handler().postDelayed(new Runnable() {
#Override
public void run()
{
// InputMethodManager inputMethodManager=(InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
// inputMethodManager.toggleSoftInputFromWindow(EnterYourViewHere.getApplicationWindowToken(), InputMethodManager.SHOW_FORCED, 0);
if (inputMethodManager != null)
{
inputMethodManager.toggleSoftInput(InputMethodManager.SHOW_FORCED,0);
}
}
}, 200);
Third Method
ADD given code to activity tag in Manifest. It will show keyboard on launch, and set the first focus to your desire view.
android:windowSoftInputMode="stateVisible"
Hey I hope you are still looking for the answer as I found it when testing out my code. here is the code:
InputMethodManager imm = (InputMethodManager)_context.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(0, 0);
Here is my question that was answered:
android - show soft keyboard on demand
This worked with me on a phone with hard keyboard:
editText1.requestFocus();
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED,0);
This is so subtle, that it is criminal. This works on the phones that do NOT have a hard, slide-out keyboard. The phones with a hard keyboard will not open automatically with this call. My LG and old Nexus One do not have a keyboard -- therefore, the soft-keyboard opens when the activity launches (that is what I want), but the MyTouch and HTC G2 phones that have slide-out keyboards do not open the soft keyboard until I touch the edit field with the hard keyboard closed.
This answer maybe late but it works perfectly for me. Maybe it helps someone :)
public void showSoftKeyboard(View view) {
if (view.requestFocus()) {
InputMethodManager imm = (InputMethodManager)
getSystemService(Context.INPUT_METHOD_SERVICE);
boolean isShowing = imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT);
if (!isShowing)
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
}
}
Depends on you need, you can use other flags
InputMethodManager.SHOW_FORCED
WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
Showing Soft Keyboard is a big problem. I searched a lot to come to a final conclusion. Thanks to this answer which gave a number of clues: https://stackoverflow.com/a/16882749/5903344
Problem:
Normally we call showSoftInput as soon as we initialize the views. In Activities, this is mostly in onCreate, in Fragments onCreateView. In order to show the keyboard, IMM needs to have the focsedView as active. This can be checked using isActive(view) method of IMM. If we call showSoftInput while the views are being created, there is a good chance that the view won't be active for IMM. That is the reason why sometimes a 50-100 ms delayed showSoftInput is useful. However, that still does not guarantee that after 100 ms the view will become active. So in my understanding, this is again a hack.
Solution:
I use the following class. This keeps running every 100 ms until the keyboard has been successfully shown. It performs various checks in each iteration. Some checks can stop the runnable, some post it after 100 ms.
public class KeyboardRunnable extends Runnable
{
// ----------------------- Constants ----------------------- //
private static final String TAG = "KEYBOARD_RUNNABLE";
// Runnable Interval
private static final int INTERVAL_MS = 100;
// ----------------------- Classes ---------------------------//
// ----------------------- Interfaces ----------------------- //
// ----------------------- Globals ----------------------- //
private Activity parentActivity = null;
private View targetView = null;
// ----------------------- Constructor ----------------------- //
public KeyboardRunnable(Activity parentActivity, View targetView)
{
this.parentActivity = parentActivity;
this.targetView = targetView;
}
// ----------------------- Overrides ----------------------- //
#Override
public void run()
{
// Validate Params
if ((parentActivity == null) || (targetView == null))
{
Dbg.error(TAG, "Invalid Params");
return;
}
// Get Input Method Manager
InputMethodManager imm = (InputMethodManager) parentActivity.getSystemService(Context.INPUT_METHOD_SERVICE);
// Check view is focusable
if (!(targetView.isFocusable() && targetView.isFocusableInTouchMode()))
{
Dbg.error(TAG, "Non focusable view");
return;
}
// Try focusing
else if (!targetView.requestFocus())
{
Dbg.error(TAG, "Cannot focus on view");
Post();
}
// Check if Imm is active with this view
else if (!imm.isActive(targetView))
{
Dbg.error(TAG, "IMM is not active");
Post();
}
// Show Keyboard
else if (!imm.showSoftInput(targetView, InputMethodManager.SHOW_IMPLICIT))
{
Dbg.error(TAG, "Unable to show keyboard");
Post();
}
}
// ----------------------- Public APIs ----------------------- //
public static void Hide(Activity parentActivity)
{
if (parentActivity != null)
{
InputMethodManager imm = (InputMethodManager) parentActivity.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(parentActivity.findViewById(android.R.id.content).getWindowToken(), 0);
}
else
{
Dbg.error(TAG, "Invalid params to hide keyboard");
}
}
// ----------------------- Private APIs ----------------------- //
protected void Post()
{
// Post this aftr 100 ms
handler.postDelayed(this, INTERVAL_MS);
}
}
To use this, Just create an instance of this class. Pass it the parent activity and the targetView which would have keyboard input and focus afterwards. Then post the instance using a Handler.
Following worked for me:
mEditTextStudy.requestFocus();
mEditTextStudy.post(
new Runnable() {
#Override
public void run() {
InputMethodManager imm =
(InputMethodManager)
getActivity()
.getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm != null) {
imm.showSoftInput(mEditTextStudy, SHOW_FORCED);
}
}
});
For those who want a less hacky, and as-short-as-it-gets reliable solution to show the keyboard in 2022, I found this blog Showing the Android Keyboard Reliably with an answer that works really well for me, and it is less hacky than the postDelay 100ms as it utilizes OnWindowFocusChangeListener to do the trick.
It is really simple to use (something like this should be built in By Google!):
editText.focusAndShowKeyboard()
Add this extension method in Kotlin to use this on any View!
fun View.focusAndShowKeyboard() {
/**
* This is to be called when the window already has focus.
*/
fun View.showTheKeyboardNow() {
if (isFocused) {
post {
// We still post the call, just in case we are being notified of the windows focus
// but InputMethodManager didn't get properly setup yet.
val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.showSoftInput(this, InputMethodManager.SHOW_IMPLICIT)
}
}
}
requestFocus()
if (hasWindowFocus()) {
// No need to wait for the window to get focus.
showTheKeyboardNow()
} else {
// We need to wait until the window gets focus.
viewTreeObserver.addOnWindowFocusChangeListener(
object : ViewTreeObserver.OnWindowFocusChangeListener {
override fun onWindowFocusChanged(hasFocus: Boolean) {
// This notification will arrive just before the InputMethodManager gets set up.
if (hasFocus) {
this#focusAndShowKeyboard.showTheKeyboardNow()
// It’s very important to remove this listener once we are done.
viewTreeObserver.removeOnWindowFocusChangeListener(this)
}
}
})
}
}
You may think but why all these code when calling showSoftInput works during my testing? What I think it works for some people but not for others is because most people tested that in a normal activity or fragment, while the ones who reported not working (like me) were probably testing it in a dialog fragment or some sort. So this solution is more fool proof and can be used anywhere.
My code had the toggle in it but not postDelayed. I had tried postDelayed for the showSoftInput without success and I have since tried your suggested solution. I was about to discard it as yet another failed potential solution until I decided to increase the delay time. It works for me all the way down to 200 ms at which point it doesn't work, at least not on the physical phones. So before you poor android developers ditch this answer, try upping the delay for a successful solution. It may pay to add a bit for older slower phones. Thanks heaps, was working on this one for hours.
Solution for Xamarin developers (_digit1 == EditText):
var focussed = _digit1.RequestFocus();
if (focussed)
{
Window.SetSoftInputMode(SoftInput.StateAlwaysVisible);
var imm = (InputMethodManager)GetSystemService(InputMethodService);
imm.ToggleSoftInput(ShowFlags.Forced, 0);
}
Here is the modified version of Siddharth Garg's answer. It work's 100% of the time.
import android.content.Context;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.util.Log;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
public class SoftInputService implements Runnable {
private static final String TAG = SoftInputService.class.getSimpleName();
private static final int INTERVAL_MS = 100;
private Context context;
private View targetView;
private Handler handler;
public SoftInputService(Context context, View targetView) {
this.context = context;
this.targetView = targetView;
handler = new Handler(Looper.getMainLooper());
}
#Override
public void run() {
if (context == null || targetView == null) {
return;
}
InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
if (!targetView.isFocusable() || !targetView.isFocusableInTouchMode()) {
Log.d(TAG,"focusable = " + targetView.isFocusable() + ", focusableInTouchMode = " + targetView.isFocusableInTouchMode());
return;
} else if (!targetView.requestFocus()) {
Log.d(TAG,"Cannot focus on view");
post();
} else if (!imm.showSoftInput(targetView, InputMethodManager.SHOW_IMPLICIT)) {
Log.d(TAG,"Unable to show keyboard");
post();
}
}
public void show() {
handler.post(this);
}
public static void hide(Context context, IBinder windowToekn) {
InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(windowToekn, 0);
}
protected void post() {
handler.postDelayed(this, INTERVAL_MS);
}
}
Usage:
// To show the soft input
new SoftInputService(context, theEditText).show();
// To hide the soft input
SoftInputService.hide(context, theEditText.getWindowToken());
Similar problem but different solution so posting in case it is useful to others.
The problem was not with my code and use of:
inputMethodManager.showSoftInput(kbdInput, InputMethodManager.SHOW_IMPLICIT);
The problem related to that as of more recent sdk compiling. I'm no longer able to apply the above to a field that is hidden. Seems you must have your field visible and larger than 0 now for keyboard to appear. I was doing this because my app is more of a game using the keyboard as entry against an image. So all I had to do was change:
<EditText
android:id="#+id/kb_input"
android:layout_width="0dp"
android:layout_height="0dp"
/>
to
<EditText
android:id="#+id/kb_input"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#color/black"
android:textColorHighlight="#color/black"
android:backgroundTint="#color/black"
android:cursorVisible="false"
/>
My background was black so while the EditText is now visible it looks invisible on the black background.
This works for me:
public void requestFocusAndShowSoftInput(View view){
view.requestFocus();
InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
inputMethodManager.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT);
}
If you're trying to show the soft keyboard in a Fragment, you need to wait until the Activity has been created before calling showSoftInput(). Sample code:
public class SampleFragment extends Fragment {
private InputMethodManager mImm;
private TextView mTextView;
#Override
public void onAttach(Context context) {
super.onAttach(context);
mImm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
showSoftKeyboard(mTextView);
}
/**
* Request the InputMethodManager show the soft keyboard. Call this in {#link #onActivityCreated(Bundle)}.
* #param view the View which would like to receive text input from the soft keyboard
*/
public void showSoftKeyboard(View view) {
if (view.requestFocus()) {
mImm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT);
}
}
}
Removing android:windowSoftInputMode from the manifest solved my problem!
in my case, i solved this problem putting this code in onResume simply:
override fun onResume() {
super.onResume()
binding.edittext.requestFocus()
val imm =
requireContext().getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.showSoftInput(binding.edittext, InputMethodManager.SHOW_IMPLICIT)
}