2017-02-12 13 views
0

私はこれを理解するのに苦労しています。私はそれに関するリストビューを持つ活動を持っています。私のlistviewはTextViewとimageViewを含むrow_itemを使います。Android - アクティビティーロード時にFirebaseからListviewにデータを取得する

ここに私の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; 
    } 
} 

負荷リストビューを参照することを最初のクラスです...これはスニペットです。

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メソッドが実行されます。このメソッドは、リストビューアダプタを設定し、FireBaseヘルパークラスを呼び出して、retrieveメソッドを実行します。 retrieveメソッドは、ChildEventListenerを設定します。

しかし、このすべてが起こっているとき、私はFirebaseデータベースを照会し、2つのリストビュー行を表示したいと思います。最初のものはレベル2と言い、次のものはレベル3と言うべきです。どちらの行にも、現在書かれているGetViewメソッドの方法に従ってロックドロウアブルが表示されるはずです。しかし、私はこれを今実行すると、私は空白の画面が表示されます。私はデータを取得してArrayListを取り込んでいるのがわかりますが、何らかの理由でデータがListViewに入っていないことがわかります。どんな助けもありがたいです。ありがとう。

+0

あなたのfirebaseデータベースに関連して、必要なのは、レベル2のユーザを1つのリストビューに、3のユーザを別のリストビューに表示することです。そうですか? –

答えて

0

問題はhelper.retrieve()が空のリストを返すことです。コードでfetchDataは、子が追加または変更されたときに非同期に呼び出されます。フェッチデータを呼び出すと、arraylistはいっぱいになっていますが、アダプタで更新されていません。

あなたのコードを再編成すると思います。しかし、あなたは、現在のコードを続行したい場合は、私はあなたがインターフェイスを定義することをお勧め -

public interface OnDataChangeListener { 
    void onDataChanged(); 
} 

は、あなたのFirebaseHelperクラスがOnDataChangeListenerオブジェクトの集合を維持しましょう。第1の方法において

void addDataChangeListener(OnDataChangeListener l); 
void removeDataChangeListener(OnDataChangeListener l); 

セットと第2セットからの参照を削除渡さリスナーオブジェクトを追加 -

FirebaseHelperに2つのメソッドを公開します。 fetchDataメソッドが完了すると、OnDataChangeListenerオブジェクトのセットを反復処理し、onDataChangedメソッドを呼び出すことができます。

アダプタクラスにOnDataChangeListenerインターフェイスを実装し、FirebaseHelperクラスに設定します。

基本的に、私が説明したのは、オブザーバーパターンを実装する必要があるということです。そのため、データが変更されるたびにアダプタに通知され、それに応じてUIがリフレッシュされます。

これが役立ちますように!!!!

+0

ありがとうございました。私はアンドロイド初心者なので、今はインターフェイスを使用しないようにしました。私は代わりに、取得メソッドとフェッチメソッドをFireBaseHelperクラスから取り出し、それらをActivityクラスに入れました。それは私がadapter.notifyDataSetChanged()を追加するまで、まだ動作しませんでした。私のChildEventListener onChildAddedメソッドとonChildChangedメソッド。それはすべて今働いている。 –

関連する問題