Android Kotlin button + alert dialog + list - android

I have this code:
var firstKitList = mutableListOf<String>("test", "potato", "another item")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_kit_list)
val mainKitList = kitListView
val mainListViewAdapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, firstKitList)
mainKitList.adapter = mainListViewAdapter
newKitListBtn.setOnClickListener {
// Handler code here.
val intent = Intent(this, NewKitListActivity::class.java)
startActivity(intent);
}
}
For this layout.
How do I go around for when I click the button, to show up an alert dialog for me too add a name (as if I was creating an item to be added to that list) and then go to the next activity? (this part is already created as you can see on the code)

I created function which hold alert dialog with editText. When your click on save name will be stored in multableList and redirected to new activity.
Modified Code
var firstKitList = mutableListOf<String>("test", "potato", "another item")
// Mutable List for holding names
val nameList = mutableListOf<String>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_kit_list)
val mainKitList = kitListView
val mainListViewAdapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, firstKitList)
mainKitList.adapter = mainListViewAdapter
newKitListBtn.setOnClickListener {
// Show Alert Dialog
showNewNameDialog()
}
}
Alert Dialog Function
fun showNewNameDialog() {
val dialogBuilder = AlertDialog.Builder(this)
val inflater = this.layoutInflater
val dialogView = inflater.inflate(R.layout.custom_dialog, null)
dialogBuilder.setView(dialogView)
val editText = dialogView.findViewById<EditText>(R.id.editTextName)
dialogBuilder.setTitle("Custom dialog")
dialogBuilder.setMessage("Enter Name Below")
dialogBuilder.setPositiveButton("Save", { dialog, whichButton ->
//do something with edt.getText().toString();
// Add Name in list
nameList.add(editText.text.toString())
// Handler code here.
val intent = Intent(this, NewKitListActivity::class.java)
startActivity(intent);
})
dialogBuilder.setNegativeButton("Cancel", { dialog, whichButton ->
//pass
})
val b = dialogBuilder.create()
b.show()
}
Custom Dialog Layout: custom_dialog.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:padding="10dp"
android:orientation="vertical">
<EditText
android:id="#+id/editTextName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text" />
</LinearLayout>

I changed the code from Rajesh Dalsaniya's answer to be a bit more concise using kotlin's features:
fun showNewNameDialog(activity: Activity) {
AlertDialog.Builder(activity).apply {
val dialogView = activity.layoutInflater.inflate(R.layout.custom_dialog, null)
val editText = dialogView.findViewById<EditText>(R.id.editTextName)
setView(dialogView)
setTitle("Custom dialog")
setMessage("Enter Name Below")
setPositiveButton("Save") { _, _ ->
//do something with edt.getText().toString();
// Add Name in list
activity.nameList.add(editText.text.toString())
// Handler code here.
val intent = Intent(activity, NewKitListActivity::class.java)
activity.startActivity(intent);
}
setNegativeButton("Cancel") { _, _ ->
//pass
}
}.create().show()
}
The xml stays:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:padding="10dp"
android:orientation="vertical">
<EditText
android:id="#+id/editTextName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text" />
</LinearLayout>

Related

Popup dialog spinner with bondedDevices is null

