Список не обновляется при получении данных с Firebase Android - PullRequest
0 голосов
/ 01 мая 2018

В моем проекте есть класс модели с именем Family. Я создаю список этого класса. Сначала я создал экземпляр базы данных firebase, а затем инициализировал список. После этого вызывается метод loadData () для заполнения списка путем сбора данных из firebase. Список обновляется там, и когда я проверяю размер внутри метода loadData (), он показывает соответствующий размер, но когда я проверяю список вне метода loadData (), он показывает список как пустой. Я запутался, что мне здесь не хватает. Вот код:

public class FamilyRecycler extends AppCompatActivity {

ArrayList<Family> list1;
ArrayList<Family> mylist;
private DatabaseReference mDatabase, demoRef;
DBHelper myDB;


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

   String id = getIntent().getExtras().getString("id");

    String name="";
    boolean flag = true;


    mylist = new ArrayList<>();
    mDatabase = FirebaseDatabase.getInstance().getReference("family");


    loadData();

    Toast.makeText(this, "Size: "+mylist.size(), Toast.LENGTH_SHORT).show();

    list1 = new ArrayList<Family>();
    myDB = new DBHelper(this);

    while(hasParent(id)){

        for(int i=0;i<mylist.size();i++){
            if(mylist.get(i).getId().equalsIgnoreCase(id)){
                list1.add(mylist.get(i));
                id=mylist.get(i).getFid();
                break;
            }
        }
    }


    this.setTitle(name+"'s Family Tree");



    RecyclerView familyList = findViewById(R.id.familyList);
    familyList.setLayoutManager(new LinearLayoutManager(this));
    familyList.setAdapter(new FamilyAdapter(list1));
}

public void loadData(){
    mDatabase.addListenerForSingleValueEvent(new ValueEventListener() {


        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {

            //List<Family> list = new ArrayList<>();
            for (DataSnapshot adSnapshot: dataSnapshot.getChildren()) {
                Family f = adSnapshot.getValue(Family.class);
                mylist.add(f);

            }


        }
        @Override
        public void onCancelled(DatabaseError databaseError) {
        }
    });

}

public boolean hasParent(String id){
    String fid="";
    boolean status =false;
    for(int i=0;i<mylist.size();i++)
    {
        Toast.makeText(this, "FID: "+mylist.get(i).getId(), Toast.LENGTH_SHORT).show();
        if(Integer.parseInt(mylist.get(i).getId())==Integer.parseInt(id))
        {
            fid = mylist.get(i).getFid();

            break;
        }
    }
    for(int i=0; i<mylist.size();i++)
    {
        Toast.makeText(this, "Value "+status, Toast.LENGTH_SHORT).show();
        if(Integer.parseInt(mylist.get(i).getId())==Integer.parseInt(fid)){
            status= true;
            break;
        }
    }
   // Toast.makeText(this, "Status"+status+mylist.get(47).getId(), Toast.LENGTH_SHORT).show();
    return status;
}
}

Дайте мне знать, если вам нужна дополнительная информация!

Ответы [ 3 ]

0 голосов
/ 01 мая 2018

Поскольку база данных Firebase реального времени работает асинхронно (запросы к базе данных и другие материалы выполняются в фоновом потоке, поэтому каким-то образом ваш метод loadData () вызывается после всех других методов, вызываемых внутри метода onCreate (). Решение состоит в том, что вы должны поместить все, что вы хотите сделать с полученными данными внутри метода onDataChange (), иначе это не сработает.

Я переписал ваш код следующим образом:

  public void loadData(){
    mDatabase.addListenerForSingleValueEvent(new ValueEventListener() {


        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {

            List<Family> list = new ArrayList<>();
            for (DataSnapshot adSnapshot: dataSnapshot.getChildren()) {
                Family f = adSnapshot.getValue(Family.class);
                list.add(f);
            }

            familyList.setAdapter(new FamilyAdapter(list));
        }
        @Override
        public void onCancelled(DatabaseError databaseError) {
        }
    });

}
0 голосов
/ 01 мая 2018

вам нужно дождаться ответа от базы данных firebase. Итак, в соответствии с требованиями вашего приложения, внесите следующие изменения в ваш код:

1) создать один интерфейс для получения ответа:

public interface GetFamilyData {

        void onDataLoaded(ArrayList<Family> families);

        void onError(String errorMsg);
    }

2) теперь измените метод loadData (), как показано ниже:

public void loadData(final GetFamilyData familyData) {
        mDatabase.addListenerForSingleValueEvent(new ValueEventListener() {


            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {

                //List<Family> list = new ArrayList<>();
                for (DataSnapshot adSnapshot : dataSnapshot.getChildren()) {
                    Family f = adSnapshot.getValue(Family.class);
                    mylist.add(f);
                }

                familyData.onDataLoaded(mylist);

            }

            @Override
            public void onCancelled(DatabaseError databaseError) {
                familyData.onError("Error occur while getting family data");
            }
        });

    }

3) теперь вызовите ваш метод loadData ():

loadData(new GetFamilyData() {
            @Override
            public void onDataLoaded(ArrayList<Family> families) {

                Toast.makeText(FamilyRecycler.this, "Size: "+families.size(), Toast.LENGTH_SHORT).show();

                list1 = new ArrayList<Family>();
                myDB = new DBHelper(this);

                while(hasParent(id)){

                    for(int i=0;i<families.size();i++){
                        if(families.get(i).getId().equalsIgnoreCase(id)){
                            list1.add(families.get(i));
                            id=families.get(i).getFid();
                            break;
                        }
                    }
                }


                FamilyRecycler.this.setTitle(name+"'s Family Tree");

                RecyclerView familyList = findViewById(R.id.familyList);
                familyList.setLayoutManager(new LinearLayoutManager(FamilyRecycler.this));
                familyList.setAdapter(new FamilyAdapter(list1));
            }

            @Override
            public void onError(String errorMsg) {

                Toast.makeText(FamilyRecycler.this, errorMsg, Toast.LENGTH_SHORT).show();
            }
        });

надеюсь, это сработает для вас

0 голосов
/ 01 мая 2018

Как я знаю, метод onDataChange () будет вызываться асинхронно. Это означает, что когда вы показываете Toast о размере списка, в то время как onDataChange () еще не может быть вызван, поэтому список пуст.

Вы должны поместить код Toast в onDataChange (), чтобы увидеть результат

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...