Android AlertDialog with dynamically changing text on every request - java

I want to show an AlertDialog with one option that might change on every request. So for example at one time I want to show the option "add to contacts" while another time it should be "remove from contacts".
My code does work on the first time, however Android seems to cache the AlertDialog so that onCreateDialog is not executed next time. Therefore the option doesnt change anymore. Can I prevent this caching, or is there just another way of changing the option?
I am working with SDK 1.5 but using 1.1.
#Override
protected Dialog onCreateDialog(final int id) {
...
String add_remove_contact = res.getString(R.string.profile_add_to_contacts);
if (user.getContacts().contains(profileID)) {
add_remove_contact = res.getString(R.string.profile_remove_from_contacts);
// TODO: this string is not changed when contact status changes
}
final CharSequence[] items = {res.getString(R.string.view_profile),
res.getString(R.string.profile_send_message),
add_remove_contact};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
...
return builder.create();
}

Take a look at onPrepareDialog method that will be called before dialog is shown. There You can change the required values based on request type.
Example with date picker
#Override
protected Dialog onCreateDialog(final int id) {
switch (id) {
case DIALOG_DATE_ID:
final Calendar c = Calendar.getInstance();
return new DatePickerDialog(this, this, c.get(Calendar.YEAR),
c.get(Calendar.MONTH),
c.get(Calendar.DAY_OF_MONTH));
default:
return super.onCreateDialog(id);
}
}
#Override
protected void onPrepareDialog(final int id, final Dialog dialog) {
switch (id) {
case DIALOG_DATE_ID:
//update to current time
final Calendar c = Calendar.getInstance();
((DatePickerDialog) dialog).updateDate(c.get(Calendar.YEAR),
c.get(Calendar.MONTH),
c.get(Calendar.DAY_OF_MONTH));
break;
}
}

You can also use the removeDialog(int) function of the Activity. When a dialog is dismissed, the Activity basically stores the state of the dialog (for performance reasons I would imagine). Calling removeDialog(int) on the dialog forces the activity to unload all references for the dialog and dismisses it from the screen if it's being shown.
Creating Dialogs
Activity#removeDialog(int)

This is a dup of this question:
Android: Can not change the text appears in AlertDialog
You can also do it this way:
http://andmobidev.blogspot.com/2010/03/modifying-alert-dialogs-list-items.html
Does seem to slow down the display of the longpress menu though...

I think I have a fix for the inconsistent behavior mentioned above. When initially creating the dialog (when it's still an AlertDialog.Builder), you have to set the message to an initial state (not null) or onPrepareDialog will NOT overwrite it with the intended value. So when you're creating the dialog, do something like this to always have a non-null value in the message. I struggled with this for days and found this solution by accident:
AlertDialog.Builder resultAlert = new AlertDialog.Builder(context);
if ( message == null ) {
resultAlert.setMessage("");
} else {
resultAlert.setMessage(message);
}

When you have a custom dialog you can change custom items by using dialog.getWindow().findViewById(...)
This example save the last text shown and display it again the next time you show the dialog.
// custom dialog
final Dialog dialog = new Dialog(this);
dialog.setContentView(R.layout.customized);
dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
#Override
public void onDismiss(DialogInterface dialogInterface) {
EditText dialogText = (EditText)dialog.getWindow().findViewById(R.id.customText);
savedText = dialogText.getText();
}
});
dialog.show();
EditText dialogText = (EditText)dialog.getWindow().findViewById(R.id.customText);
dialogText.setText(savedText);
Customized dialog's xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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">
<Button
android:id="#+id/buttonOK"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="OK"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginBottom="16dp" />
<EditText
android:id="#+id/customText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="19dp"
android:hint="Message"
android:ems="10"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true" />

I understand the performance reasons for using activity managed dialogs, but would recommend that they are not used except for simple cases. The reasons for this are:
The Bundle argument was only added in API Level 8, so can't be adopted for backwards compatibility. This effectively means that 'onPrepareDialog' needs to rely on non-local variables for state differences;
Practice indicates poor and inconsistent behaviour in response to any dialog changes made in the body of 'onPrepareDialog'.
None of these difficulties arise if Dialogs are subclassed and created as needed. 'setOwnerActivity' can be called if necessary.