When trying to make a popup dialog with paired bluetooth devices in a spinner, my app crashes upon opening. See this code for the xml layout:
<?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:padding="10dp">
<Spinner
android:id="#+id/spinner_devices"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<Button
android:id="#+id/bConnectBtn"
android:text="CONNECT"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
In the code below here, I call a function that checks for bonded devices and then puts it in the spinner:
private fun onBluetoothEnabled() {
val bondedDevices = bluetoothAdapter?.bondedDevices
if (bondedDevices != null) {
val bondedAdapter = ArrayAdapter(this, android.R.layout.simple_spinner_item, bondedDevices.map { it.name })
bondedAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
spinner_devices.adapter = bondedAdapter
bConnectBtn.setOnClickListener {
val device = bondedDevices.toList()[spinner_devices.selectedItemPosition]
setupClient(device)
}
}
}
Here I show the dialog:
val bluetoothView = layoutInflater.inflate(R.layout.bluetoothdialog, null)
val bluetoothDialog = AlertDialog.Builder(this#MainActivity)
bluetoothDialog.setTitle("Paired Devices")
bluetoothDialog.setView(bluetoothView)
bluetoothDialog.setCancelable(false)
bluetoothDialog.setNeutralButton("TEMP CLOSE") { _, _ -> }
bluetoothDialog.show()
Some extra details about this, this works just fine when the spinner is in the main activity xml, but when I put the spinner in a popup dialog xml file, it crashes upon start. When I add ? or !! to spinner_devices?.adapter it works but doesn't fill the spinner with the bonded devices which makes sense because it allows null now.
When I debug my code, I can see that the bondedApapter gets filled with paired bluetooth devices, but when it gets to the spinner_devices.adapter it is null. Any guesses on what I am doing wrong?
There is some object initialization when you tries to bind adapter from AlertDialog. Checkout the below code that is working fine.
val bluetoothView = layoutInflater.inflate(R.layout.bluetoothdialog, null)
val bluetoothDialog = AlertDialog.Builder(this#MainActivity)
bluetoothDialog.setTitle("Paired Devices")
bluetoothDialog.setView(bluetoothView)
bluetoothDialog.setCancelable(false)
bluetoothDialog.setNeutralButton("TEMP CLOSE") { _, _ ->}
bluetoothDialog.show()
**//get views from inflated layout
val spinnerDevices = bluetoothView.findViewById(R.id.spinner_devices)
val bConnectBtn = bluetoothView.findViewById(R.id.bConnectBtn)**
//bind adapter
val bondedAdapter = ArrayAdapter(this, android.R.layout.simple_spinner_item, bondedDevices.map { it.name })
bondedAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
spinnerDevices.adapter = bondedAdapter
bConnectBtn.setOnClickListener {
val device = bondedDevices.toList()[spinnerDevices.selectedItemPosition]
Toast.makeText(this#MainActivity,"Connection to:${device.name}",Toast.LENGTH_SHORT).show()
}
For those wondering. I was able to fix it and made it a bit more usefull by being able to click on a bluetooth device and make it connect. See code below for full code:
private fun showPairedDevicesPopup() {
val bluetoothAdapter = BluetoothAdapter.getDefaultAdapter()
val pairedDevices: Set<BluetoothDevice> = bluetoothAdapter.bondedDevices
// Create a list of device names
val deviceNames = ArrayList<String>()
pairedDevices.forEach { deviceNames.add(it.name) }
// Create an array adapter to display the list of device names
val adapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, deviceNames)
// Build the alert dialog
val builder = AlertDialog.Builder(this)
builder.setTitle("Paired Devices")
builder.setCancelable(false)
builder.setAdapter(adapter) { _, which ->
// Get the selected device
val selectedDevice = pairedDevices.elementAt(which)
// Attempt to connect to the selected device
val socket: BluetoothSocket?
try {
socket = selectedDevice.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"))
socket.connect()
} catch (e: IOException) {
// Failed to connect to the device
e.printStackTrace()
}
}
builder.setNegativeButton("Cancel") { dialog, _ ->
dialog.dismiss()
}
// Show the alert dialog
val dialog = builder.create()
dialog.show()
}

AlertDialog hyperlink not clickable

I have a alertdialog that contains a hyperlink, however the hyperlink isn't clickable. It does show as a hyperlink
val termsDialog = AlertDialog.Builder(this#MainActivity)
val termsView = layoutInflater.inflate(R.layout.termsdialog, null)
val termsBox: CheckBox = termsView.findViewById(R.id.termsCheckbox)
val termsMsg = Html.fromHtml("By using this application you accept to our Terms and Conditions and Privacy Policy. \nMore information here")
termsDialog.setTitle("Terms and Conditions")
termsDialog.setView(termsView)
termsDialog.setMessage(termsMsg)
termsDialog.setPositiveButton("OK") { _, _ -> }
termsDialog.setCancelable(false)
termsBox.setOnCheckedChangeListener { compoundButton, _ ->
if (compoundButton.isChecked) {
storeDialogStatus(true)
} else {
storeDialogStatus(false)
}
}
// Automatic show terms dialog when dialog status is not checked
if (!this.getDialogStatus()) {
termsDialog.show()
}
Create a TextView for your message in termsdialog.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">
<TextView
android:id="#+id/dialog_textview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
Then you must call setMovementMethod(LinkMovementMethod.getInstance()) on your TextView:
val termsDialog = AlertDialog.Builder(context)
val termsView = layoutInflater.inflate(R.layout.termsdialog, null)
val termsMessage: TextView = termsView.findViewById(R.id.dialog_textview)
val termsMsg = Html.fromHtml("By using this application you accept to our Terms and Conditions and Privacy Policy. \nMore information here")
termsDialog.setTitle("Terms and Conditions")
termsDialog.setView(termsView)
termsMessage.setText(termsMsg)
termsMessage.setMovementMethod(LinkMovementMethod.getInstance())
termsDialog.show()

Don't dismiss AlertDialog if EditText is empty

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()
}
}
}

