views:

122

answers:

1

Im trying to get an onClickListener to fire on a Spinner, but i get the following error: Java.lang.RuntimeException is "Don't call setOnClickListener for an AdapterView. You probably want setOnItemClickListener instead," the thing is, im sure I want to call onClickListener and NOT onItemClickListener. I found this question asked by someone else on stackOverflow, the question is here: link text

The answer stated there is:

You will have to set the Click listener on the underlying view (normally a TextView with id: android.R.id.text1) of the spinner. To do so:

Create a custom Spinner In the constructor (with attributes) create the spinner by supplying the layout android.R.layout.simple_spinner_item Do a findViewById(android.R.id.text1) to get the TextView Now set the onClickListener to the TextView

I have tried the answer noted there, but it doesnt seem to work, I get a null pointer to the TextView after I do the findViewById().

This is what im doing:

Spinner spinner = (Spinner) findViewById(R.id.spinner);    
    ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,R.layout.layoutspinner,dataArray);

    spinner.setAdapter(adapter);

    TextView SpinnerText = (TextView)findViewById(R.id.spinnerText);
    if(SpinnerText==null){
        System.out.println("Not found");
    }else{
        SpinnerText.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View arg0) {
                //Do something
            }           
        });
    }

layoutspinner.xml

<?xml version="1.0" encoding="utf-8"?>
<TextView 
xmlns:android="http://schemas.android.com/apk/res/android"
              android:id="@+id/spinnerText"
              android:singleLine ="true"
              android:layout_width="fill_parent"
              android:layout_height="wrap_content"
              android:textSize="6pt"
              android:gravity="right"/>

Any idea what am I doing wrong? I'm new to stack overflow, I didnt find any way to post an aditional question to the other thread (or comment since I have to little rep) so I started a new question.

Edit:

Per recomendation I tried this:

int a = spinnerMes.getCount();
        int b = spinnerMes.getChildCount();
        System.out.println("Count ="+a);
        System.out.println("ChildCount ="+b);
        for (int i = 0; i < b; i++) {
            View v = spinnerMes.getChildAt(i);
            if(v==null){
                System.out.println("View not found");
            }else{
                v.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        //Click code
                    }
                });
            }
        }

But logCat isnt showing promising results.

10-14 16:09:08.127: INFO/System.out(3116): Count =7
10-14 16:09:08.127: INFO/System.out(3116): ChildCount =0

I have tested this on API levels 7 and 8 with same results.

+1  A: 

this works how you want but is not ideal

public class Tester extends Activity {

String[] vals = { "here", "are", "some", "values" };
Spinner spinner;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    spinner = (Spinner) findViewById(R.id.spin);
    ArrayAdapter<String> ad = new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line, vals);
    spinner.setAdapter(ad);
    Log.i("", "" + spinner.getChildCount());
    Timer t = new Timer();
    t.schedule(new TimerTask() {

        @Override
        public void run() {
            int a = spinner.getCount();
            int b = spinner.getChildCount();
            System.out.println("Count =" + a);
            System.out.println("ChildCount =" + b);
            for (int i = 0; i < b; i++) {
                View v = spinner.getChildAt(i);
                if (v == null) {
                    System.out.println("View not found");
                } else {
                    v.setOnClickListener(new View.OnClickListener() {

                        @Override
                        public void onClick(View v) {
                                    Log.i("","click");
                                    }
                    });
                }
            }
        }
    }, 500);
}

}

let me know exactly how you need the spinner to behave and we can work out a better solution

Dave.B
I belive I tried this today with no success, but I'll report back once I try again just to be sure.
blindstuff
I just checked the code, I tried that and im still getting a null reference in return. Any ideas?
blindstuff
try code in the edit.
Dave.B
Edited my question, not quite there yet, but thanx for helping out, im really lost here.
blindstuff
the problem with the code i posted is that the spinner doesn't actual get any items until the screen renders which is after onCreate is executed. if you move the loop into a timer which fires after the view is rendered it works. however the problem is that the spinner only ever has 1 child. when you select the spinner a dialog os spawned so that you can select a value. when the value is changed a new child is created and the event you added wil be lost. If you could tell me specifically how you need the apinner to behave we may be able to come up with a more elegant solution.
Dave.B
That does work, but the problem you are describing is a deal breaker. Let me go back to the problem that brought me to needing this. I have a screen with 2 spinners, as I'm pretty sure you are aware off, spinners fire off the onItemSelected when created. Both onItemSelected on this activity start network request, so my solution was to use a simple boolean flag, lets call it spinnerClicked. The onItemClickedListener looks if the spinnerClicked is true, and does the data fetch, otherwise it just ignores it.
blindstuff
The idea was to set the onClick for the spinner to set the flag to true, and after the onItemSelected fired, set it to false. This solves not firing 2 worker threads, and also keeps from re-downloading the data on screen rotation.So basically I just wanted to, onClick, set a flag to true.
blindstuff
why not just initialize the boolean to true and then set it to false after the first click?
Dave.B
I want it to load the data when ever a new options is selected from either spinner, but keep it from firing upon rotation. A "obtain data" button would solve this but its really a last resort thing.
blindstuff
create a dictionary of booleans in oncreate with a value for each item in the spinner. in the onitemSelect listener get the value of the selected item and then check the dictionary to see if the download has been completed
Dave.B
I did something similar to a dictionary, and while the solution is far from elegant it works, thaks for the help Dave. I would up this, but im still a couple of points away from being able.
blindstuff