I need to change the Adapter of my Spinner exactly at the moment when I click on it.
I'm trying to display a Spinner with The value "Make Your choice" and then when the user click, another adapter is loaded on the Spinner and he can make his choice (without displaying the "Make Your choice").
Here is my code
ArayAdapter adapterclasse = new ArrayAdapter(this,android.R.layout.simple_spinner_item, affp.classes);
ArrayAdapter adaptermodule = new ArrayAdapter(this,android.R.layout.simple_spinner_item, affp.matiers);
spinner.setAdapter(adapterclasse);
spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
spinner.setAdapter(adaptermodule);
}
#Override
public void onNothingSelected(AdapterView<?> parentView) {
// your code here
}
});
but it's not working. When the app is launched, I got the second adapter loaded instead of the first.
Please help and thanks.
The second adapter is set because when the spinner is loaded the method onItemSelected is called, that's normal (the first element is selected).
Anyway, in general I don't think you need 2 adapters, you can just put "Make Your choise" on top and onItemSelected if the user has selected that, you can stop him and ask to select a real value.
Actually, it's possible to load a new adapter when the user touch the view (spinner)
spinner.setOnTouchListener(new OnTouchListener()
{
#Override
public boolean onTouch(View v, MotionEvent event)
{
spinner.setAdapter(adapterclasse2);
return false;
}
});
Related
I have a weird problem when using spinner widget inside a recyclerview. So the story is like this I have a recyclerview which has the spinner and I am passing list which needs to be inflated from fragment to the recyclereview where I am creating adapter if the data is not null and setting it into the spinner, but it works sometimes and most of the times not. It also works when getting focus or typing in edit text below it.
Note: I have already checked the other questions related this and yes I am using a white background with black text color layout which is basically a custom layout for the spinner. I am having a hard time figuring out what is going on.
This is my code for setting spinner in onBindViewHolder()
#Override
public void onBindViewHolder(FamilyMemberAdapter.ViewHolder holder, int position) {
FamilyMemberRecyclerViewModel familyMemberModel = familyMemberRecyclerViewModelList.get(holder.getAdapterPosition());
if (familyMemberModel.getRelationTypeModelList()!=null){
relationTypeModelArrayAdapter = new ArrayAdapter<RelationTypeModel>(context,R.layout.item_spinner,familyMemberModel.getRelationTypeModelList());
holder.spnRelationType.setAdapter(relationTypeModelArrayAdapter);
if (familyMemberModel.getRelationTypeAdapterModel()!=null){
int positionRelation = relationTypeModelArrayAdapter.getPosition(familyMemberModel.getRelationTypeAdapterModel());
holder.spnRelationType.setSelection(positionRelation);
}
}
}
spinner onItemSelectedListener()
spnRelationType.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
//here differentiate between different doc and relation
uploadDocumentItemsClickListener.onSpinnerChangeListener(spnRelationType,getAdapterPosition(),adapterView.getSelectedItemPosition());
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
Here is snapshot of what is going on.
This is I am selecting item from the spinner
This is after selecting an item from the spinner.
Please let me know if more code needed.
I believe this is because the edit text still has the focus and not on the spinner. Try something like this.
spinner.setFocusableInTouchMode(true);
spinner.setOnFocusChangeListener((v, hasFocus) -> {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
if (spinner.getWindowToken() != null) {
spinner.performClick();
}
}
}
});
My codes goes like this.
spinner.setAdapter(mAdapter);
spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
chosenPosition = position;
spinner.setEnabled(false);
}
My intention is to save the position chosen by user and store it and immediately disable the spinner. But, when I set the Adapter, the first item automatically gets selected and the spinner gets disabled. How do I prevent it from calling the onItemSelected method when the Adapter is set?
Thank You.
Define a flag on top such as :
boolean isFirstSelection = true;
and in your onItemSelected method:
spinner.setEnabled(isFirstSelection);
if(isFirstSelection) {
isFirstSelection = !isFirstSelection;
}
In my application there are lot's of views(spinner, buttons, editText, textView, ImageButton etc).
After selecting one value in the spinner it not reflect the value which I selected. The old value is till there on the spinner. But when I tap on other views like editTest then spinner value automatically updated.
I think no need to mention the code because normal spinner is there which populating data from ArrayAdapter and I am doing small task after selecting value.
CODE:-
spinnerWard = (Spinner) findViewById(R.id.spinnerWard);
aAdapterWard = new ArrayAdapter<WardList>(this,
android.R.layout.simple_spinner_item, listWard);
aAdapterWard.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinnerWard.setAdapter(aAdapterWard);
spinnerWard.setOnItemSelectedListener(new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View v,
int pos, long id) {
intWardPosition = pos;
intFinalWardId = listWard.get(pos).getId();
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {}
});
Spinner OnclickListener event executes twice -
Spinner initialization
User selected manually
where as implementation of listener is as :
spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
}
public void onNothingSelected(AdapterView<?> parent) {
}
});
Problem definition
I want to save user selected text into data storage, when user choose any item from spinner, and I am able to do this. But my another task is that to show previously selected item (access from data storage) as selected item in spinner, but each time when I call spinner's activity, spinner shows first item as default selected item, and also in data storage it make change previous item to default.
How can I make difference between 'Spinner initialization' and 'User selected manually' events?
You have to handle both events logically. As these references (Android Spinner selection, problem on spinner) says that you have to use flag variable to handle this, I am putting a code sample.
Hope this will help you to clear your logic.
public class TestActivity extends Activity {
//Checks report spinner selection is default or user selected item
private boolean isDefaultSelection;
//Spinner setup
Spinner spinner;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.your_layout);
// Set true at onCreate
isDefaultSelection = true;
spinner = (Spinner) findViewById(R.id.id_of_spinner);
ArrayAdapter<String> spinnerAdapter = new ArrayAdapter<String> (this, R.layout.drop_down_custom_row, data);
//Implement custom view for drop down of spinner
//spinnerAdapter.setDropDownViewResource( android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(spinnerAdapter);
spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
if(isDefaultSelection) { //If spinner initializes
spinner.setSelection("Set_here_id_of_data_item_from_storage_which_was_previously_stored");
isDefaultSelection = false;
} else { //If user manually select item
int itemPosition = spinner.getSelectedItemPosition();
//Write here code to store selection (itemPosition) of user into data storage
}
}
public void onNothingSelected(AdapterView<?> parent) {
//User selected same item. Nothing to do.
}
});
}
}
Hope it will clear your doubt.
You can call the setSelection at the same time that the items are added to the adapter, see this example: How to avoid onItemSelected to be called twice in Spinners
It appears that android's Spinner class (and possibly ListView in general, although I don't know for sure) calls your OnItemSelectedListener's onItemSelected() method after you call setAdapter(), even if the user hasn't explicitly selected anything yet.
I can see how this would be useful in many situations, but there are times when I only want onItemSelected() to be called when an item is actually specifically selected.
Is there a way to control this behaviour and have Spinner NOT call onItemSelected() after setting the adapter?
I haven't used this solution for very long yet so I'm not totally confident that it works as expected, but I've had luck so far with this workaround:
spinner.setOnItemSelectedListener( new OnItemSelectedListener() {
protected Adapter initializedAdapter = null;
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
// Always ignore the initial selection performed after setAdapter
if( initializedAdapter !=parent.getAdapter() ) {
initializedAdapter = parent.getAdapter();
return;
}
...
}
}
Is there a better way?
Add listener to spinner like below:
spinner.post(new Runnable(){
public void run()
{
spinner.setOnItemSelectedListener( new OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
...
}
}
}
});
I've used the setTag and getTag methods, and created a resource id called "spinnerstate".
Then whenever I programmatically set the adapter, I set the "spinnerstate" tag to "init", and in the fired event, set it to "ready" and ignore the event. (note my code is Mono for Android se it will look different):
Set Adapter:
profileSpn.SetTag (Resource.Id.spinnerstate, "init");
profileSpn.Adapter = new ArrayAdapter (this, Android.Resource.Layout.SimpleSpinnerItem, items.ToArray ());
Item Selected event:
string state = (string)((Spinner)sender).GetTag (Resource.Id.spinnerstate);
if (state == "init") {
((Spinner)sender).SetTag (Resource.Id.spinnerstate, "ready");
return;
}
I agree that this is not desired behaviour in almost 100% of cases, and I don't think it's good design on the part of Google, but there you go.
I did similar things before, I used count value. Using parent adapter object is incomplete because it can be a problem when view is refreshed or getView() called again.
Therefore, I recommend that using array of counter.
At first, define array of count in adapter globally.
private int isInitializedView[];
And then initialize it on getView().
isInitializedView[position] = 0;
In the selection listener, do something that you want if it already initialized.
holder.mySpinner.setOnItemSelectedListener(new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
isInitializedView[position]++;
if(isInitializedView[position] > 1) {
// do someting that you want
}
}
#Override
public void onNothingSelected(AdapterView<?> parentView) {}
});
(Note that isInitializedView[position]++; can be come after if() routine, and only trigger event when this value is >0 . It's your choice.)
I had three spinner in my activity and all spinner adapter data has been filled at runtime(from web-service data after call from onCreate method). So it automatically call onItemSelected(AdapterView<?> parent, View view, int position, long id) method of spinner.
I solved this issue by using onUserInteraction() method of activity
check this method that user is interacting with spinner or not. if yes then perform the action else not
Declare isUserIntract boolean variable globally
in onItemSelected method use following procedure
If(isUserIntract)
{
//perform Action
}
else{
//not perform action
}
use below code in activity
#Override
public void onUserInteraction() {
super.onUserInteraction();
isUserIntract = true;
}