如何从firebase数据库中正确获取数据?

时间:2017-04-19 18:12:38

标签: android firebase firebase-realtime-database

我正在开发保持用户费用的应用程序,我写了CustomAdapter

public class CustomAdapter extends BaseAdapter{
Context c;
ArrayList<Income> incomes;



public CustomAdapter(){}

public CustomAdapter(Context c,ArrayList<Income> incomes){
    this.incomes=incomes;
    this.c=c;


}

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

@Override
public Object getItem(int position) {
    return incomes.get(position);
}

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

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

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

    TextView nameTxt= (TextView) convertView.findViewById(R.id.nameTxt);
    TextView propTxt= (TextView) convertView.findViewById(R.id.aciklama);
    TextView descTxt= (TextView) convertView.findViewById(R.id.descTxt);



     Income s= (Income) this.getItem(position);
    nameTxt.setText(s.getName());
    propTxt.setText(s.getType());
    descTxt.setText((String.valueOf(s.getMiktar())));

    return convertView;
}

并在活动

上实施
public class ExpenseActivity extends Activity{

DatabaseReference db;

FloatingActionButton fab;
ExpenseAdapter adapter;
ListView lv;
Boolean saved;
EditText nameEditTxt, propTxt, descTxt;
ArrayList<Expense> expenselist = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.expense_content);

    //Toolbar toolbar=(Toolbar)findViewById(R.id.toolbar);
    // setSupportActionBar(toolbar);
    lv = (ListView) findViewById(R.id.listview);

    db = FirebaseDatabase.getInstance().getReference();
    //isa



    adapter = new ExpenseAdapter(ExpenseActivity.this, getExpenses());
    lv.setAdapter(adapter);
    adapter.notifyDataSetChanged();
    fab = (FloatingActionButton) findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            displayInput();
        }
    });


}

public Boolean save(Expense expense){

    if(expense==null){

        saved=false;

    }else{

        try{


            db.child("Expense").push().setValue(expense);

            saved=true;
        }catch (Exception ex){

            ex.printStackTrace();;
            saved=false;

        }
    }

    return saved;


}



public void fetchData(DataSnapshot dataSnapshot)
{



    expenselist.clear();


    for (DataSnapshot ds : dataSnapshot.getChildren())
    {
        Expense expense=ds.getValue(Expense.class);
        expenselist.add(expense);
        adapter.notifyDataSetChanged();

    }

}




public ArrayList<Expense> getExpenses(){

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



        }

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

            fetchData(dataSnapshot);
        }

        @Override
        public void onChildRemoved(DataSnapshot dataSnapshot) {

        }

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

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });

    return expenselist;

}






private void displayInput() {
    final Dialog d=new Dialog(this);

    d.setTitle("Gelir Girin");

    d.setContentView(R.layout.expense_layout);

    nameEditTxt = (EditText) d.findViewById(R.id.name);
    propTxt = (EditText) d.findViewById(R.id.kategori);
    descTxt = (EditText) d.findViewById(R.id.miktar);
    Button saveBtn = (Button) d.findViewById(R.id.saveBtn);


    saveBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            String name = nameEditTxt.getText().toString();
            String type = propTxt.getText().toString();
            String  amount= String.valueOf(descTxt.getText().toString());

            Expense expense=new Expense(name,type,amount);




            if (name != null && name.length() > 0) {
                //THEN SAVE
                if (save(expense)) {


                    //IF SAVED CLEAR EDITXT
                    d.cancel();
                    nameEditTxt.setText("");
                    propTxt.setText("");
                    descTxt.setText("");


                }
            } else {
                Toast.makeText(ExpenseActivity.this, "Name Must Not Be Empty", Toast.LENGTH_SHORT).show();
            }

        }
    });

    d.show();




}

但是即使我在firebase中保存了一些数据,它返回null并且首先将null传递给字段(textview)但是当我添加新项目时它会在Firebase中显示现有数据。我的一个朋友说我是异步调用数据但我不理解它。我想在打开活动时直接显示数据。感谢任何帮助,谢谢

当我打开活动时:

enter image description here

添加新数据后:

enter image description here

2 个答案:

答案 0 :(得分:0)

  myRef.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            fetchdata();
           }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });

这将获取适当的数据

答案 1 :(得分:0)

您的问题是您在从数据库中获取数据之前正在初始化您的适配器。

adapter = new ExpenseAdapter(ExpenseActivity.this, getExpenses());

getExpenses()方法正在执行异步操作

尝试直接传递列表并调用getExpenses方法

adapter = new ExpenseAdapter(ExpenseActivity.this, expenselist);
getExpenses()

然后,当在fetchData方法中调用notifyDatasetChanged时,它将更新列表。