And I got a idea but not so good.*This is used when the users don't use the dialog quite frequently!*The solution :first,you should declare a variable (int type) and make the default value as 0.such as private int i=0;
and before you use the showDialog methods of Activity,increase the int variable i and post the value i as the parameter as showDialog method.
the code may like this
private int i=0;
//before you show the dialog
this.i++;
this.showDialog(this.i);

exactly. for AlertDialog, that was created w/ Builder.create(), onPrepareDialog() is useless. Builder is one-way in that once the dialog is created, you can't update. i mean can't loosely, i am sure you could get a handle to the view and do it all manually, but that defeats the point of using the builder in the first place.
the only solution i found was to manually create / show / dismiss the dialog instead of using onCreateDialog(), showDialog(), etc. i tried calling removeDialog(), but that did not seem to work.

Related

when am I safe to query a View's dimensions?

I'm trying to grab the dimensions of a view in my activity. The view is a simple custom view which extends an ImageView:
<com.example.dragdropshapes.CustomStrechView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#drawable/border"
android:src="#drawable/missingpuz"
android:clickable="true"
android:onClick="pickShapes"
/>
I need to know what the specific "fill_parent" ends up being. I attempted to get this information during the onCreate method of the Activity using the layout containing my custom views:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_puzzle_picker);
// Show the Up button in the action bar.
setupActionBar();
int a = findViewById(R.id.pickshapes).getMeasuredHeight();
int b = findViewById(R.id.pickshapes).getHeight();
In this case, both a and b return a value of 0. Later, the custom view will be used as a button (it has an onClick handler) so I thought to try again to get the size in the handler:
public void pickShapes(View view){
Intent intent = new Intent(this, ShapesActivity.class);
int a = findViewById(R.id.pickshapes).getMeasuredHeight();
int b = findViewById(R.id.pickshapes).getHeight();
startActivity(intent);
}
Here a and b both give valid dimensions... I don't want to wait for a "onClick" event however, I want to get the dimensions as soon as possible. I've tried Overriding both onStart() and onResume() to check the dimensions as well, but in both cases I still get 0.
So my question is, where in the Android Activity start up flow, is the first place I can get the actual size of a View? I want to be able to get the height/width as soon as I can, and I want to do it before the user has a chance to interact with the environment.
There's a fairly useful thing in Android called the ViewTreeObserver. I've done precisely what you need to do many times this way. As you've discovered, you need to wait until at least the measure cycle completes. Try something like the following:
...
setContextView(R.layout.activity_puzzle_picker);
final View view = findViewById(R.id.pickshapes);
view.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
int height = view.getMeasuredHeight();
if(height > 0) {
// do whatever you want with the measured height.
setMyViewHeight(height);
// ... and ALWAYS remove the listener when you're done.
view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
}
});
...
(Note that you haven't set the id of your view in your XML... I'm using R.id.pickshapes because that's what you chose.)

Android: TextView.setLayoutParams sometimes work, sometimes doesn't

I have an android app that let's the user modify some layout parameters. One of my functions let's the user decide if a TextView will be aligned against the top or the bottom of a picture.
This is the function:
private void setAlign(String align) {
/* Get Preferences */
SharedPreferences prefs = getSharedPreferences("prefs", Context.MODE_WORLD_READABLE);
SharedPreferences.Editor editor = prefs.edit();
editor.putString("align", align);
editor.commit();
Log.d("ALIGN", align);
paramAlign = align;
FrameLayout.LayoutParams floLP = new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.WRAP_CONTENT,
FrameLayout.LayoutParams.WRAP_CONTENT,
(align == "TOP") ? Gravity.TOP : Gravity.BOTTOM);
txtGoal.setLayoutParams(floLP);
int res = paramAlign == "TOP" ? R.drawable.btn_toolbar_align_top_up : R.drawable.btn_toolbar_align_bottom_up ;
btnAlign.setImageResource(res);
}
Now once the activity is started, this function works fine. However, when I initialize the activity, I call the setAlign() function in the onGlobalLayout method after retrieving the alignment preference.
This is the relevant code:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.personalize);
/* Get Preferences */
SharedPreferences prefs = getSharedPreferences("prefs", Context.MODE_WORLD_READABLE);
paramAlign = prefs.getString("align", "BOTTOM");
Log.d("ALIGN", paramAlign);
// Get screen dimensions and initialize preview
ViewTreeObserver vto = rootView.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
setAlign(paramAlign);
ViewTreeObserver obs = rootView.getViewTreeObserver();
obs.removeGlobalOnLayoutListener(this);
}
});
}
Now if you notice the logging functions, they both return "TOP" when I start the activity. And the setAlign() function is obviously getting called. Yet, the TextView is aligned at the bottom. This is the XML for the TextView:
<TextView
android:id="#+id/txtGoal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dip"
android:textColor="#color/color_white"
android:textSize="8sp"
android:shadowColor="#color/color_black"
android:shadowDx="1.2"
android:shadowDy="1.2"
android:shadowRadius="1.2"
/>
Any idea why the setLayoutParams is not happening when the activity is created? The function is getting fired when the layout is done being drawn so it shouldn't be the issue here. And the XML has no gravity specified to start with.
What am I missing here?
First of all, I see that the variable txtGoal is not initialized (nor even declared) so I am assuming you did that somewhere else (that is not posted in the question).
The behavior you are encountering is pretty much normal : the function is working only at start-up, and that's because once you change the layout of your text view, you must indicate that so it will be redrawn, by adding the following :
txtGoal.invalidate ();
after this :
txtGoal.setLayoutParams(floLP);
EDIT:
You can also try changing the gravity in a different way:
txtGoal.setGravity ( Gravity.TOP );
EDIT:
My apologies, what I suggest (the second solution) is wrong, because it changes the gravity of the text inside the text view (and not the gravity of the text view inside the root view).
Please try the following:
Do not try to modify the gravity of your text view using a listener, you can directly apply the gravity you want after setting the content view of your activity (because the text view is thus created). I advise the following:
Apply the new layout to your text view directly (not via the listener) after retrieving the shared preferences.
Your onCreate method should look something similar to this:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.personalize);
/* Get Preferences */
SharedPreferences prefs = getSharedPreferences("prefs", Context.MODE_WORLD_READABLE);
paramAlign = prefs.getString("align", "BOTTOM");
setAlign(paramAlign);
}
You should compare two string using the equals method:
Replace that :
(align == "TOP")
By that
align.equals ( "TOP" )
And this :
paramAlign == "TOP"
By this :
paramAlign.equals ( "TOP" )
So, here is what I found out and what I did to fix my problem.
Apparently the condition
align == "TOP"
Was not testing true when the activity was started altho the Log dump would tell me that it was in fact true at the time. Now why it did that I have no clue. This seems like a weird bug. That condition tested true once the activity was running.
Since this parameter could only have 2 values, I switched it to a Boolean variable where false is now the equivalent of "BOTTOM" and true the equivalent of "TOP" and it is working perfectly.
This is something that might actually need to be looked into as the condition should of tested true at startup.
** EDIT **
You cannot compare 2 strings in java using the "==" operator. You have to use .equals() instead.

