首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在Android中使用MVC模式从firebase中检索数据?

如何在Android中使用MVC模式从firebase中检索数据?
EN

Stack Overflow用户
提问于 2018-03-07 07:34:10
回答 2查看 1.1K关注 0票数 3

我正在做一个简单的Android项目,可以从Firebase插入和检索数据。插入功能运行良好,这意味着项目已成功连接到Firebase数据库。但是,检索部分不起作用。我做了很多测试,我认为问题出在FirebaseHelper中,因为当我试图在活动中打印"firebasehelper.retrieveMajor()“的结果时,它什么也没有显示。但在FirebaseHelper中打印数据时,它确实显示了数据。代码如下所示。

型号:

代码语言:javascript
运行
复制
@IgnoreExtraProperties
public class Major {

    public String major_id;
    public String major_name;

    public Major() {
    }

    public Major(String major_id, String major_name) {
        this.major_id = major_id;
        this.major_name = major_name;
    }

    public String getMajor_id() {
        return major_id;
    }

    public String getMajor_name() {
        return major_name;
    }
}

适配器:

代码语言:javascript
运行
复制
public class MajorListAdapter extends BaseAdapter {
    Context context;
    ArrayList<Major> majors;

    public MajorListAdapter(Context context, ArrayList<Major> majors) {
        this.context = context;
        this.majors = majors;
    }

    @Override
    public int getCount() {
        return majors.size();
    }

    @Override
    public Object getItem(int pos) {
        return majors.get(pos);
    }

    @Override
    public long getItemId(int pos) {
        return pos;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup viewGroup) {

        if(convertView==null)
        {
            convertView= LayoutInflater.from(context).inflate(R.layout.model,viewGroup,false);
        }

        TextView tv_majorid= (TextView) convertView.findViewById(R.id.tx_majorid);
        TextView tv_majorname= (TextView) convertView.findViewById(R.id.tx_majorname);

        final Major major= (Major) this.getItem(position);

        tv_majorid.setText(major.getMajor_id());
        tv_majorname.setText(major.getMajor_name());

        return convertView;
    }

}

FirebaseHelper:

代码语言:javascript
运行
复制
public class FirebaseHelper {

    DatabaseReference db;
    Boolean saved=null;
    ArrayList<Major> majors = new ArrayList<>();

    public FirebaseHelper(DatabaseReference db) {
        this.db = db;
    }

    //Save the Major info. into db
    public Boolean saveMajor(Major major)
    {
        if(major==null)
        {
            saved=false;
        }else
        {
            try
            {
                db.child("Major").push().setValue(major);
                saved=true;

            }catch (DatabaseException e)
            {
                e.printStackTrace();
                saved=false;
            }
        }

        return saved;
    }

    private void fetchDataFromMajor(DataSnapshot dataSnapshot) {
        majors.clear();

        for (DataSnapshot ds : dataSnapshot.getChildren()) {
            Major major = ds.getValue(Major.class);
            majors.add(major);
        }

    }

    public ArrayList<Major> retrieveMajor() {

        db.addChildEventListener(new ChildEventListener() {
            @Override
            public void onChildAdded(DataSnapshot dataSnapshot, String s) {
                fetchDataFromMajor(dataSnapshot);                  
            }

            @Override
            public void onChildChanged(DataSnapshot dataSnapshot, String s) {
                fetchDataFromMajor(dataSnapshot);

            }

            @Override
            public void onChildRemoved(DataSnapshot dataSnapshot) {

            }

            @Override
            public void onChildMoved(DataSnapshot dataSnapshot, String s) {

            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });


        return majors;
    }
}

检索数据并将数据与ListView绑定的活动:

代码语言:javascript
运行
复制
public class MajorListActivity extends AppCompatActivity {

    DatabaseReference db;
    FirebaseHelper firebasehelper;
    MajorListAdapter adapter;
    ListView lv_MajorList;

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

        lv_MajorList = (ListView) findViewById(R.id.lv_MajorList);

        db= FirebaseDatabase.getInstance().getReference();
        firebasehelper=new FirebaseHelper(db);

        //ADAPTER
        adapter = new MajorListAdapter(getApplicationContext(),firebasehelper.retrieveMajor());

        lv_MajorList.setAdapter(adapter);
    }

}
EN

回答 2

Stack Overflow用户

发布于 2018-03-07 07:47:59

Firebase API是异步的,这意味着它们会在查询结果完成之前立即返回。一段时间后,您的回调将与结果一起调用。这意味着在查询完成之前,retrieveMajor函数将返回数组majors中的所有内容。

您需要正确处理Firebase API的异步特性,这意味着您不能编写直接返回从数据库获取的数据的方法。您必须使用回调来等待结果,然后根据需要更新您的UI。

要更多地了解为什么Firebase API是异步的,以及对它们有什么期望,请访问read this article

票数 1
EN

Stack Overflow用户

发布于 2018-03-07 08:07:38

它打印数据是因为您的ArrayList正在被填充,但是在您将数据传递给您的适配器之后是异步的。

适配器包含对稍后通过Firebase回调填充的相同ArrayList的引用,但是当数组中有新数据时,需要使用notifyDataSetChanged()通知适配器本身,否则它不会检查它。

基本上,每次从Firebase获得新数据时,您都需要找到一种方法来通知适配器数据集的更改。可以使用的一种简单机制是callback

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49141769

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档