Как исправить Список <>, который становится нулевым внутри OnCreateView ()

1

Я пытаюсь извлечь данные из базы данных 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 поэтому фрагмент не будет пустым

Теги:
firebase
android-fragments
firebase-realtime-database

1 ответ

1

API-интерфейсы Firebase являются асинхронными, что означает, что onDataChange() возвращается сразу после его вызова, и обратный вызов будет вызван через некоторое время. Там нет никаких гарантий о том, сколько времени это займет. Таким образом, получение этих данных может занять от нескольких сотен миллисекунд до нескольких секунд.

Поскольку этот метод немедленно возвращается, ваш список ibu_val который вы пытаетесь использовать вне onDataChange(), еще не будет заполнен из обратного вызова, и поэтому он всегда пуст.

По сути, вы пытаетесь использовать значение переменной синхронно из API, который является асинхронным. Это не очень хорошая идея, вы должны обращаться с API асинхронно, как и предполагалось.

Быстрое решение этой проблемы - уведомить адаптер, как только вы получите все элементы из базы данных, используя:

myrv.notifyDatasetChanged();

Поэтому добавьте эту строку кода сразу после окончания цикла for.

Если вы намереваетесь использовать этот список за пределами обратного вызова, я рекомендую вам ознакомиться с последней частью моего ответа от этого поста, в которой я объяснил, как это можно сделать с помощью специального обратного вызова. Вы также можете посмотреть это видео для лучшего понимания.

  • 0
    Привет, дпустакан! Вы пробовали мое решение выше? Если вы считаете, что мой ответ помог вам, рассмотрите возможность его принятия, нажав на флажок (✔️) с левой стороны под стрелками голосования. Следует изменить цвет на зеленый. Буду признателен. Спасибо!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню