Android - 从Firebase数据库显示ListView中的数据 [英] Android - Display data in ListView from Firebase database

查看:121
本文介绍了Android - 从Firebase数据库显示ListView中的数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个自定义 listview 来显示来自Firebase数据库的数据。
$ b

SectionDetails model

  public class SectionDetails {
private String sectionCode;
private String sectionSeats;

public SectionDetails(){
}

public SectionDetails(String sectionCode,String sectionSeats){
this.sectionCode = sectionCode;
this.sectionSeats = sectionSeats;
}

public String getSectionCode(){
return sectionCode;
}

public String getSectionSeats(){
return sectionSeats;
}

public void setSectionCode(String sectionCode){
this.sectionCode = sectionCode;
}

public void setSectionSeats(String sectionSeats){
this.sectionSeats = sectionSeats;




$ p $ FirebaseHelper


  public class FirebaseHelper {
DatabaseReference db;
布尔保存;
ArrayList< SectionDetails> sectionDetailsArrayList = new ArrayList<>();

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

$ b公共布尔save(SectionDetails sectionDetails){

if(sectionDetails == null){
saved = false;
} else {
try {
db.push()。setValue(sectionDetails);
saved = true;

adapter.notifyDataSetChanged();

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

返回保存;


private void fetchData(DataSnapshot dataSnapshot){
sectionDetailsArrayList.clear();

SectionDetails sectionDetails = dataSnapshot.getValue(SectionDetails.class);
sectionDetailsArrayList.add(sectionDetails);
}

public ArrayList< SectionDetails> (){
db.addChildEventListener(new ChildEventListener(){
@Override $ b $ public void onChildAdded(DataSnapshot dataSnapshot,String s){
fetchData(dataSnapshot);


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

@覆盖
public void onChildRemoved(DataSnapshot dataSnapshot){


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

}

@Override
public void onCancelled(DatabaseError databaseError){


});
return sectionDetailsArrayList;




$ CustomAdapter

$ $ p $ public class CustomAdapter extends BaseAdapter {
Context c;
ArrayList< SectionDetails> sectionDetailsArrayList;

public CustomAdapter(Context c,ArrayList< SectionDetails> sectionDetailsArrayList){
this.c = c;
this.sectionDetailsArrayList = sectionDetailsArrayList;
}

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

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

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

$ b @Override
public View getView(int position,View convertView,ViewGroup parent){
if(convertView == null){
convertView = LayoutInflater.from(c).inflate(R.layout.sections_custom_listview,parent,false);
}

TextView lvTvSectionCode =(TextView)convertView.findViewById(R.id.lvTvSectionCode);
TextView lvTvSectionSeats =(TextView)convertView.findViewById(R.id.lvTvSectionSeats);

final SectionDetails sd =(SectionDetails)this.getItem(position);

lvTvSectionCode.setText(sd.getSectionCode());
lvTvSectionSeats.setText(allocated seats:+ sd.getSectionSeats());

convertView.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
Toast.makeText(c,sd.getSectionCode (),Toast.LENGTH_LONG).show();
}
});

返回convertView;




MainActivity b

$ p $ public class AddSection extends AppCompatActivity implements View.OnClickListener {

DatabaseReference mRef;
FirebaseHelper助手;
CustomAdapter适配器;
按钮btnCreateSection;
ListView lvSectionsListOne;
String getFullSection,seats;

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

lvSectionsListOne =(ListView)findViewById(R.id.lvSectionsList);

mRef = FirebaseDatabase.getInstance()。getReference()。child(Constants.FIREBASE_COURSES).child(sections);
helper = new FirebaseHelper(mRef);

adapter = new CustomAdapter(this,helper.retrieve());
lvSectionsListOne.setAdapter(adapter);

btnCreateSection =(Button)findViewById(R.id.btnCreateSection);
btnCreateSection.setOnClickListener(this);


@Override
public void onClick(View v){
if(v == btnCreateSection){

getFullSection =section 1A;
seats =20;

SectionDetails sectionDetails = new SectionDetails(getFullSection,seats); $(b)b
if(helper.save(sectionDetails)){

adapter = new CustomAdapter(AddSection.this,helper.retrieve());
lvSectionsListOne.setAdapter(adapter);

adapter.notifyDataSetChanged();




$ b code



here ,但是这个问题是不同的。当添加第一个数据时, listview 中不显示任何内容。当添加第二个数据时,第一个数据显示在 listview 中。当添加第三个数据时,第一个数据被第二个数据替换,第二个数据显示在 listview 中。我曾尝试添加 adapter.notifyDataSetChanged(),但仍然是相同的结果。

解决方案

数据是从Firebase数据库异步检索(并同步)到您的应用程序的。这意味着您的 sectionDetailsArrayList 可能随时被修改。当你修改数据时,你需要告诉适配器,以便它可以更新视图。

  private void fetchData (DataSnapshot dataSnapshot){
sectionDetailsArrayList.clear();

SectionDetails sectionDetails = dataSnapshot.getValue(SectionDetails.class);
sectionDetailsArrayList.add(sectionDetails);

//告诉适配器我们更改了它的数据
adapter.notifyDataSetChanged();
}

这应该更新视图。但是,由于您清除了每个被添加或更改的孩子的列表,因此该应用只会显示最新添加/修改的项目。



在Firebase中设置同步数组是有点牵扯的,因为你必须处理所有的事件类型,事实上evens可以以任何顺序发生。因此,我们创建了 FirebaseUI库,其中包含从Firebase数据库到ListView的适配器和RecyclerView


I have a custom listview to display data from Firebase database.

SectionDetails model

public class SectionDetails {
    private String sectionCode;
    private String sectionSeats;

public SectionDetails() {
}

public SectionDetails(String sectionCode, String sectionSeats) {
    this.sectionCode = sectionCode;
    this.sectionSeats = sectionSeats;
}

public String getSectionCode() {
    return sectionCode;
}

public String getSectionSeats() {
    return sectionSeats;
}

public void setSectionCode(String sectionCode) {
    this.sectionCode = sectionCode;
}

public void setSectionSeats(String sectionSeats) {
    this.sectionSeats = sectionSeats;
}
}

FirebaseHelper class

public class FirebaseHelper {
        DatabaseReference db;
        Boolean saved;
        ArrayList<SectionDetails> sectionDetailsArrayList = new ArrayList<>();

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

    public Boolean save(SectionDetails sectionDetails) {

        if (sectionDetails == null) {
            saved = false;
        } else {
            try {
                db.push().setValue(sectionDetails);
                saved = true;

                adapter.notifyDataSetChanged();

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

        return saved;
    }

    private void fetchData(DataSnapshot dataSnapshot) {
        sectionDetailsArrayList.clear();

        SectionDetails sectionDetails = dataSnapshot.getValue(SectionDetails.class);
        sectionDetailsArrayList.add(sectionDetails);
    }

    public ArrayList<SectionDetails> retrieve() {
        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 sectionDetailsArrayList;
    }
}

CustomAdapter class

public class CustomAdapter extends BaseAdapter {
        Context c;
        ArrayList<SectionDetails> sectionDetailsArrayList;

    public CustomAdapter(Context c, ArrayList<SectionDetails> sectionDetailsArrayList) {
        this.c = c;
        this.sectionDetailsArrayList = sectionDetailsArrayList;
    }

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

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

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if (convertView == null) {
            convertView = LayoutInflater.from(c).inflate(R.layout.sections_custom_listview, parent, false);
        }

        TextView lvTvSectionCode = (TextView) convertView.findViewById(R.id.lvTvSectionCode);
        TextView lvTvSectionSeats = (TextView) convertView.findViewById(R.id.lvTvSectionSeats);

        final SectionDetails sd = (SectionDetails) this.getItem(position);

        lvTvSectionCode.setText(sd.getSectionCode());
        lvTvSectionSeats.setText("allocated seats: " + sd.getSectionSeats());

        convertView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(c, sd.getSectionCode(), Toast.LENGTH_LONG).show();
            }
        });

        return convertView;
    }
}

MainActivity class

public class AddSection extends AppCompatActivity implements View.OnClickListener {

DatabaseReference mRef;
FirebaseHelper helper;
CustomAdapter adapter;
Button btnCreateSection;
ListView lvSectionsListOne;
String getFullSection, seats;

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

    lvSectionsListOne = (ListView) findViewById(R.id.lvSectionsList);

    mRef = FirebaseDatabase.getInstance().getReference().child(Constants.FIREBASE_COURSES).child("sections");
    helper = new FirebaseHelper(mRef);

    adapter = new CustomAdapter(this, helper.retrieve());
    lvSectionsListOne.setAdapter(adapter);

    btnCreateSection = (Button) findViewById(R.id.btnCreateSection);
    btnCreateSection.setOnClickListener(this);

}

@Override
public void onClick(View v) {
    if (v == btnCreateSection) {

        getFullSection = "section 1A";
        seats = "20";

        SectionDetails sectionDetails = new SectionDetails(getFullSection, seats);

            if (helper.save(sectionDetails)) {

                adapter = new CustomAdapter(AddSection.this, helper.retrieve());
                lvSectionsListOne.setAdapter(adapter);

                adapter.notifyDataSetChanged();

            }
    }
}
}

I posted a similar question here, but this problem is different. When first data is added, nothing is shown in the listview. When second data is added, first data is shown in listview. And when third data is added, first data is replaced by second data, and second data is shown in listview. I have tried adding adapter.notifyDataSetChanged(), but still the same result.

解决方案

Data is retrieved (and synchronized) from the Firebase Database to your app asynchronously. This means that your sectionDetailsArrayList may be modified at any time. When you modify the data, you need to tell the adapter about it, so that it can update the view.

private void fetchData(DataSnapshot dataSnapshot) {
    sectionDetailsArrayList.clear();

    SectionDetails sectionDetails = dataSnapshot.getValue(SectionDetails.class);
    sectionDetailsArrayList.add(sectionDetails);

    // tell the adapter that we changed its data
    adapter.notifyDataSetChanged();
}

This should update the view. But since you clear out the list for every child that gets added or changed, the app will only show the latest added/modified item.

Setting up a synchronized array in Firebase is somewhat involved, since you have to deal with all event types and with the fact that evens can happen in any order. For that reason we create the FirebaseUI library, which contains adapters from the Firebase Database to a ListView and RecyclerView.

这篇关于Android - 从Firebase数据库显示ListView中的数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