1

I am retrieving data from a database into an ArrayList, which is then used to populate a Spinner.
This all works fine, I can see the items in the dropdown.

However, it does not show the selected item, even though I have used mySpinner.setSelected(INDEX).
It does not even run the code in the setOnItemSelectedListener I created.

I realize there are many similar questions already, but even crawling through those answers I've been unable to solve the problem.

My code is given below.

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    // Inflate the layout for this fragment
    View v = inflater.inflate(R.layout.fragment_add_man_data, container, false);

    // Create the variables
    final FirebaseDatabase database = FirebaseDatabase.getInstance();
    final DatabaseReference ref = database.getReference();
    final ArrayList<String> statesForSpinner = new ArrayList<>();
    final TextView txtView = v.findViewById(R.id.add_man_data_txtview_1);

    // Retrieve the database data (This bit works fine)
    ref.child("stateDescriptions").addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            int length = (int)dataSnapshot.getChildrenCount();

            for(int i = 0;i<length;i++) {
                statesForSpinner.add(dataSnapshot.child(Integer.toString(i)).getValue(String.class));
            }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });

    // Create the spinner (This also works)
    final Spinner stateSpinner = v.findViewById(R.id.state_spinner);
    ArrayAdapter<String> adapter = new ArrayAdapter<>(getContext(), R.layout.spinner_item, statesForSpinner);
    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    stateSpinner.setAdapter(adapter);

    // But this does not work... Why?
    stateSpinner.setSelection(1);

    // And this never runs... Why?
    stateSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener(){
        @Override
        public void onItemSelected(AdapterView<?> adapter, View v, int position, long id){
            stateSpinner.setSelection(position);
        }
        @Override
        public void onNothingSelected(AdapterView<?> blah){

        }
    });

    return v;
}
Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
John Voss
  • 107
  • 1
  • 4

1 Answers1

1

Your adapter is empty until Firebase asynchronously hands you data

You are adding to the Arraylist instead of the adapter, and you never notify the adapter of new data as it arrives

In other words, there's nothing to set a selection to. Matter of fact, I would like to think you'd get an out of bounds exception there at setting the selection since the list is empty.

Your item selection listener will trigger, but you need to select something. But again, you haven't notified the adapter there is data available to listen on.


In code

final FirebaseDatabase database = FirebaseDatabase.getInstance();
final DatabaseReference ref = database.getReference();

final Spinner stateSpinner = v.findViewById(R.id.state_spinner);

final ArrayAdapter<String> adapter = new ArrayAdapter<>(getContext(), R.layout.spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
stateSpinner.setAdapter(adapter);

ref.child("stateDescriptions").addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        int length = (int)dataSnapshot.getChildrenCount();
        adapter.clear();
        for(int i = 0;i<length;i++) {
            adapter.add(dataSnapshot.child(Integer.toString(i)).getValue(String.class));
        }
        // For example, but this sets it back whenever data is added to Firebase 
        stateSpinner.setSelection(1);
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {
        // TODO: Implement error handling 
    }
});

stateSpinner.setOnItemSelectedListener( .... 

And ideally, I think you should be using for (DataSnapshot child : dataSnapshot.children()) rather than getting the length and subsequently getting the child at that position

OneCricketeer
  • 179,855
  • 19
  • 132
  • 245