I hit my head against the wall, and I do not understand why this is happening. I am working with new architectural components for Android, and I am having problems updating LiveData with a list of objects. I have two spinners. When I change the parameter in the first, the second should change its contents. But this last part does not occur. Can anybody help me?
State.java
@Entity(tableName = "states") public class State{ @PrimaryKey(autoGenerate = false) private int id; private String name; @ColumnInfo(name = "countryId") private String CountryId; @Ignore private Object geoCenter, geoLimit; public State(){ } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getCountryId() { return CountryId; } public void setCountryId(String countryId) { CountryId = countryId; } }
StateDAO
@Dao public interface StateDao { @Query("SELECT * FROM states") LiveData<List<State>> getAllStates(); @Query("SELECT * FROM states WHERE countryId = :countryID") LiveData<List<State>> getStatesFromCountry(String countryID); @Query("SELECT COUNT(*) FROM states") int getNrStates(); @Query("SELECT COUNT(*) FROM states WHERE countryId = :countryID") int getNrStatesByCountry(String countryID); @Insert(onConflict = IGNORE) void insertAll(List<State> states); @Delete void delete(State state); }
StateRepository
@Singleton public class StatesRepository { private final WebServices services; private final StateDao stateDao; private final Executor executor; @Inject public StatesRepository(Executor executor, StateDao stateDao, WebServices services) { this.services = services; this.stateDao = stateDao; this.executor = executor; } public LiveData<List<State>> getStates(String token){ refreshStates(token); return stateDao.getAllStates(); } public LiveData<List<State>> getStatesFromCountry(String countryID){ return stateDao.getStatesFromCountry(countryID); } private void refreshStates(final String token){ executor.execute(() -> { Log.d("oooooo", stateDao.getNrStates() + ""); if(stateDao.getNrStates() == 0){ try { Response<List<State>> response = services.getStates("Bearer "+token).execute(); stateDao.insertAll(response.body()); } catch (IOException e) { e.printStackTrace(); } } }); } }
Stateviewmodel
public class StatesViewModel extends ViewModel { private LiveData<List<State>> states; private StatesRepository repo; @Inject public StatesViewModel(StatesRepository repository){ this.repo = repository; } public void init(String token){ states = repo.getStates(token); } public void getStatesFromCountry(String countryID){ states = repo.getStatesFromCountry(countryID); } public LiveData<List<State>> getStates(){ return this.states; } }
Fragment
public class EditAddressFragment extends LifecycleFragment implements View.OnClickListener, Injectable{ private Spinner country, city, state, zip_code; private String token; private List<Country> countries; private List<City> cities; private List<State> states; @Inject ViewModelFactory viewModelFactory; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.addresses_edit_layout, container, false); city = view.findViewById(R.id.city); state = view.findViewById(R.id.state); country = view.findViewById(R.id.country); ... countries = new ArrayList<>(); cities = new ArrayList<>(); states = new ArrayList<>(); return view; } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); CountrySpinnerAdapter adapter = new CountrySpinnerAdapter(getActivity(), android.R.layout.simple_spinner_item, countries); country.setAdapter(adapter); CitySpinnerAdapter cityAdapter = new CitySpinnerAdapter(getActivity(), android.R.layout.simple_spinner_item, cities); city.setAdapter(cityAdapter); StateSpinnerAdapter stateAdapter = new StateSpinnerAdapter(getActivity(), android.R.layout.simple_spinner_item, states); state.setAdapter(stateAdapter); CountriesViewModel countriesViewModel = ViewModelProviders.of(this, viewModelFactory).get(CountriesViewModel.class); countriesViewModel.init(token); countriesViewModel.getCountries().observe(this, adapter::setValues); CityViewModel cityViewModel = ViewModelProviders.of(this, viewModelFactory).get(CityViewModel.class); cityViewModel.init(token); cityViewModel.getCities().observe(this, cityAdapter::setValues); StatesViewModel statesViewModel = ViewModelProviders.of(this, viewModelFactory).get(StatesViewModel.class); statesViewModel.init(token); statesViewModel.getStates().observe(this, states -> { Log.d("called", states.toString()); stateAdapter.setValues(states); } ); country.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) { Country c = (Country) adapterView.getItemAtPosition(i); Log.d("cd", c.getId());
....
Adapter
public void setValues(List<State> states) { this.states = states; Log.d("s", states.isEmpty()+" "+states.toString()); notifyDataSetChanged(); }