0

I have added items dynamically in Android spinner by populating final List<String> categories = new ArrayList<>(); from Firebase database. Items are loading successfully as shown in screenshot:

screenshot of items loaded in spinner

However, the spinner not showing the first item as hint(snapshot below) and it's not selecting the item either.

screenshot of spinner before selection

I have added the code below for reference:

activity_select_category.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="100dp"
    tools:context=".SelectCategoryActivity">

    <Spinner
        android:id="@+id/spinner_select_category"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</android.support.constraint.ConstraintLayout>

SelectCategoryActivity.java

package com.example.digicube;

import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import com.google.firebase.database.ChildEventListener;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;

import java.util.ArrayList;
import java.util.List;

public class SelectCategoryActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_select_category);

        Spinner selectCategorySpinner = findViewById(R.id.spinner_select_category);
        final List<String> categories = new ArrayList<>();
        DatabaseReference mCategoriesDatabaseReference = FirebaseDatabase.getInstance().getReference().child("categories");
        mCategoriesDatabaseReference.addChildEventListener(new ChildEventListener() {
            @Override
            public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
                Category category = dataSnapshot.getValue(Category.class);
                category.setKey(dataSnapshot.getKey());
                categories.add(0, category.getCategoryName());
            }
            @Override
            public void onChildChanged(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
            }

            @Override
            public void onChildRemoved(@NonNull DataSnapshot dataSnapshot) {
            }

            @Override
            public void onChildMoved(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {
            }
        });
        ArrayAdapter<String> categoryAdapter = new ArrayAdapter<String>(SelectCategoryActivity.this, android.R.layout.simple_spinner_item, categories){
            @Override
            public boolean isEnabled(int position) {
                return position != 0;
            }

            @Override
            public View getDropDownView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
                View view =  super.getDropDownView(position, convertView, parent);
                TextView hintView = (TextView) view;
                if (position == 0) {
                    hintView.setText(R.string.select_category_spinner);
                }
                return view;
            }
        };
        categoryAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        selectCategorySpinner.setAdapter(categoryAdapter);
        selectCategorySpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long l) {
                if (position > 0) {
                    String item = parent.getItemAtPosition(position).toString();
                    Toast.makeText(parent.getContext(), "Selected: " + item, Toast.LENGTH_LONG).show();
                }
            }

            @Override
            public void onNothingSelected(AdapterView<?> adapterView) {

            }
        });
    }
}
Alex Mamo
  • 130,605
  • 17
  • 163
  • 193

1 Answers1

1

You cannot pass the categories list that you get from the database to your adapter outside the callback because it will always be empty. That's why you have that empty screen. Note, that onChildAdded() method has an asynchronous behavior.

A quick solve for this problem would be to move the declaration of your adapter inside the onDataChange() method and then just notify the adapter. For more details I recommend you see my anwser from this post in which I have explained how you can get an object outside the callback. You can also take a look at this video for a better understanding.

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193