2017-04-23 5 views
1

Androidスタジオでアプリを開発しており、Firebaseを使用してデータを保存/取得しています。これは正常に動作しますが、取得したデータをローカル変数に保存してからリストビューに表示しようとすると、ビューを更新するまで機能しません。AndroidのFirebaseデータが更新されるまでロードされない

これは私のOnCreate関数である:

protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.my_chores); 

    //get database reference and user data 
    mDatabase = FirebaseDatabase.getInstance().getReferenceFromUrl("https://..."); 
    user = (User) getIntent().getSerializableExtra("user"); 

    configureBackButton(); 
    updateFromFirebase(); 
    display(); 
} 

これは、更新機能(変数マップがグローバルVARである)である:

private void updateFromFirebase() { 
    final ArrayList<String> list; 
    final String name = user.getName().toLowerCase(); 

    mDatabase.addListenerForSingleValueEvent(new ValueEventListener() { 
     @Override 
     public void onDataChange(DataSnapshot snapshot) { 
      for(DataSnapshot child : snapshot.getChildren()) { 
       ArrayList<String> list; 
       String name; 
       name = child.getKey(); 
       list = (ArrayList)child.getValue(); 
       map.put(name.toLowerCase(), list); 
      } 
     } 

     @Override 
     public void onCancelled(DatabaseError databaseError) { 
      ... 
     } 
    }); 
    list = map.get(name); 
    if(list==null) return; 

    final ListView list_xml = (ListView) findViewById(R.id.list); 
    final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, list); 
    list_xml.setAdapter(adapter); 
} 

そして、これは表示機能である:

private void display() { 
    final ArrayList<String> list; 
    final String name = user.getName().toLowerCase(); 

    list = map.get(name); 
    if(list==null) return; 

    final ListView list_xml = (ListView) findViewById(R.id.list); 
    final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, list); 
    list_xml.setAdapter(adapter); 

    list_xml.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
     @Override 
     public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
      String item = adapter.getItem(position); 
      list.remove(item); 
      map.put(name, list); 

      CoordinatorLayout coordinatorLayout = (CoordinatorLayout) findViewById(R.id.coordinatorLayout); 

      Snackbar sb = Snackbar.make(coordinatorLayout, "Item Removed!", Snackbar.LENGTH_SHORT); 
      sb.show(); 

      adapter.notifyDataSetChanged(); 
     } 
    }); 

    } 

なぜ最初に表示されないのかについての洞察は理解できます。

+0

を更新した場合、それは良くなると思いますあなたはファイアーベースの権利から必要な要素をすべて手に入れますか?だからそこにあなたのビューにアダプタを設定しようとすると、それは動作するはずです。 – koksalb

+0

私はアダプタコードをonDataChange()の後ろに追加しようとしましたが、addListenerForSingleValueEvent()内にまだ残っていましたが、アダプタのコンストラクタを解決できない、または変数を解決できないというエラーが発生しました。 addListenerForSingleValueEvent()の外部のコードブロックと同じですが、updateFromFirebase()内(更新された記事を参照)にエラーはありませんが、前と同じ結果が得られます。 – kcinj

答えて

1

valueEventListenerは非同期関数であるので、それはすぐに結果を取得できない場合がありますので、私はあなたがOnDataChangeの後にデータが変更されたUI、(OnDataChangeのに)

@Override 
    public void onDataChange(DataSnapshot snapshot) { 
     for(DataSnapshot child : snapshot.getChildren()) { 
      ArrayList<String> list; 
      String name; 
      name = child.getKey(); 
      list = (ArrayList)child.getValue(); 
      map.put(name.toLowerCase(), list); 
     } 
     //this is displaying result whenever change occurs 
     display(); 
    } 
+0

はい、それを解決した、私はその機能の非同期性を知らなかった、ありがとう! – kcinj

関連する問題