Conditional button actions depending on selected item in a ListView - android

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

Related

How to use SetOnClickListener on a programmatic ScrollView Android Kotlin

I created a scrollView programmaticaly that contains 20 views each with an image and a text.
I have two questions :
1 - is the id assignment correct and is my setOnClickListener correct?
2 - By which method onClick can I know which view of the scrollView the user has clicked?
See my code below
private var integerList: MutableList<Int>? = mutableListOf()
private var cellNo: MutableList<String>? = mutableListOf()
private var sv_mvmtChoosed = ""
private fun showSpinner() {
/* SCROllL VIEW */
var linearLayout: LinearLayout? = null
linearLayout = findViewById(R.id.linear1)
val layoutInflater = LayoutInflater.from(this)
var randIndex = 0
for (posIndex in 0..19) {
val rand = Random()
randIndex = rand.nextInt(20)
while (integerList!!.contains(randIndex)) {
randIndex = rand.nextInt(20)
}
integerList!!.add(randIndex)
// Create the view...
val view: View = layoutInflater.inflate(R.layout.scroll_bckgrnd, linearLayout, false)
// give it an id
view.id = generateViewId()
view.setOnClickListener(this)
cellNo!!.add(view.id.toString())
println(cellNo)
//... then populate it with image and text
val iv = view.findViewById<ImageView>(R.id.iv)
iv.setImageResource(sv_photoImage[randIndex])
val tv = view.findViewById<TextView>(R.id.tv)
tv.text = sv_photoName[randIndex]
linearLayout?.addView(view)
}
// which view the user did select?
fun onClick(view: View?) {
when (view!!.id) {
??? -> doSomething
}
}
}
Any idea to get me back on track will be welcome.
Its probably better to make a new OnClickListener for every view.
view.setOnClickListener(this)
needs to be this
view.setOnClickListener {
// do something
}
or
view.setOnClickListener(createOnClickListner())
fun createOnClickListner():View.OnClickListener{
return object :View.OnClickListener{
override fun onClick(view : View) {
//do something with the view that was clicked
}
}
}
Thanks a lot avalerio.
I finally found a solution as follow :
I replaced :
// give it an id
view.id = generateViewId()
view.setOnClickListener(this)
cellNo!!.add(view.id.toString())
println(cellNo)
with :
// give it an id
view.id = posIndex
view.setOnClickListener(this)
then I did this :
// the onClickListener for my 20 images/text
override fun onClick(view: View?) {
when (view!!.id) {
// Now de position clicked on the ScrollView
in 0..19 -> didHeSucceeded(view!!.id)
}
}
And use the result:
private fun didHeSucceeded(scrllPos: Int) {
// TODO: close de scrollView, how ? :-)
spinnerChoice = nameOfTechScrollVw[scrllPos]
succes = (!allreadyChoosedArray.contains(spinnerChoice)) && (currentArray.contains(spinnerChoice
))
if (succes) {
...
...
}
It works perfectly

How to make android spinner show same item always instead of changing

Long story short. I want my spinner to always show same first item "Add". When item selected from the list it should be gone from the list and the specific action happen. The text "Add" should still appear on spinner. So my question is how to make that spinner always show first item on his dataList? PS. I made that first item in the list don't show when drop down is open.
My layout:
<Spinner
android:id="#+id/spinner_add"
style="#style/Widget.AppCompat.Spinner.Underlined"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:backgroundTint="#color/colorButton" />
Method to set spinner adapter with data list:
private fun fillAddSpinner() {
val spinner: Spinner = findViewById(R.id.spinner_add)
val titles: MutableList<String> = ArrayList()
titles.add(resources.getString(R.string.add_advanced_filter))
for (filter in tableAdvancedFilters) {
titles.add(filter.title)
}
val dataAdapter = object : ArrayAdapter<String?>(this, R.layout.spinner_item,
titles as List<String?>
) {
override fun getDropDownView(
position: Int,
convertView: View?,
parent: ViewGroup
): View {
var v: View? = null
// If this is the initial dummy entry, make it hidden
if (position == 0) {
val tv = TextView(context)
tv.height = 0
tv.visibility = View.GONE
v = tv
} else { // Pass convertView as null to prevent reuse of special case views
v = super.getDropDownView(position, null, parent)
}
// Hide scroll bar because it appears sometimes unnecessarily, this does not prevent scrolling
parent.isVerticalScrollBarEnabled = false
return v!!
}
}
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
spinner.adapter = dataAdapter
}
I want it stay the same like it is now:
After user selects one item from spinner I will render specific filter choices.
If you want to programmatically set spinner selected item use the following: spinnerObject.setSelection(INDEX_OF_ITEM)

android - how to update mutablieLiveData from another class

I've a mutableLiveData of list of items in my fragment and I have a custom dialog that I pass a single item from this list to it . this is my code:
adapter.itemPosPriceListener.observe(this, Observer { pos ->
activity?.let { act ->
val dialog = DialogRoomPrices(act)
dialog.item.value = it.get(pos)
}
})
this is my dialog :
class DialogRoomPrices(act: Activity) {
private var dialog: Dialog
private var act: Activity
val item = MutableLiveData<RoomItem>()
init {
dialog = Dialog(act, R.style.DialogAnimation)
dialog.setContentView(R.layout.dialog_room_prices)
this.act = act
makeDialog()
val lp = WindowManager.LayoutParams()
lp.copyFrom(dialog.window?.attributes)
lp.width = WindowManager.LayoutParams.MATCH_PARENT
lp.height = WindowManager.LayoutParams.WRAP_CONTENT
dialog.getWindow()?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE)
dialog.show()
dialog.window?.attributes = lp
}
private fun makeDialog() {
item?.value?.let { row ->
dialog.et_roomp_price_paye.setText(row.price_paye)
dialog.et_roomp_price_akhathafte.setText(row.price_akhathafte)
////and 10 more rows of these
}
dialog.bt_next.setOnClickListener {
/////need to update the item and observe it in my fragment
dialog.dismiss()
}
}
as you can see ,dialog has a form and after filling the data and clicking on submit button , I need to update my item in fragment class .
the question is , how can I update the this item and notify my fragment's item about it ?
I don't see the whole code, but such communication can be done simply with a callback.
Solution will look like
class DialogRoomPrices(act: Activity) {
interface Listener() {
fun onNext(data: SomeData)
}
private var listener: Listener?
private var dialog: Dialog
private var act: Activity
val item = MutableLiveData<RoomItem>()
...
dialog.bt_next.setOnClickListener {
val dataToBeSetToHostingFragment = getData()
listener?.onNext(dataToBeSetToHostingFragment)
dialog.dismiss()
}
In the Fragment
class HostingFragment(): Listener {
adapter.itemPosPriceListener.observe(this, Observer { pos ->
activity?.let { act ->
val dialog = DialogRoomPrices(act)
dialog.item.value = it.get(pos)
dialog.listener = object : DialogRoomPrices.Listener {
override onNext(data: SomeData) {
// Assign data to your liveData, force update recycler view or do any other action you want to
}
}
}
})

Android recycler view position occurs index error

I tried to control recycler view item visibility when i click button but it does not work
I'm using databinding in xml
this is error message
java.lang.IndexOutOfBoundsException: Index: 5, Size: 4
In my code, recycler view item has a constraintLayout and button
And constraintLayout has recycler view
I want to show constraintLayout of item that has clicked button and hide other item's constraintLayout
The way that i tried to resolve this problem is to use previous position
When button is clicked, hide previous position's item and show current position's item
the code below is what i tried
this is clickListener in activity code
answerAdapter.onItemClickListener = object : QnaDetailAdapter.OnItemClickListener {
override fun onClick(
view: View,
position: Int,
holder: QnaDetailAdapter.AnswerHolder
) {
if (prePosition != -1)
binding.recyclerViewAnswer[prePosition].comment_holder.visibility = View.GONE
if (binding.recyclerViewAnswer[position].comment_holder.visibility == View.GONE) {
binding.recyclerViewAnswer[position].comment_holder.visibility = View.VISIBLE
prePosition = position
} else {
binding.recyclerViewAnswer[position-1].comment_holder.visibility = View.GONE
prePosition = -1
}
}
}
And this is adapter's onBindViewHodler
override fun onBindViewHolder(holder: AnswerHolder, position: Int) {
if (onItemClickListener != null) {
holder.btnComment.setOnClickListener { v ->
onItemClickListener?.onClick(v, position, holder)
}
}
holder.layout.recycler_view_comment.layoutManager = LinearLayoutManager(context)
holder.layout.recycler_view_comment.setHasFixedSize(true)
holder.layout.recycler_view_comment.adapter = adapter
val item = answerList[position]
holder.bind(item)
}
And this is AnswerHodler class
class AnswerHolder(private val binding: QnaDetailItemBinding) :
RecyclerView.ViewHolder(binding.root) {
val btnComment: Button = binding.btnComment
val layout: ConstraintLayout = binding.commentHolder
fun bind(item: Answer) {
binding.item = item
}
}
binding.comment is constraintLayout i touched on
thank for your help
Rather thaan usingposition, use holder.getAdapterPosition()

How to fix Android Spinner selection if it is not working?

Android Spinner is not working, the API is working and the Spinner's list of items is working. However, the item selection is not working.
class PlayerSignup2Activity : AppCompatActivity() {
private lateinit var positions : List<Position>
val positionSpinner = positionsSpinner
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(com.example.app.R.layout.activity_user_signup2)
//Positions from API
positions = APIService.getPositions(this)
val spinnerAdapter = ArrayAdapter(this, R.layout.spinner_item, positions)
spinnerAdapter.setDropDownViewResource(R.layout.spinner_item)
positionSpinner.adapter = spinnerAdapter
}
Spinner list
After selecting any item
Any idea on how to fix this?!
Try with this
<Spinner
android:id="#+id/spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
In Kotlin
class MainActivity : /** Other Classes, */AdapterView.OnItemSelectedListener {
var list_of_items = arrayOf("Item 1", "Item 2", "Item 3")
override fun onCreate(savedInstanceState: Bundle?) {
spinner!!.setOnItemSelectedListener(this)
// Create an ArrayAdapter using a simple spinner layout and languages array
val aa = ArrayAdapter(this, android.R.layout.simple_spinner_item, list_of_items)
// Set layout to use when the list of choices appear
aa.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
// Set Adapter to Spinner
spinner!!.setAdapter(aa)
}
override fun onItemSelected(arg0: AdapterView<*>, arg1: View, position: Int, id:Long{
// use position to know the selected item
//here you will get the answwer
}
override fun onNothingSelected(arg0: AdapterView<*>) {
}
}
try using prompt for adding title in .XML file
<Spinner
android:id="#+id/spinner"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:prompt="#string/spinner_title"/>
or try adding 1 more item that contains whatever title you want like "select position" on index 0.
positions.add("select position");
positions.add("value 1");
after adding values to list set spinner value to index 0 by default using below code.
mSpinner.setSelection(0) .
and on Item Selected check if index 0 or value is "select position" then ignore selection else perform action you want.
private lateinit var positions : List<Position>
//add dummy data first
positions.add(Position("select position"));
//Positions from API
positions.addAll(APIService.getPositions(this));

Categories

Resources