Reputation: 8509
I have been struggling with this for days now, I have a list of items I am loading from my server. When the items are loaded I display the list and I set the selected item for each spinner. Now these are my problems.
Case 1: The onItemSelectedListener for each item in my adapter gets triggered on page load.
So I did some research online and decided to use a variable to check the state. When the view is created I set firstTime to true in the on click listener like this:
viewHolder.spStatus.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
if (!firstTime) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle("Confirm");
builder.setMessage("Are you sure you want to change this?");
builder.setPositiveButton("YES", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
int selectedPosition = Integer.parseInt(viewHolder.id.getTag().toString());
String selectedId = viewHolder.id.getText().toString();
updateStatus(selectedPosition, selectedId,
((ArrayAdapter<String>) viewHolder.spStatus.getAdapter())
.getItem(selectedPosition));
}
});
builder.setNegativeButton("NO", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// Do nothing
dialog.dismiss();
}
});
AlertDialog alert = builder.create();
alert.show();
}
firstTime = false;
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
// Do Nothing
}
});
Now this is what happens when I do this it's either when I scroll the onItemSelected change listener fires depending on where I put firstTime=false
or when I filter the list I have to tap twice before the event is triggered.
Upvotes: 2
Views: 1983
Reputation: 63
You can do it like this,
public void setSelection(int position, boolean animate, boolean noTrigger, OnItemSelectedListener onItemSelectedListener) {
if(noTrigger) {
Log.e("SET_SELECTION", "No trigger at position " + position);
this.setOnItemSelectedListener(null);
}
super.setSelection(position, animate);
this.post(new Runnable() {
@Override
public void run() {
setOnItemSelectedListener(onItemSelectedListener);
}
});
}
Upvotes: 1
Reputation: 418
Solution for RecyclerView Adapter in Kotlin
class DataAdapter(myData: ArrayList<MyData>) : RecyclerView.Adapter<DataAdapter.DataHolder>(){
override fun onViewRecycled(holder: DataHolder){
holder.mSpinner.onItemSelectedListener = null //remove listener when item is out of view
super.onViewRecycled(holder)
}
class DataHolder(itemView: View, private val context: Context) : RecyclerView.ViewHolder(itemView) {
val mSpinner: Spinner = itemView.findViewById(R.id.spinner)
fun bind(data: MyData){
var pass = false // variable to check first run
val adapter = SpinnerAdapter(context)
mSpinner.adapter = adapter
val onSelectListener = object : AdapterView.OnItemSelectedListener{
override fun onNothingSelected(p0: AdapterView<*>?) {
}
override fun onItemSelected(p0: AdapterView<*>?, p1: View?, p2: Int, p3: Long) {
if (pass){
// actions onSelected
}
pass = true
}
}
mSpinner.setSelection(3) //the onItemSelected will be triggered when the item is first created
mSpinner.onItemSelectedListener = onSelectListener
}
}
}
Upvotes: 0
Reputation: 13009
If I understand correctly, you have a ViewHolder
with an itemView
which contains a Spinner
. You want to be able to set the selected position of the Spinner
programmatically without triggering the OnItemSelectedListener
of the Spinner
.
Right now you are using an anonymous OnItemSelectedListener
. If you make this listener a field of the ViewHolder
class
private OnItemSelectedListener listener = new AdapterView.OnItemSelectedListener(){
// listener code goes here
// ...
};
... then you can "unset" the listener before setting the selected position programmatically and "reset" it afterwards like the following method shows:
private void setPosition(int position){
if(listener != null){
spinner.setOnItemClickListener(null);
}
spinner.setSelection(position);
spinner.setOnItemClickListener(listener);
}
Upvotes: 0