Conditional button actions depending on selected item in a ListView

I´m trying to display a message when pressing a button but nothing has been selected in list1. And if an item is selected, I want it to get the listView layout visibility set to gone and the website layout visibility set to visible.
All I get when pressing the button is the toast message no matter what.
Here is the code:
My button:
button1.setOnClickListener {
var selectedObj = list1.getSelectedItem()
if (selectedObj == null) {
toast("You need to choose an item form the list first")
}
else {
val builder = AlertDialog.Builder(this)
builder.setTitle("Warning")
builder.setMessage("This service requires data")
builder.setPositiveButton("Yes", { dialogInterface: DialogInterface, i: Int ->
ListView.visibility = View.GONE
website.visibility = View.VISIBLE
})
builder.setNegativeButton("No", { dialogInterface: DialogInterface, i: Int -> })
builder.show()
}
}
here is my listView:
<ListView
android:id="#+id/list1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:choiceMode="singleChoice"
android:focusable="true"
android:focusableInTouchMode="true"
android:listSelector="#android:color/darker_gray"
android:textSize="10dp"
</ListView>
my code:
val nameofanimals = arrayOf("cat","dog","parrot")
val list1 = findViewById(R.id.list1) as ListView
internal lateinit var adapteranimals: ArrayAdapter<String>
my adapter:
adapteranimals = ArrayAdapter(
this#MainActivity,
R.layout.list1layout,
nameofanimals)
list1.adapter = adapteranimals
Tyvm in advance for yout support
Regards.
ListView does not store selectedItem position when you set choice mode. It stores the checked item position.
Check this out
class MainActivity : AppCompatActivity() {
private lateinit var listView:ListView
internal lateinit var adapteranimals: ArrayAdapter<String>
val nameofanimals = arrayOf("cat","dog","parrot")
private lateinit var btn1:Button
private lateinit var myobject:String
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
listView = findViewById<ListView>(R.id.list1)
btn1 = findViewById<Button>(R.id.btn1)
adapteranimals = ArrayAdapter(
this#MainActivity,
R.layout.list1layout,
nameofanimals)
listView.adapter = adapteranimals
btn1.setOnClickListener {
val pos = listView.getCheckedItemPosition()
myobject = listView.getAdapter().getItem(pos) as String
Log.d("Selected item",myobject);
}
}
}
You are trying to access the variable from list and you expect the list to store that variable position. But unfortunately list does not save the click item position. Use this code and the item that is clicked is in position.
ListView list = (ListView) findViewById(R.id.listview);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// Object listItem = list.getItemAtPosition(position);
ListView.visibility = View.GONE
website.visibility = View.VISIBLE
//you can get the list item clicked in position variable
}
});

How to use anko spinner?

I'm trying to add a spinner inside an alert using anko. My code so far looks like this:
alert(getString(R.string.alert)) {
positiveButton("Cool") { toast("Yess!!!") }
customView {
linearLayout {
textView("I'm a text")
padding = dip(16)
orientation = LinearLayout.VERTICAL
spinner(R.style.Widget_AppCompat_Spinner) {
id = R.id.spinner_todo_category
prompt = "Select a Category"
}
}
}
}.show()
but I get compilation errors because apparently that's not how to call a spinner. I've been looking at the docs (Anko GitHub Wiki) but it says nothing about spinners.
Thanks in advance
One solution :
class AddActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val items = listOf(Friend("bla","bla",50),Friend("bla","bla",50));
val adapterFriends = ArrayAdapter(this,R.layout.mon_spinner,items)
verticalLayout {
val friends = spinner { adapter = adapterFriends }
val wine = editText()
button("Say Hello") {
onClick { toast("Hello, ${wine.text}!") }
}
}
}
}
with this layout (mon_spinner.xml) :
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:textSize="14sp"
android:textColor="#color/colorPrimary"
android:spinnerMode="dialog"
android:text="XXX"
/>
It's all right !!
Try this in your AnkoComponent:
spinner {
adapter = ArrayAdapter.createFromResource(
ctx,
R.array.your_string_array,
android.R.layout.simple_spinner_dropdown_item)
}

Categories

Resources