列表从firebase android获取数据时不更新

时间:2018-05-01 02:48:38

标签: android firebase firebase-realtime-database

我的项目中有一个名为Family的模型类。我正在创建该类的列表。 首先,我实例化了firebase数据库,然后初始化列表。之后,通过从firebase收集数据来调用loadData()方法来填充列表。列表在那里得到更新,当我在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 :(得分:1)

据我所知,onDataChange()方法将异步调用。这意味着当您向Toast显示列表大小时,当时可能尚未调用onDataChange(),因此列表为空。

你应该在onDataChange()中放入Toast代码来查看结果

答案 1 :(得分:1)

由于Firebase实时数据库是异步工作的(数据库查询和东西在后台线程上运行,因此在onCreate()方法中调用所有其他方法后调用loadData()方法。解决方案是,你必须把所有的东西都放在你想在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) {
        }
    });

}

答案 2 :(得分:1)

您需要等待来自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();
            }
        });

希望这对你有用