How to use Multiple spinners in a single layout i.e., setting set On Item Selected Listener in on create
Welcome to SO. You definitely should read the FAQ to learn what kind of questions to ask and how. If you want good answers and don't want your privileges to be revoked you need to be more specific about your questions and add relevant code and error messages showing that you have tried. But since you are new I'm going to give you this one. The easiest way to do this is attach the listener to each one in onCreate() after getting a reference to each spinner through your xml
spinner1.setOnItemSelectedListener(this);
spinner2.setOnItemSelectedListener(this;
then put the methods outside of onCreate()
#Override
public void onItemSelected(AdapterView<?> parent, View view, int arg2,
long arg3)
{
// do whatever you need here depending on what is selected
// you can use a case statement and switch on the id to get the spinner (parent) or view
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
and add Implements OnItemSelectedListener in your Activity signature. Good luck and please ask more specific questions in the future and add code showing that you have made an attempt.
Related
This might sound a bit convoluted.
I have roughly 15 Spinners in one activity and made a distinct method for each of these spinners. I then initiate the methods in the onCreate method.
Method example:
//Relative Position Spinner
public void relativePositionSpinner() {
Spinner relativePositionSpinner = (Spinner) findViewById(R.id.spinner_relativePosition);
ArrayAdapter relativePositionAdapter = ArrayAdapter.createFromResource(this, R.array.relativePosition, R.layout.spinner_item);
relativePositionSpinner.setAdapter(relativePositionAdapter);
//what happens when selected
relativePositionSpinner.setOnItemSelectedListener(this);
}
OnCreate Method:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_new_hand);
//initiate all Spinners
relativePositionSpinner();
absolutePositionSpinner();
etc.
Now what I want is to send the data of each Spinner to another Activity with the click of a Button. I know that I can do this with an intent and using putExtra in the Button method like this:
public void openHandSummary() {
//Find the Button that gives option to enter new hand
Button handInputButton = (Button) findViewById(R.id.hand_input_button);
//set a click listener on Hand Analyzer Button
handInputButton.setOnClickListener(new View.OnClickListener() {
//below code will be executed when the new Hand Button is clicked
#Override
public void onClick(View view) {
Intent handSummaryIntent = new Intent(NewHandActivity.this, HandSummaryActivity.class);
handSummaryIntent.putExtra("RelPosString", WHATTOENTERHERE??)
startActivity(handSummaryIntent);
}
});
}
However I do not know how to retrieve the value/variable out of my Spinners to put them into the Button/intent method? Because if I make a String in the Spinner method, then I can't access this in the Button method.
So I feel like I have too many methods? So is there a way to pass data from one method to another method, or do I have to cancel some methods? What would be the easiest way to set this up?
I also made an onItemSelected to make some toasts, which worked. Can I use OnItemSelected somehow to create variables or initiate a data transfer to another Activity?
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
TextView myText = (TextView) view;
switch (parent.getId()) {
case R.id.spinner_relativePosition:
makeText(NewHandActivity.this, "Relative Position is " + myText.getText(), Toast.LENGTH_SHORT).show();
break;
case R.id.spinner_absolutePosition:
makeText(NewHandActivity.this, "Absolute Position is " + myText.getText(), Toast.LENGTH_SHORT).show();
break;
I'm very new to coding, and I just can't figure out the logic how I get the Spinner methods, Button/iniate method and OnItemSelected method to work together and exchange variables. Would appreciate if someone can point me in the right direction. Have already browsed the internet a day or so to find an answer, with no success.
I like your idea of separating out the code to create each spinner into its own method. However, if you are copying and pasting the whole method and making a few changes, you should step back and think about how you can do it even more easily. Often the changes you make after copy and paste give a hint that you should add some parameters to the method. If you do it correctly, you can write just a single method and then copy and paste the method call instead of the entire method and then make appropriate changes to the arguments.
As for your actual question, you are making this much more complicated than necessary. Specifically, you do not need to setOnItemSelectedListener() on any of the Spinners. Instead, the OnClickListener for the button should just get the selected item from each spinner and send it to the new activity in the Intent.
Let me explain myself:
As you know, when you've a view which have to be inflated several times, but changing values, you use a GridView or a ListView. Those two Composite views, have some methods like onItemClick. This method is so useful, as it returns the position of the view clicked.
With this position you can perform some concrete tasks, like retreiving from an ArrayList, the information of that object. Here's an example:
ArrayList<DocumentInfo> documents;
And when you set a setOnItemClickListener() you can get the correct values:
gallery.setOnItemClickListener(new OnItemClickListener(){
#Override
public void onItemClick(AdapterView<?> arg0, View v, int pos, long arg3) {
getDocumentInfoOf(pos);
}
});
public void getDocumentInfoOf(int position){
DocumentInfo doc = documents.get(position);
}
However, when you aren't using a GridView or a ListView, you're in your own. You don't have a clear way (AFAIK) to know which layout inflated is the one clicked (I mean like the previous example, the "position" value).
What I am currently doing, is the following:
for (int i=0; i<10;i++){
RelativeLayout documentInflated = (RelativeLayout) this.mInflater.inflate(R.layout.open_document_per_inflar, null);
documentInflated.setContentDescription(""+i);
documentInflated.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
openDocument(v);
}
});
container.addView(documentInflated);
}
public void openDocument(View v){
int idDocument = Integer.parseInt(v.getContentDescription());
//idDocument is the view clicked
}
Do you guys think this is a clear way of doing this?
Thank you!!!
If I'm not mistaken you want to get some data from your created Relative Layout when you click on it. The best solution here is to use the method setTag(Object tag). After that you get the informatiom with the method getTag(). This method allows you to add extra information to your view. As it says in the documentation:
Tags
Unlike IDs, tags are not used to identify views. Tags are essentially an extra piece of information that can be associated with a view. They are most often used as a convenience to store data related to views in the views themselves rather than by putting them in a separate structure.
Also depending on your needs you can seperate every tag with a key -> value pair with the method setTag(int key, Object tag), after that you can retrieve this object with getTag(int key);
So in your case you will have
documentInflated.setTag(i)
in the onClick yo will then have:
int i = (int)v.getTag();
Unless I'm not understanding your desire...
#Override
public void onClick(View v) {
openDocument(v);
}
v IS the view being clicked. Your code looks like it should do what you're hoping it will do. What are you actually seeing happen?
I wanted to know which is a best method for getting user input and then filtering that input. The only option i can think of is spinners. Basically I did is use spinners. In my case, I have one spinner with all states, and the second spinner with list of all colleges in those states. I filter the colleges accordingly to user selection for the state in the 1st spinner. I used spinners here, is their another way to do this. Thanks in advance, sorry If i was not clear.
You are going in right direction. I am also doing same kind of project using two spinner.select the 1st spinner and based on the Item selected add items to 2nd spinner in
spinner1.setOnItemSelectedListener(new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> arg0, View arg1,
int arg2, long arg3) {
// TODO Auto-generated method stub
//add items to array/arraylist of 2nd spinner
}
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++;
}
I use setOnItemSelectedListener on a spinner.
The listener is triggered if I change the selection but not if I select the same item that is already selected.
I need to be nofified even if the user select the same item that is already selected.
I tought about using setOnItemClickListener but it is not supported by the Spinner.
Any hints ?
TIA
If you're still looking for a solution to this question, Regis, it may be worth having a look at a related question I asked a while ago, which has several answers with good ideas on how to work around this issue.
Did you tried to override onNothingSelected()? in onNS() you implement to do/get/whatever item that is selected by "default". I hope you get my idea.
spin.setOnItemSelectedListener(new OnItemSelectedListener(){
#Override
public void onItemSelected(AdapterView<?> arg0, View arg1,int arg2, long arg3) {
// Some operation with other selection
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
//operation with that item that onItemSelected() did not triggered. I mean, let's say you have 3 items on the spinner: A,B,C. Initially what we see its the A item and on this item this method will apply.
}});