I asked a question here and got the answer
OK, all I needed was to add package name in xml file, so this spinner works now, but another problem has appeared.
To select the element, that was selected during the initialise, I have to click on it twice. I guess, it is because I use a counter to check if the item selected by user:
variables.spinner1.setOnItemSelectedListener(new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view,
int position, long id) {
CharSequence t2 = (CharSequence) parent.getItemAtPosition(position);
variables.wall=t2.toString();
if(i>0){
new DownloadRow().execute();
}
if(i==0) i++;
}
#Override
public void onNothingSelected(AdapterView<?> arg0)
// TODO Auto-generated method stub
}
});
What have I do to make it so that user will need to click on a selected item only once?
just a hint (i.e. you don't want any processing at all), no, this is an amiss variant. Situation is, when user clicks element at position 0 (or on any other position) new DownloadRow().execute() have to start. But now (I don't know why) if user clicks element at zero position, nothing happens. If he clicks it again DownloadRow().execute() starts, as it had to be done after the first user click. It looks like if during initialise of this spinner increament of var i doesn't happen (or some other problem). But if I do increament again if position==0. then DownloadRow().execute() starts automatically, user doesn't select an iem himself.
I'm not sure if I fully understand what you're trying to do here, but I think that if you change your if statement to be:
if(position>0){
new DownloadRow().execute();
}
You should get the behaviour that you want, as this starts DownloadRow when an item other than the default value is selected.
If you need the default value selectable by the user, then I would suggest instead having the default value (at position 0) one which is just a hint (i.e. you don't want any processing at all), and every other position to be an option which you would like to call DownloadRow().execute
Found the solution.
if(i==0) {
if(position==0) variables.spinner1.setSelection(0);
i++;
}
Related
I have a ListView that contains items with checkboxes that should behave sometimes like a CHOICE_MODE_MULTIPLE and sometimes like a CHOICE_MODE_SINGLE. What I mean is for certain items in the list, when selected certain other items needs to be deselected whilst other can remain selected.
So when item A is checked I can find in my data the item B that needs to be unchecked but how do I get the UI to refresh to show this as I (I believe) cannot find the actual View that represents B but just it's data?
It sounds like you're off to a good start. You're right that you should be manipulating the underlying data source for item B when A is clicked.
Two tips that may help you:
Your getView() method in the Adapter should be looking at your data source and changing convertView based on what it finds. You cannot find the actual View that represents B because in a ListView, the Views are recycled and get reused as different data needs to be displayed. Basically, when an item is scrolled off the list, the View that was used gets passed to the getView() function as convertView, ready to handle the next element's data. For this reason, you should probably never directly change a View in a ListView based on user input, but rather the underlying data.
You can call notifyDataSetChanged() from within your adapter to signal that somewhere the underlying data has been changed and getView() should be called again for the elements currently displayed in your list.
If you're still having trouble, feel free to post some code that illustrates the specific problem that you're having. It's much easier to provide concrete advice when the problem is better defined. Hope this helps!
you can use singleChoice alartDialog, i have used like:
private int i = 0; // this is global
private final CharSequence[] items = {"Breakfast", "Lunch", "Dinner"}; // this is global
Button settings = (Button)view.findViewById(R.id.settings);
settings.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(final View v) {
AlertDialog.Builder builder = new AlertDialog.Builder(v.getContext());
//Title of Popup
builder.setTitle("Settings");
builder.setSingleChoiceItems(items, i,
new DialogInterface.OnClickListener() {
// When you click the radio button
public void onClick(DialogInterface dialog, int item){
i=item;
}
});
builder.setPositiveButton("Confirm",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
if (i == 0) {
//it means 1st item is checked, so do your code
}
if (i == 1) {
//it means 2nd item is checked, so do your code
} /// for more item do if statement
}
});
//When you click Cancel, Leaves PopUp.
builder.setNegativeButton("Cancel", null);
builder.create().show();
}
});
i have initialized i=0, so that for the very first time when user click on settings button, the first item is selected. and after then when user select other item, i have saved the i value so that next time when user click settings button, i can show user his/her previously selected item is selected.
I come across and solve this question today.
public class ItemChooceActivity extends Activity implements OnItemClickListener {
private int chosenOne = -1;
class Madapter extends BaseAdapter {
.....
.....
#Override
public View getView(final int position, View convertView,
ViewGroup parent) {
// TODO Auto-generated method stub
if (chosenOne != position) {
set the view in A style
} else {
set the view in B style
}
return convertView;
}
}
#Override
public void onItemClick(AdapterView<?> arg0, View view, int position,
long arg3) {
,,,,
chosenOne = position;
adapter.notifyDataSetChanged();
,,,
}
}
I have an intent launched activity with a number of spinners on the page. I've just set up my spinner's ItemSelected listeners, following this guide. The problem is, the first item in each Spinner is basically "Please select", just so it's not a blank box: so my ItemSelected Listener detects the fact that Please select is in the spinner and seems to assume that it was selected rather than loaded by default. Ideally I want the listener to only detect when an actual choice is made. What is the best way to ignore the default selection?
Here's the relevant code:
ageSpinner = (Spinner) findViewById(R.id.ageSpinner);
ageAdapter = ArrayAdapter.createFromResource
(this, R.array.ageArray, android.R.layout.simple_spinner_item);
ageAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
ageSpinner.setAdapter(ageAdapter);
ageSpinner.setOnItemSelectedListener(new MyOnItemSelectedListener());
public class MyOnItemSelectedListener implements OnItemSelectedListener {
public void onItemSelected(AdapterView<?> parent,
View view, int pos, long id) {
Toast.makeText(parent.getContext(), "The planet is " +
parent.getItemAtPosition(pos).toString(), Toast.LENGTH_LONG).show();
}
public void onNothingSelected(AdapterView parent) {
// Do nothing.
}
}
The problem is that the selection is done on the first layout phase. So the first time your layout is computed, the Spinner raises onItemSelected. Its quite annoying, but its the way it works. You could try a couple different things, but given you already have Please Select Something items, the best you could do is ignore the event when the selected item is 0.
Set a boolean to false, check it in the onItemSelected and if false, set it to true and do nothing else. Next time, when it's true do as you normally would.
There are lots of approaches possible here. For example, you can override the normal behaviour of a Spinner using reflection, or simply switch to a Button imitating a Spinner, which on clicking on it pops up an AlertDialog.
However, other solutions can easier to implement. Barak has named one, while an alternative would be to simply check the selected position in the Spinner, assuming that "Please select" will always be the first item (and hence, at position 0) and you're not doing any sorting on the items.
I'm sure you'll find one of the possibilities suitable for your problem, but perhaps you can also a elaborate a bit more on why exactly it's problematic onItemSelected(...) gets fired for the initial selection?
Solution by OP.
public class MyOnItemSelectedListener implements OnItemSelectedListener {
public void onItemSelected(AdapterView<?> parent,
View view, int pos, long id) {
if (pos != 0) {
//this if makes sure it ignores 0, which is
//Please Select in the drop down
Toast.makeText(parent.getContext(), parent.getTag().toString() +
parent.getItemAtPosition(pos).toString(), Toast.LENGTH_LONG).show();
}
}
public void onNothingSelected(AdapterView parent) {
// Do nothing.
}
}
I am using a spinner in my application. After selecting an index in spinner I open
a new activity and then come back to the first. Now my spinner is showing the previous selected value and if I select the same index again nothing happens.
The doc says onItemSelectedListener invokes iff the index is different from the previous. And I can't set it to default(0) when i come back.
So is there any alternative solution to do this? Please help me. Thanks. Here is my code:
companyspin.setOnItemSelectedListener(new OnItemSelectedListener() {
public void onNothingSelected(AdapterView<?> arg0) {
}
public void onItemSelected(AdapterView<?> arg0,
android.view.View arg1, int arg2, long arg3) {
Object o = companyspin.getSelectedItem();
network = CheckNetworkStateReceiver.isOnline(context);
selectCompany = o.toString().trim();
Data.homeCommunityValue = arg2;
setCompanyList(arg2);
flagCatageory = false;
try {
tracker.trackEvent("Home", // Category
"Drop Down Selection", // Action
selectCompany, // Label
arg2); // Value
} catch (Exception e) {
e.printStackTrace();
}
}
});``
You start the new activity as soon as it's selected in the spinner ?
Just grab the data from the spinner you need for your activity in the onItemSele.... listener.
Set
mySpinner.setSelection(your_position)
before your new activity starts. If you want it to stay the on the same value in the spinner, a Button to activate your selection seems easier, and less error-prone for the user depending on what the selection do.
EDIT:
The selection is still the same afterwards so the callback will never fire. You can put a placebo object at position(0) with some info text "Choose here..." which you can return to after a valid selection, with setSelection. Just add a check in the listener if it's a valid choice or the placebo.
Since you want 1st item to be selected when you return to your main activity, you can try
companyspin.setSelection(0);
in onCreate() of main activity.
I've a Spinner with onItemSelected interation that works, but how the Api specification says:
This callback is invoked only when the newly selected position is
different from the previously selected position or if there was no
selected item.
I need to remove this limitation and i want that the callback is invoked also if the user select the same element.
How to do that? I read a suggestion about extending Spinner class and set the position to INVALID_POSITION, but i've not understood/able to do that.
Anyone did the same thing?
I also needed a solution to this problem. What I wanted to do was have a Spinner that has date ranges with a custom range option. The rows would look something like this:
Apr 10 - May 10
Mar 10 - Apr 10
Feb 10 - Mar 10
Custom Range
The problem is that if the user selects a custom range and then wants to change their custom range, they have to select a different range and then select the custom range option again. I wanted the user to just be able to select "Custom Range" again so that the custom range dialog could be shown again.
I sub-classed Spinner and created my own listener. The code switches the selection, but then immediately switches it so that nothing is selected. In my listener I just ignore any position that is less than zero.
The Spinner just displays the last selected item. I created my own custom adapter and specify what to display for each view, but that shouldn't be necessary. Here is how I sub-classed Spinner.
package com.example.widget;
import android.content.Context;
import android.widget.Spinner;
public class DateRangeSpinner extends Spinner {
private ItemSelectionListener listener;
public DateRangeSpinner(Context context) {
super(context);
}
/**
* This listener will be fired every time an item is selected,
* regardless of whether it has already been selected or not.
*
* #param l
*/
public void setOnItemSelectedListener(ItemSelectionListener l) {
listener = l;
}
public void removeOnItemSelectedListener() {
listener = null;
}
#Override
public void setSelection(int position) {
setSelection(position, true);
}
#Override
public void setSelection(int position, boolean animate) {
if (listener != null) {
listener.onItemSelected(position);
}
super.setSelection(position, animate);
super.setSelection(-1, animate);
}
public interface ItemSelectionListener {
public void onItemSelected(int position);
}
}
I hope this helps!
You can do this by a custom adapter, like create a layout of your desire views, then inflate this in custom adapter then on onItemClick function you can get the view by this function.
To distinguish each view you must to set the tag of each row.
It probably works in your condition.
Let me know any issue if you have
why you have select the selected item again. Just give a refresh button if you want to perform that task again.
This is the spinner Element with custom dialog mode and whitout promt:
<Spinner
android:id="#+id/spinner_metatag"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:entries="#array/search_adv"
/>
The Array element where the default value is putted at position 0:
<string-array name="search_adv">
<item>#string/search_adv_prompt</item>
<item>#string/search_adv_title</item>
<item>#string/search_adv_desc</item>
<item>#string/search_adv_autore</item>
....
</string-array>
The String elements for the array with the default value:
<string name="search_adv_prompt">Scegli un metatag</string> <!-- Default value-->
<string name="search_adv_title">Titolo</string>
<string name="search_adv_desc">Descrizione</string>
<string name="search_adv_autore">Autore</string>
...
And here the code to prevent the event fired on onCreateMethod and the work around to permit to select the same element already selected:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.search_adv_main);
spinner = (Spinner) findViewById(R.id.spinner_metatag);
spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view, int pos,long id) {
//prevent onCreate event fire and the loop
if(pos==0)
return;
//HERE YOUR CODE
//at the end move to the default element the spinner
spinner.setSelection(0);
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {}
});
}
Hope helps. The idea come from the second solution from TreKing's answer
Use OnItemClickListener instead of on itemSelectedListener.That will work for every click whether it is same or different.
I guess you must be storing the value in a variable, initialize the vairable with -1. And change the value as the user selects the item spinner, if the value is -1 ask the user to reselect or whatever u want.
#i want that the callback is invoked also if the user select the same element.
Android will do it for u as this is the default behavior of android.
I'm in a trouble managing a spinner, so may I ask for your help ?
I have a spinner with its adapter.
I initialize the spinner with a list of values when starting my activity.
Then I force the selected value to be the one used in the object that I manage.
Once the screen is initialized :
When the user selects a value in the spinner, according to the selected value, I may continue (or not) to another activity for let the user choose a complementary and necessary value.
If the user "cancels" this second activity, I want to rollback the spinner to its previous selected value, and cancel some actions made in the meantime.
If the user goes to the end of the second activity, everything is fine and I want juste to refresh the spinner display with the datas selected in the second activity (I overload the getView method in the adapter to do this).
Overall, I can easily do all of this, however, when I force the selected value in the spinner at the begining of my activity, or whene returning back from the second activity by "Cancel", the change value event is catched and the second activity is triggered (the user did not click anything at all).
How would you allow the second activity to be lauched only if the change of the selected value in the spinner is due to a manual action from the user, and prevent that same second activity to be launched when the value of spinner is changed "in the code "?
I tried many solutions, as setting a boolean into the adapter that tells if the next event will be raised because of an "in the code" action.
Or also putting a boolean in the adapter that tells if the adapter has initialised itself, and I force that boolean to true on the forst change catched event.
But nothing that really works fine.
Thank you for your help.
Oliver
I've always solved that issue with boolean flags, it isnt pretty at all, but it works if you think it through.
The idea is more or less, create a global usable boolean and init with false, in the onSelectedItemListener() use that boolean to choose wether or not to trigger the action, the important thing to remember is to set it to true after the computer has selected it the first time automatically, and reset it to false in the onResume() method.
This isnt perfect but it should work.
Edit:
bool spinnerUsable1;
bool spinnerUsable2;
int positionSpinner;
public void onCreate(Bundle savedInstanceState){
spinnerUsable1 = false;
spinnerUsable2 = true;
if(savedInstanceState != null){
positionSpinner = savedInstanceState.getInt("posSpinner");
if(positionSpinner != 0) spinnerUsable2 = false;
}
//Declare your spinner, set the on item selected lister
spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> arg0, View arg1,
int arg2, long arg3) {
boolean spinnerUsable = (spinnerUsable1 && spinnerUsable2);
if (!spinnerUsable1) {
spinnerUsable1 = true;
} else if (!spinnerUsable2) {
spinnerUsable2 = true;
}
if (spinnerUsable) {
//Action;
}
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
// Nothing
}
});
}
Something like this should work.