I am trying to get the text of a textInputEditText, which is in a dialog (to be exact the onCreateDialog method in the set positive button section), but it doesn't work. I've read many questions which already are on StackOverflow, but none helped me.
The variable inputAddTunnel in which the text should be saved, is always just equal to "":
private fun getInput(): String {
val inputAddTunnel = this.layoutInflater.inflate(R.layout.dialog_add_vpn_tunnel,null).findViewById<TextInputEditText>(R.id.input_add_tunnel).getText().toString()
return inputAddTunnel
}
The Xml for the dialog is:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/input_add_tunnel_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:hint="#string/name_of_vpn">
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/input_add_tunnel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"/>
</com.google.android.material.textfield.TextInputLayout>
Edit: Here is the onCreateDialog() method
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return activity?.let {
val builder = androidx.appcompat.app.AlertDialog.Builder(it)
// Get the layout inflater
val inflater = requireActivity().layoutInflater
// Inflate and set the layout for the dialog
// Pass null as the parent view because its going in the dialog layout
builder.setView(inflater.inflate(R.layout.dialog_add_vpn_tunnel, null))
// Add action buttons
.setPositiveButton(R.string.add_vpn_tunnel,
DialogInterface.OnClickListener { dialog, id ->
// Add VPN tunnel
addVpn()
})
.setNegativeButton(R.string.cancel,
DialogInterface.OnClickListener { dialog, id ->
getDialog()?.cancel()
})
builder.create()
} ?: throw IllegalStateException("Activity cannot be null")
}
And this is the addVpn method, which is called in onCreateDialog():
private fun addVpn() {
// TODO test function addVpn(); count doesn't work properly
val count = activity?.getPreferences(AppCompatActivity.MODE_PRIVATE)?.getInt("countTunnels", -1)
val inputAddTunnel = getInput()
// If inputAddTunnel is not equal to "", put it in getPreferences
if(inputAddTunnel != "") { //TODO test if !== is needed, not !=
activity?.getPreferences(AppCompatActivity.MODE_PRIVATE)?.
edit()?.putString("tunnel$count", inputAddTunnel).apply { }
}
// Edit the count in getPreferences to the incremented count
count?.plus(1)
if (count != null) {
activity?.getPreferences(AppCompatActivity.MODE_PRIVATE)?.getInt("countTunnels", count)
}
}
You need to get editext object from dialog view and call getText() method
Edittext edittext= getDialog().getView().findViewbyId(R.id.editText);
edittext.getText(); // for getting textvalue from editetxt
You are re-inflating a brand new view, not querying from the one you already set for your dialog.
You should call findViewById on the root dialog view that you initially inflated. Please share your onCreateDialog method for more help.
Related
I'm trying to create a to-do list. first click menu item (add) and alertdialog write edittext and save but I'm trying to get editable text with alarm box but i get always same number.
number photo
i write bread but same number generate photo
here is a menu code
R.id.add -> {
val mDialogView = LayoutInflater.from(this).inflate(R.layout.dialog_add_todo, null)
AlertDialog.Builder(this).setView(mDialogView).setTitle("ADD TODO").setPositiveButton("Save"){
dialogInterface, i ->
val todoTitle = R.id.et_dialog_add.toString()
if(todoTitle.isNotEmpty()) {
val todo = Todo(todoTitle)
todoAdapter.addTodo(todo)
alert dialog:
<EditText
android:id="#+id/et_dialog_add"
android:hint="Buy a Bread"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</EditText>
here is adapters:
fun addTodo(todo: Todo) {
todos.add(todo)
notifyItemInserted(todos.size -1)
}
This is your problem:
val todoTitle = R.id.et_dialog_add.toString()
This is not how you get the text value from an EditText field. You need to first use findViewById() to get a reference to the EditText, and then you can use its text property to get what the user entered:
val todoTitleView = mDialogView.findViewById<EditText>(R.id.et_dialog_add)
val todoTitle = todoTitleView.text
I have custom dialog where inside its xml has a Submit button that whenever clicked, it should dismiss the softKeyboard.
I have the following code:
MainActivity.kt (Inherits from BaseActivity)
val updateDialog = Dialog(this, R.style.CustomDialog)
updateDialog.setContentView(R.layout.dialog_update)
val tvSubmitToFirestore = updateDialog.findViewById<HelveticaBoldTextView>(R.id.tv_update_item)
tvSubmitToFirestore.setOnClickListener {
hideKeyboard(currentFocus ?: View(this))
}
BaseActivity:
open class BaseActivity : AppCompatActivity() {
//hide keyboard when instance of an event
fun Context.hideKeyboard(view: View) {
val inputMethodManager = getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
inputMethodManager.hideSoftInputFromWindow(view.windowToken, 0)
}
}
But the keyboard remains on its position after clicking the said button.
Update:
//update item
val tvUpdate = showItemDialog.findViewById<HelveticaNormalTextView>(R.id.tv_update)
tvUpdate.setOnClickListener {
//close search dialog
showItemDialog.dismiss()
val updateDialog = Dialog(this, R.style.CustomDialog)
updateDialog.setContentView(R.layout.dialog_update)
updateDialog.setCancelable(false)
//spinner settings
val spinner = updateDialog.findViewById<Spinner>(R.id.sp_update)
populateSpinner(spinner, dialogProductCategory.text.toString())
//set default values of update dialog fields == the current product's properties(name, category, price)
val etProductName = updateDialog.findViewById<TextInputEditText>(R.id.et_update_product_name)
val etProductPrice = updateDialog.findViewById<TextInputEditText>(R.id.et_update_product_price)
etProductName.setText(dialogProdName.text.toString())
etProductPrice.setText(dialogProductPrice.text.toString())
//update item
val tvSubmitToFirestore = updateDialog.findViewById<HelveticaBoldTextView>(R.id.tv_update_item)
//TODO allow user to update an item with the same name provided that it should only exist once
// and must be unique
tvSubmitToFirestore.setOnClickListener {
// hideKeyboard(currentFocus ?: tvSubmitToFirestore)
hideKeyboard1(it, this#MainActivity)
val newProductName = etProductName.text.toString().trim()
val newProductCategory = spinner.selectedItem.toString().uppercase()
val newProductPrice = etProductPrice.text.toString().toDouble()
GlobalScope.launch {
validateProduct(newProductName, newProductCategory, newProductPrice)
}
//TODO : allow user to reuse the product name when updating
}
You can use the new WindowInsetsController library to hide and show keyboard. Use this function:
fun hideKeyboard(view: View, activity: Activity) {
WindowInsetsControllerCompat(activity.window, view).hide(WindowInsetsCompat.Type.ime())
}
In your case, you call use it like this:
tvSubmitToFirestore.setOnClickListener { view ->
hideKeyboard(view, this) // 'this' refers to MainActivity
}
I implemented a "Don't show again" option to my Alert Dialog, but it's not working as intended:
All the other questions are 6-7 years old and in java, and since I am completely new to programming I only know the basics of kotlin as of right now..
fun showDialog() {
val dialogBuilder = AlertDialog.Builder(context)
val inflater = requireActivity().layoutInflater;
dialogBuilder.setView(inflater.inflate(R.layout.alert, null))
dialogBuilder.setMessage("Please always put the total on the bottom right corner. An example is shown below.")
dialogBuilder.setPositiveButton("Alright, got it!",
DialogInterface.OnClickListener { dialog, whichButton ->
pb.visibility = View.VISIBLE
checkPermission(Manifest.permission.CAMERA,CAMERA_PERMISSION_CODE)
startActivityForResult(receiptsViewModel.cameraIntent(requireActivity()),REQUEST_CODE_KAMERA)
})
val mainView: View = inflater.inflate(R.layout.alert, null)
checkBox = mainView.findViewById<View>(R.id.checkBox) as CheckBox
val b = dialogBuilder.create()
b.show()
checkBox.setOnCheckedChangeListener { compoundButton, b ->
if (compoundButton.isChecked) {
storeDialogStatus(true)
} else {
storeDialogStatus(false)
}
}
if (dialogStatus) {
b.hide()
} else {
b.show()
}
}
private fun storeDialogStatus(isChecked: Boolean) {
val mSharedPreferences = requireActivity().getSharedPreferences("CheckItem", AppCompatActivity.MODE_PRIVATE)
val mEditor = mSharedPreferences.edit()
mEditor.putBoolean("item", isChecked)
mEditor.apply()
}
private val dialogStatus: Boolean
private get() {
val mSharedPreferences = requireActivity().getSharedPreferences("CheckItem",
AppCompatActivity.MODE_PRIVATE
)
return mSharedPreferences.getBoolean("item", false)
}
The problem I see is that the checkbox that you're adding a listener to is for a layout that you're not using. You inflated a layout and set that as your dialog view. Then you inflate a second copy of the layout and set a listener on the checkbox in that unused second layout.
A few other tips, but these aren't things that are preventing it from working. They'll just make your code clearer:
You can chain Builder calls so you don't have to keep putting dialogBuilder. and you don't even have to store it in a variable.
findViewById<View> can be changed to findViewById<CheckBox> so you don't have to cast its result to CheckBox.
You can return early from the function if the dialog isn't needed rather than creating the dialog, showing it, and then immediately hiding it.
Instead of using if (someBoolean) doSomething(true) else doSomething(false) you can simplify to doSomething(someBoolean).
private fun startCamera() {
pb.visibility = View.VISIBLE
checkPermission(Manifest.permission.CAMERA,CAMERA_PERMISSION_CODE)
startActivityForResult(
receiptsViewModel.cameraIntent(requireActivity()),
REQUEST_CODE_KAMERA
)
}
fun showDialog() {
if (dialogStatus) {
startCamera()
return
}
val mainView = requireActivity().layoutInflater.inflate(R.layout.alert, null)
checkBox = mainView.findViewById<CheckBox>(R.id.checkBox)
checkBox.setOnCheckedChangeListener { compoundButton, b ->
storeDialogStatus(compoundButton.isChecked)
}
AlertDialog.Builder(context)
.setView(mainView)
.setMessage("Please always put the total on the bottom right corner. An example is shown below.")
.setPositiveButton("Alright, got it!") { _, _ -> startCamera() }
.create()
.show()
}
I also find it odd that you have a property for checkBox that couldn't possibly be useful outside this function. You should probably remove the property.
Also, you should look into using DialogFragment instead of a bare Dialog. There are issues with bare Dialogs, such as them disappearing after a screen rotation. The official documentation explains how to use DialogFragment. I will admit, though, that I think DialogFragment is kind of convoluted to use, especially for a new Android programmer.
Your logic seems to be faulty. This piece of code does not work as intended:
if (dialogStatus) {
b.hide()
} else {
b.show()
}
You should not create the dialog at all if the user has opted out. Please try this modified code:
fun showDialog() {
if (dialogStatus) {
return
}
val dialogBuilder = AlertDialog.Builder(context)
val inflater = requireActivity().layoutInflater
dialogBuilder.setView(inflater.inflate(R.layout.alert, null))
.setMessage("Please always put the total on the bottom right corner. An example is shown below.")
.setPositiveButton("Alright, got it!",
DialogInterface.OnClickListener { dialog, whichButton ->
pb.visibility = View.VISIBLE
checkPermission(Manifest.permission.CAMERA, CAMERA_PERMISSION_CODE)
startActivityForResult(
receiptsViewModel.cameraIntent(requireActivity()),
REQUEST_CODE_KAMERA
)
})
dialogBuilder.create().show()
val mainView: View = inflater.inflate(R.layout.alert, null)
checkBox = mainView.findViewById<CheckBox>(R.id.checkBox)
checkBox.setOnCheckedChangeListener { compoundButton, b ->
if (compoundButton.isChecked) {
storeDialogStatus(true)
} else {
storeDialogStatus(false)
}
}
}
Despite a lot of searches and trials, I can't avoid my AlertDialog to close if my EditText is empty... I saw that it was a current issue on StackOverflow with a lot of responses but when I try it, it doesn't work...
Here is my Kotlin code, thanks for your help...
import androidx.appcompat.app.AlertDialog
import android.content.DialogInterface
private fun showMyEditextDialog() {
val alertDialog = AlertDialog.Builder(this)
val view = layoutInflater.inflate(R.layout.my_layout, null)
val myedittext = view.findViewById(R.id.myedittext) as EditText
alertDialog.setTitle(getString(R.string.title))
alertDialog.setView(view)
alertDialog.setCancelable(false)
alertDialog.setPositiveButton(R.string.ok, DialogInterface.OnClickListener { dialogInterface, i ->
var isValid = true
if ( isEmpty(myedittext.text.toString()) ) {
isValid = false
Toast.makeText(this, "empty", Toast.LENGHT_SHORT).show()
}
if ( isValid ) {
Toast.makeText(this, "yeah!", Toast.LENGHT_SHORT).show() }
if ( isValid ) {
dialogInterface.dismiss()
}
})
}
My xml :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/question" />
<EditText
android:id="#+id/myedittext"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="numberDecimal" />
</LinearLayout>
If I enter a value, I've got my "yeah" message.
If I don't enter a value, I've got my "empty" message but my dialog dismiss...
Thanks for your help,
MT
Use onShow to handle this like below:
val dialog = alertDialog.create()
dialog.setOnShowListener {
dialog.getButton(DialogInterface.BUTTON_POSITIVE).setOnClickListener {
var isValid = true
if ( isEmpty(myedittext.text.toString()) ) {
isValid = false
Toast.makeText(this#MainActivity, "empty", Toast.LENGTH_SHORT).show()
}
if ( isValid ) {
Toast.makeText(this#MainActivity, "yeah!", Toast.LENGTH_SHORT).show()
dialog.dismiss()
}
}
}
dialog.show()
I'm unsure if there's a way to bypass an alertdialog's buttons' functions. If there is, I've never found it. However, you could go with a much simpler solution. Just create your own "alert" view with an editText and buttons. Set the view to view.setVisibility(View.INVISIBLE) or (View.GONE), and any of its children views will be invisible or gone as well. I generally, when this is necessary, do this with a semi-transparent black background behind the view as the parent; and set that view's visibility back and forth. Then, you can customize the functionality of the buttons and the rest of the view in any way you want.
You need to get the positive button to override the method onclick
you can use this code:
private fun showMyEditextDialog() {
val alertDialog = AlertDialog.Builder(this)
val view = layoutInflater.inflate(R.layout.my_layout, null)
val myedittext = view.findViewById(R.id.myedittext) as EditText
alertDialog.setTitle(getString(R.string.title))
alertDialog.setView(view)
alertDialog.setCancelable(false)
alertDialog.setPositiveButton(R.string.ok, null)
alertDialog.create()
var dialog = alertDialog.create()
dialog.show()
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener {
var isValid = true
if ( isEmpty(myedittext.text.toString()) ) {
isValid = false
Toast.makeText(this, "empty", Toast.LENGTH_SHORT).show()
}
if ( isValid ) {
Toast.makeText(this, "yeah!", Toast.LENGTH_SHORT).show() }
if ( isValid ) {
dialog.dismiss()
}
}
}
I would like to dismiss Anko Dialog when pressing the button defined in my customLayout
val dialog = alert {
val view = layoutInflater.inflate(R.layout.match_stats, null)
val closeButton = view.findViewById<ImageButton>(R.id.closeButton)
closeButton.setOnClickListener { _ -> dialog.dismiss()}
customView = view
}
dialog.show()
I tried above code, unfortunately, I can’t get a reference to dialog in my onClickListener. Do you have any idea how to solve it?
You could declare variable before and assign null:
var dialog: DialogInterface? = null
dialog = alert {
val view = layoutInflater.inflate(R.layout.match_stats, null)
val closeButton = view.findViewById<ImageButton>(R.id.closeButton)
closeButton.setOnClickListener { _ -> dialog?.dismiss()}
customView = view
}.show()
Of course now your dialog variable is muttable and optional.