Android - 在活动负载

时间:2017-02-12 03:39:47

标签: android listview firebase firebase-realtime-database

我很难搞清楚这一点。我有一个带有listview的活动。我的listview使用包含TextView和imageView的row_item。

这是我的Firebase RealTime数据库。 Firebase Database

这是我的数据对象

public class Spacecraft
{
    private int level;
    private int NumCorrect;

    public Spacecraft()
    {
    }

    public int getLevel() {return level;}
    public void setLevel(int level) {this.level = level;}

    public int getNumCorrect() {return NumCorrect;}
    public void setNumCorrect(int numCorrect) {NumCorrect = numCorrect;}
}

我的FireBaseHelper类

public class FirebaseHelper {
    DatabaseReference db;
    Boolean saved;
    ArrayList<Spacecraft> spacecrafts=new ArrayList<>();
    /*
 PASS DATABASE REFRENCE
  */
    public FirebaseHelper(DatabaseReference db) {
        this.db = db;
    }
    //WRITE IF NOT NULL
    public Boolean save(Spacecraft spacecraft)
    {
        if(spacecraft==null)
        {
            saved=false;
        }else
        {
            try
            {
                db.child("users").push().setValue(spacecraft);
                //db.child("Spacecraft").push().setValue(spacecraft);
                saved=true;
            }catch (DatabaseException e)
            {
                e.printStackTrace();
                saved=false;
            }
        }
        return saved;
    }
    //IMPLEMENT FETCH DATA AND FILL ARRAYLIST
    private void fetchData(DataSnapshot dataSnapshot)
    {
        spacecrafts.clear();
        for (DataSnapshot ds : dataSnapshot.getChildren())
        {
            Spacecraft spacecraft=ds.getValue(Spacecraft.class);
            spacecrafts.add(spacecraft);
        }
    }
    //RETRIEVE
    public ArrayList<Spacecraft> 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 spacecrafts;
    }
}

我的自定义适配器

public class CustomAdapter extends BaseAdapter{
    Context c;
    ArrayList<Spacecraft> spacecrafts;
    public CustomAdapter(Context c, ArrayList<Spacecraft> spacecrafts) {
        this.c = c;
        this.spacecrafts = spacecrafts;
    }
    @Override
    public int getCount() {
        return spacecrafts.size();
    }
    @Override
    public Object getItem(int position) {
        return spacecrafts.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.list_item,parent,false);
        }
        TextView nameTxt= (TextView) convertView.findViewById(R.id.LevelText);
        //TextView propTxt= (TextView) convertView.findViewById(R.id.propellantTxt);
        //TextView descTxt= (TextView) convertView.findViewById(R.id.descTxt);
        ImageView iv=(ImageView) convertView.findViewById(R.id.imageViewStars);

        final Spacecraft s= (Spacecraft) this.getItem(position);
        nameTxt.setText("Level " + s.getLevel());
        iv.setImageResource(R.drawable.lock);

        return convertView;
    }
}

加载的第一个类引用listview ...这是一个snipet。

public class GoogleAuthentication extends AppCompatActivity implements Serializable,
        GoogleApiClient.OnConnectionFailedListener {

    private static final String TAG = "SignInActivity";
    private static final int RC_SIGN_IN = 9001;
    public final static String USER_ID = "USER_ID";

    private GoogleApiClient mGoogleApiClient;
    private FireBase mFirebase;

    DatabaseReference db;
    FirebaseHelper helper;
    CustomAdapter adapter;

    private TextView mStatusTextView;
    private ProgressDialog mProgressDialog;
    MenuInflater inflater;
    private boolean  mSignedIn;
    private GoogleSignInAccount acct;
    private NumberPicker picker;
    ArrayList Levels;
    String[] LevelsArray;


    ListView lv;

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

        //INITIALIZE FIREBASE DB
        db = FirebaseDatabase.getInstance().getReference();
        helper = new FirebaseHelper(db);
        //ADAPTER
        lv = (ListView) findViewById(R.id.LevelListView);
// Configure sign-in to request the user's ID, email address, and basic
// profile. ID and basic profile are included in DEFAULT_SIGN_IN.
        GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                .requestEmail()
                .build();

        // Build a GoogleApiClient with access to the Google Sign-In API and the
// options specified by gso.
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */)
                .addApi(Auth.GOOGLE_SIGN_IN_API, gso)
                .build();
    }
private void updateUI(boolean signedIn)
    {
        mSignedIn = signedIn;
        if (signedIn)
        {
            Spacecraft s = new Spacecraft();
            s.setLevel(0);


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

            invalidateOptionsMenu();
        } else {
            //mStatusTextView.setText(R.string.signed_out);
        }
    }
}

因此,当加载GoogleAuthentication类时,它会初始化并获取对Firebase数据库的引用。然后它将用户签入他们的Google帐户。然后运行UpdateUI方法。此方法设置listview适配器并调用FireBase Helper类并运行retrieve方法。 retrieve方法设置ChildEventListener。

但是,当所有这一切发生时,我想查询Firebase数据库并显示2个listview行。第一个应该说第2级,下一个应该说第3级。两行都应该根据我现在编写的GetView方法显示锁定drawable。但是,当我现在运行时,我只看到一个空白屏幕。我可以看到我正在检索数据并填充ArrayList,但由于某种原因,数据没有进入ListView。任何帮助将不胜感激。谢谢。

1 个答案:

答案 0 :(得分:0)

问题是helper.retrieve()返回一个空列表。在添加或更改子项时,代码fetchData会异步调用。在调用获取数据时,arraylist正在填充,但在适配器上不会更新。

您可能会考虑重新组织代码。但是如果你想继续使用当前的代码,我建议你定义一个接口 -

public interface OnDataChangeListener {
    void onDataChanged();
}

让您的FirebaseHelper班级保留一组OnDataChangeListener个对象。

FirebaseHelper -

中公开两种方法
void addDataChangeListener(OnDataChangeListener l);
void removeDataChangeListener(OnDataChangeListener l);

在第一种方法中,添加传递给集合的侦听器对象,然后在第二种方法中删除集合中的引用。 每当fetchData方法完成时,您可以迭代OnDataChangeListener个对象并调用onDataChanged方法。

让您的适配器类实现OnDataChangeListener接口并将其设置为FirebaseHelper类。

基本上,我解释的是你应该实现一个观察者模式。这样每次数据更改时都会通知适配器并相应地刷新UI。

希望这有助于!!!!