Я пытаюсь извлечь данные из базы данных Firebase в реальном времени и поместить их в CardView внутри RecyclerView внутри фрагмента.
Но показанный фрагмент чистый белый без ошибок. Я извлекаю данные из метода OnCreate и добавляю их в список.
При отладке приложения выяснилось, что даже после присвоения извлеченных данных внутри метода onCreate
список все еще равен NULL внутри метода onCreateView
.
Класс списка фрагментов панели инструментов:
public class fragment_dashboard_list extends Fragment {
List<ibu> ibu_ibu;
FirebaseDatabase database;
DatabaseReference myRef ;
String a;
public fragment_dashboard_list() {}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ibu_ibu = new ArrayList<>();
database = FirebaseDatabase.getInstance();
myRef = database.getReference("Guardian");
myRef.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
// This method is called once with the initial value and again
// whenever data at this location is updated.
for(DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()){
ibu value = dataSnapshot1.getValue(ibu.class);
ibu ibu_val = new ibu();
String alamat = value.getAlamat();
String foto = value.getFoto();
String hp = value.getHp();
String ktp = value.getKtp();
String nama = value.getNama();
String privilege = value.getPrivilege();
String ttl = value.getTtl();
ibu_val.setAlamat(alamat);
ibu_val.setFoto(foto);
ibu_val.setHp(hp);
ibu_val.setKtp(ktp);
ibu_val.setNama(nama);
ibu_val.setPrivilege(privilege);
ibu_val.setTtl(ttl);
// Here the List ibu_ibu is not NULL
ibu_ibu.add(ibu_val);
}
}
@Override
public void onCancelled(DatabaseError error) {
// Failed to read value
Log.w("Hello", "Failed to read value.", error.toException());
}
});
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_dashboard_list, container, false);
RecyclerView myrv = (RecyclerView) view.findViewById(R.id.dashboard_recycler_view);
//Here the List ibu_ibu is null
adapter_list_ibu myAdapter = new adapter_list_ibu(ibu_ibu);
LinearLayoutManager LinearLayoutManager = new LinearLayoutManager(getContext());
myrv.setLayoutManager(LinearLayoutManager);
myrv.setAdapter(myAdapter);
return view;
}
}
Я ожидал, что список будет не пустым внутри OnCreateView
поэтому фрагмент не будет пустым
API-интерфейсы Firebase являются асинхронными, что означает, что onDataChange()
возвращается сразу после его вызова, и обратный вызов будет вызван через некоторое время. Там нет никаких гарантий о том, сколько времени это займет. Таким образом, получение этих данных может занять от нескольких сотен миллисекунд до нескольких секунд.
Поскольку этот метод немедленно возвращается, ваш список ibu_val
который вы пытаетесь использовать вне onDataChange()
, еще не будет заполнен из обратного вызова, и поэтому он всегда пуст.
По сути, вы пытаетесь использовать значение переменной синхронно из API, который является асинхронным. Это не очень хорошая идея, вы должны обращаться с API асинхронно, как и предполагалось.
Быстрое решение этой проблемы - уведомить адаптер, как только вы получите все элементы из базы данных, используя:
myrv.notifyDatasetChanged();
Поэтому добавьте эту строку кода сразу после окончания цикла for.
Если вы намереваетесь использовать этот список за пределами обратного вызова, я рекомендую вам ознакомиться с последней частью моего ответа от этого поста, в которой я объяснил, как это можно сделать с помощью специального обратного вызова. Вы также можете посмотреть это видео для лучшего понимания.