我正在做一个简单的Android项目,可以从Firebase插入和检索数据。插入功能运行良好,这意味着项目已成功连接到Firebase数据库。但是,检索部分不起作用。我做了很多测试,我认为问题出在FirebaseHelper中,因为当我试图在活动中打印"firebasehelper.retrieveMajor()“的结果时,它什么也没有显示。但在FirebaseHelper中打印数据时,它确实显示了数据。代码如下所示。
型号:
@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;
}
}适配器:
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:
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绑定的活动:
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);
}
}发布于 2018-03-07 07:47:59
Firebase API是异步的,这意味着它们会在查询结果完成之前立即返回。一段时间后,您的回调将与结果一起调用。这意味着在查询完成之前,retrieveMajor函数将返回数组majors中的所有内容。
您需要正确处理Firebase API的异步特性,这意味着您不能编写直接返回从数据库获取的数据的方法。您必须使用回调来等待结果,然后根据需要更新您的UI。
要更多地了解为什么Firebase API是异步的,以及对它们有什么期望,请访问read this article。
发布于 2018-03-07 08:07:38
它打印数据是因为您的ArrayList正在被填充,但是在您将数据传递给您的适配器之后是异步的。
适配器包含对稍后通过Firebase回调填充的相同ArrayList的引用,但是当数组中有新数据时,需要使用notifyDataSetChanged()通知适配器本身,否则它不会检查它。
基本上,每次从Firebase获得新数据时,您都需要找到一种方法来通知适配器数据集的更改。可以使用的一种简单机制是callback。
https://stackoverflow.com/questions/49141769
复制相似问题