我很难搞清楚这一点。我有一个带有listview的活动。我的listview使用包含TextView和imageView的row_item。
这是我的数据对象
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。任何帮助将不胜感激。谢谢。
答案 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。
希望这有助于!!!!