Установить обновление адаптера или RecyclerView после функции Firestore - PullRequest
0 голосов
/ 10 сентября 2018

Я заполняю таблицу базы данных realm информацией из коллекции Cloud Firestore.При первой загрузке приложение открывает и сохраняет информацию, но не отображает ее, пока я не закрою и не открою приложение.

Мне нужно, чтобы информация отображалась после ее записи в базу данных области.т.е. без необходимости закрывать и открывать приложение.Я попытался сделать это, поместив их в методы и по порядку в методе onCreate.

Так что после того, как он записал всю информацию в базу данных области, я хочу заполнить представление recycler, но я не знаю, как это сделать.что, пожалуйста, помогите?

Скриншоты

Первый запуск (слева) и второй запуск (справа)

Screen1 Screen2

OnCreate:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_edit_import_user);
    RelativeLayout = findViewById(R.id.contentuserimport);
    // initialize realm
    Realm.init(getApplicationContext());
    //SETUP REEALM
    RealmConfiguration defaultConfig = new RealmConfiguration.Builder()
            .schemaVersion(0)
            .build();
    realm=Realm.getInstance(defaultConfig);
    Intent intent = getIntent();
    moduleID = intent.getStringExtra("moduleID");
    moduleName = intent.getStringExtra("moduleName");
    ButterKnife.bind(this);
    init();
    getAssessList();
}

Init ():

private void init(){
    linearLayoutManager = new LinearLayoutManager(getApplicationContext(), LinearLayoutManager.HORIZONTAL, false);
    friendList.setLayoutManager(linearLayoutManager);
    db = FirebaseFirestore.getInstance();
    textView1.setText("Assessments - "+moduleName);
    db.collection("assessment").whereEqualTo("module","xbIpNiDXGsIPmb5sTwbH").get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
        @Override
        public void onComplete(@NonNull Task<QuerySnapshot> task) {
            if (task.isSuccessful()) {
                for (QueryDocumentSnapshot document : task.getResult()) {
                    //GET DATA
                    Assessment a=new Assessment(Double.parseDouble(document.get("achieved").toString()),
                            document.get("date").toString(),document.get("desc").toString(),document.get("module").toString(),
                            document.get("time").toString(),Double.parseDouble(document.get("total").toString()),document.get("type").toString(),
                            document.get("weight").toString());
                    //SAVE
                    RealmHelper helper=new RealmHelper(realm);
                    helper.save(a);
                }
            }
        }
    });
    //READ
    RealmHelper helper=new RealmHelper(realm);
    Assessment=helper.retrieve();
    //BIND
    adapter=new AssessAdapter(this,Assessment);
    friendList.setAdapter(adapter);
    adapter.notifyDataSetChanged();
    friendList.setAdapter(adapter);
}

getAssessList ():

private void getAssessList(){        
    //RETRIEVE
    RealmHelper helper=new RealmHelper(realm);
    Assessment=helper.retrieve();
    //BIND
    adapter=new AssessAdapter(this,Assessment);
    friendList.setAdapter(adapter);
    adapter.notifyDataSetChanged();
    friendList.setAdapter(adapter);
}

1 Ответ

0 голосов
/ 10 сентября 2018

Попытка получить данные за пределами обратного вызова, как вы, не будет работать, так как метод onComplete() имеет асинхронное поведение. Поэтому вы не можете просто использовать следующую строку кода:

Assessment=helper.retrieve();

И ожидайте получить и использовать данные вот так. API Firebase имеют значение asynchronous, что означает, что метод onComplete() возвращается сразу после его вызова, а обратный вызов из Task, который он возвращает, будет вызван через некоторое время. Там нет никаких гарантий о том, сколько времени это займет. Таким образом, получение этих данных может занять от нескольких сотен миллисекунд до нескольких секунд. Поскольку этот метод немедленно возвращает значение, значение вашего Assessment объекта, который вы пытаетесь использовать вне метода onComplete(), еще не будет заполнено из обратного вызова.

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

Быстрое решение этой проблемы - использование объекта a, который вы получаете из базы данных только внутри метода onComplete(), в противном случае я рекомендую вам посмотреть последнюю часть моего ответа из этого post , в котором я объяснил, как это можно сделать с помощью пользовательского обратного вызова. Вы также можете взглянуть на это видео для лучшего понимания.

...