Changing font in AlertDialog

Could someone suggest a way to change font in a dynamically created AlertDialog (in title and body)? I tried in loads of ways, but none of them worked. The code is:
public void onClick(View v) {
new AlertDialog.Builder( c )
.setTitle( data.eqselect )
// .set
.setIcon(R.drawable.icon)
.setMessage(Threads.myData[0] )
.setNegativeButton( "Close", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
Log.d( "AlertDialog", "Negative" );
}
} )
.show();
}
Instead of setting the text of the alertdialog, you should set a custom view form your layouts. And before you do so, modify your view's font.
TextView mycontent = (TextView) findViewById(R.id.yourid);
mycontent.setTypeface(Typeface.createFromAsset(getAssets(), "font.ttf")
And to set the view of your alert dialog, call .setView(mycontent) instead of setMessage()
Although this doesn't change your title as far as I know.
Update
I'm seeing you're unable to get what I'm saying, so here's a full example
TextView content = new TextView(this);
content.setText("on another font");
content.setTypeface(Typeface.SANS_SERIF);
//Use the first example, if your using a xml generated view
AlertDialog.Builder myalert = new AlertDialog.Builder(this);
myalert.setTitle("Your title");
myalert.setView(content);
myalert.setNeutralButton("Close dialog", null);
myalert.setCancelable(true);
myalert.show();
This is using a TextView that we've just created, and it won't have margins or such. If you use a readily created one form your layout files, you'd be able to customize all those settings, although you can do that for this example to in code.
Of course, replace the font with the one you want..
A sample TextView from xml could be:
<TextView
android:id="#+id/yourid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="8dp"
android:text="your content" />

Custom AlertDialog fails to initialize in onCreate()

I'm trying to build a custom AlertDialog by extending the AlertDialog class.
As usual, I'm setting up the dialog inside its onCreate() method. Or, I'm trying to do so:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setTitle("Some title");
this.setButton(BUTTON_POSITIVE, "Click me", (DialogInterface.OnClickListener)null);
final FrameLayout custom = (FrameLayout) this
.findViewById(android.R.id.custom);
custom.addView(this.getLayoutInflater().inflate(R.layout.mydlg, null),
LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
}
Now, when it comes to displaying an instance of this dialog, nothing is shown. The current Activity fades out and loses focus but not a single pixel of my dialog is displayed. Pressing Back brings the Activity back to the foreground, indicating to me that a dialog actually is shown, but just a completely empty one.
However, when I create an AlertDialog and use, for instance, dlg.setButton(BUTTON_POSITIVE, "Click me", (DialogInterface.OnClickListener)null);
the dialog is shown with the respective button.
Even when I set up my custom dialog in its constructor using the very same code as above everything seems to work ok.
Now, how can this be? Why can't I seem to initialize my dialog in its onCreate() method? Isn't this the way you're supposed to initialize any GUI element? What am I missing?
EDIT
Please note, that something is 'shown', fading out the Activity and taking focus from it. It's just that it seems to be completely empty/invisible.
Here another attempt:
this.setTitle("Some title");
this.setButton(BUTTON_POSITIVE, "Click me", (DialogInterface.OnClickListener)null);
final View v = this.getLayoutInflater().inflate(R.layout.mydlg, null);
this.setView(v);
These exact lines do work when put into my dialog's constructor.
These exact lines do not work when put into my dialog's onCreate().
What is going on here?!
Generally, am I not supposed to do it in onCreate()? - Am I facing trouble if I resort to doing the above initialization in the constructor instead? (This does not seem too clean to me, anyway.)
You need to call the show() method in order to see something.
You should consider using AlertDialog.Builder instead of subclassing AlertDialog itself. It allows you to do all the things you need in your example (in order: setTitle(),setPositiveButton() and setView() ). Don't forget to call create() at the end to actually get your dialog.
Also, check if your onCreateDialog() and onPrepareDialog() activity methods are implemented correctly. If you don't have them implemented at all (an unmanaged dialog), consider doing that anyway, especially if your app allows for orientation changes. You probably know about this, but here is a tutorial:
http://developer.android.com/guide/topics/ui/dialogs.html
also, DialogFragments are a bit easier way to implement this, but you need a newer API version or the Compatibility package:
http://developer.android.com/reference/android/app/DialogFragment.
One final issue - where are you calling show() in your activity? onResume() should be OK, onCreate() not as much.
Sorry I'm late to the party :)
You have to thing differently for the alert dialog.
The way I did it is to customize the view before creating the alert dialog:
// This is the activity that is the background of the AlertDialog
public class Main extends Activity {
public static final int DIALOG_CONFIG = 1;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.emptybackground);
}
#Override
protected void onStart() {
super.onStart();
// Open the alert dialog on openning the Activity
showDialog(Main.DIALOG_CONFIG );
}
protected Dialog onCreateDialog(int id) {
LayoutInflater factory = LayoutInflater.from(this);
switch (id) {
case DIALOG_CONFIG:
// Here, we load the existing view R.layout.config
configView = factory.inflate(R.layout.config, null);
configDialog = new AlertDialog.Builder(this)
.setTitle("Configuration")
.setView(configView)
.create();
// Using configView, you can do whatever you want with the view. Here, we add value to a spinner.
Spinner spinner = (Spinner)configView.findViewById(R.id.config_select_conn);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
adapter.add("TCP");
adapter.add("Bluetooth");
spinner.setAdapter(adapter);
return configPrinter;
}
return null;
}
}
you should call custom_alertDialog.create(); before custom_alertDialog.show();

How to set focus on a view when a layout is created and displayed?

Currently, I have a layout which contains a Button, a TextView and an EditText. When the layout is displayed, the focus will be automatically put on the EditText, which will trigger the keyboard to show up on Android phone. It is not what I want. Is there any way that I can set the focus on TextView or on nothing when a layout is displayed?
Set focus: The framework will handled
moving focus in response to user
input. To force focus to a specific
view, call requestFocus()
This works:
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
You should add this:
android:focusableInTouchMode="true"
To set focus, delay the requestFocus() using a Handler.
private Handler mHandler= new Handler();
public class HelloAndroid extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
LinearLayout mainVw = (LinearLayout) findViewById(R.id.main_layout);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.FILL_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
EditText edit = new EditText(this);
edit.setLayoutParams(params);
mainVw.addView(edit);
TextView titleTv = new TextView(this);
titleTv.setText("test");
titleTv.setLayoutParams(params);
mainVw.addView(titleTv);
mHandler.post(
new Runnable()
{
public void run()
{
titleTv.requestFocus();
}
}
);
}
}
Set
android:focusable="true"
in your <EditText/>
You can try just hidding the keyboard. Something like this:
InputMethodManager inputManager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
Set these lines to OnResume as well and make sure if focusableInTouch is set to true while you initialize your controls
<controlName>.requestFocus();
<controlName>.requestFocusFromTouch();
Try
comp.requestFocusInWindow();
to change the focus make the textView in xml focusable
<TextView
**android:focusable="true"**
android:id="#+id/tv_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
and in java in on create
textView.requestFocus();
or simply hide the keyboard
public void hideKeyBoard(Activity act) {
act.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
InputMethodManager imm = (InputMethodManager) act.getSystemService(Context.INPUT_METHOD_SERVICE);
}
None of the answers above works for me. The only (let's say) solution has been to change the first TextView in a disabled EditText that receives focus and then add
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
in the onCreate callback to prevent keyboard to be shown. Now my first EditText looks like a TextView but can get the initial focus, finally.
The last suggestion is the correct solution. Just to repeat, first set android:focusable="true" in the layout xml file, then requestFocus() on the view in your code.
i think a text view is not focusable. Try to set the focus on a button for example, or to set the property focusable to true.
you can add an edit text of size "0 dip" as the first control in ur xml, so, that will get the focus on render.(make sure its focusable and all...)
You can start by adding android:windowSoftInputMode to your activity in AndroidManifest.xml file.
<activity android:name="YourActivity"
android:windowSoftInputMode="stateHidden" />
This will make the keyboard to not show, but EditText is still got focus. To solve that, you can set android:focusableInTouchmode and android:focusable to true on your root view.
<LinearLayout android:orientation="vertical"
android:focusable="true"
android:focusableInTouchMode="true"
...
>
<EditText
...
/>
<TextView
...
/>
<Button
...
/>
</LinearLayout>
The code above will make sure that RelativeLayout is getting focus instead of EditText
Focus is for selecting UI components when you are using something besides touch (ie, a d-pad, a keyboard, etc.). Any view can receive focus, though some are not focusable by default. (You can make a view focusable with setFocusable(true) and force it to be focused with requestFocus().)
However, it is important to note that when you are in touch mode, focus is disabled. So if you are using your fingers, changing the focus programmatically doesn't do anything. The exception to this is for views that receive input from an input editor. An EditText is such an example. For this special situation setFocusableInTouchMode(true) is used to let the soft keyboard know where to send input. An EditText has this setting by default. The soft keyboard will automatically pop up.
If you don't want the soft keyboard popping up automatically then you can temporarily suppress it as #abeljus noted:
InputMethodManager inputManager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
When a user clicks on the EditText, it should still show the keyboard, though.
Further reading:
Having Trouble Focusing? A Primer on Focus in Android
Android Developers Blog: Touch Mode
You can add
android:importantForAccessibility="yes"
android:focusable="true"
android:focusableInTouchMode="true"
to your Layout to force Talkback/accessibility to go there first.
You really only need the first line, however, the others reinforce to the OS what you want focused.
You can use the following Kotlin extension
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)
}
}
}
)
}
}
And just call your view.focusAndShowKeyboard() in override fun onViewCreated(..) or override fun OnCreate(..)
PS: For hiding Views use the following extension
fun View.hideKeyboard() {
val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(windowToken, 0)
}
Make sure the views are focusable before that using the following android XML attributes, u can also do it programmatically
android:focusableInTouchMode="true"
android:focusable="true"

Categories