5

Я выборка некоторых данных из FirebaseDatabase, а затем положить их в array, а затем пытаюсь показать их в List, который в обычае AlertDialog.данных извлекаются из FirebaseDatabase становятся показано в 3 отдельных AlertDialogs вместо одного

Вот код:

query = mDatabase.child("child").child(anotherChild).child("yetAnotherChild"); 

uProfile.setOnClickListener(new View.OnClickListener() { 
    @Override 
    public void onClick(View view) { 
     query.orderByChild("someChild").addChildEventListener(new ChildEventListener() { 
      @Override 
      public void onChildAdded(DataSnapshot dataSnapshot, String s) { 
       if (dataSnapshot != null) { 

        Map<String, String> newD = (Map<String, String>) dataSnapshot.getValue(); 

        ArrayList<String> l = new ArrayList<String>(); 
        l.add(newD.get("lol").substring(30)); 

        String names[] = l.toArray(new String[0]); 

        AlertDialog.Builder alertDialog = new AlertDialog.Builder(Activity.this); 
        LayoutInflater inflater = getLayoutInflater(); 
        View convertView = inflater.inflate(R.layout.dialog_list, null); 
        alertDialog.setView(convertView); 
        alertDialog.setTitle("title"); 
        ListView lv = (ListView) convertView.findViewById(R.id.lv); 
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(getBaseContext(), android.R.layout.simple_list_item_1, names); 
        lv.setAdapter(adapter); 

        alertDialog.setPositiveButton("OK", new DialogInterface.OnClickListener() { 
         @Override 
         public void onClick(DialogInterface dialogInterface, int i) { 

         } 
        }); 

        alertDialog.show(); 
       } else { 
        Toast.makeText(getBaseContext(), "NULLLLL", Toast.LENGTH_SHORT).show(); 
       } 
      } 

      ... 
      ... 
     }); 

    } 
}); 

Вот структура базы данных:

app 
-child 
    -anotherChild 
    -yetAnotherChild 
     -inaccessibleChild 
     -someChild: "value" 
     -lol: "value" 

Я не могу использовать valueEventListener() здесь, как у меня нет доступа к inaccessibleChild. inaccessibleChild вот uid других пользователей, которые следовали за определенным пользователем. Как я могу получить там uid?

Проблема в том, что данные получают за уши, но вместо того, чтобы показаны в списке в одном AlertDialog, он становится показан один за одним в отдельной AlertDialog.

Что здесь общего не работает?

Пожалуйста, дайте мне знать.

+0

Сколько детей находится под 'child/anotherChild/yetAnotherChild'? вы прикрепляете 'ChildEventListener', и похоже, что у него есть 3 дочерних элемента под этим узлом, поэтому поэтому' onChildAdded' запускается 3 раза (и 'alertDialog.show();' называется 3 раза – Wilik

+0

@Wilik yeah ... это то, что происходит. Как разрешить 'alertDialog.show();' получать только один раз, показывая все 3 значения? –

+0

Ответ Reaz Murshed является лучшим примером, используя 'ValueEventListener' – Wilik

ответ

1

Ну, ни один из приведенных выше ответов не помог, хотя ответ Linxy правильный, я увидел его после решения проблемы.

Двигаясь весь код, и писать только эту строку: alertDialog.show(); внутри setOnClickListener() улучшение моего кода к этому:

query = mDatabase.child("child").child(anotherChild).child("yetAnotherChild"); 

    query.orderByChild("someChild").addChildEventListener(new ChildEventListener() { 
       @Override 
       public void onChildAdded(DataSnapshot dataSnapshot, String s) { 
        if (dataSnapshot != null) { 

         Map<String, String> newD = (Map<String, String>) dataSnapshot.getValue(); 

         ArrayList<String> l = new ArrayList<String>(); 
         l.add(newD.get("lol").substring(30)); 

         String names[] = l.toArray(new String[0]); 

         AlertDialog.Builder alertDialog = new AlertDialog.Builder(Activity.this); 
         LayoutInflater inflater = getLayoutInflater(); 
         View convertView = inflater.inflate(R.layout.dialog_list, null); 
         alertDialog.setView(convertView); 
         alertDialog.setTitle("title"); 
         ListView lv = (ListView) convertView.findViewById(R.id.lv); 
         ArrayAdapter<String> adapter = new ArrayAdapter<String>(getBaseContext(), android.R.layout.simple_list_item_1, names); 
         lv.setAdapter(adapter); 

         alertDialog.setPositiveButton("OK", new DialogInterface.OnClickListener() { 
          @Override 
          public void onClick(DialogInterface dialogInterface, int i) { 

          } 
         }); 
        } else { 
         Toast.makeText(getBaseContext(), "NULLLLL", Toast.LENGTH_SHORT).show(); 
        } 
       } 

       ... 
       ... 
      }); 

uProfile.setOnClickListener(new View.OnClickListener() { 
    @Override 
    public void onClick(View view) { 
     alert11.show(); 
    } 
}); 

Во всяком случае, я хотел бы поблагодарить всех тех, кто ответил на этот вопрос.

Мир.

3

Операции с Firebase являются асинхронными, поэтому ваша начальная линия для добавления трех детей происходит после того, как вы установили слушателя, поэтому ваш обратный вызов называется 3 раза. (создание 3 диалоговых окон).

Переместить эту линию вне из по щелчку:

query = mDatabase.child("child").child(anotherChild).child("yetAnotherChild"); 

Затем, когда вы добавляете ниже слушателя (внутри по щелчку) оно должно быть в порядке

query.orderByChild("someChild").addChildEventListener(new ChildEventListener() { 
        @Override 
        public void onChildAdded(DataSnapshot dataSnapshot, String s) { 
+0

это не работает. см. обновленный вопрос. все еще получая 3 диалога. –

1

Вы можете использовать Firebase Запросы к ограничить данные, загружаемые слушателем.

query.orderByChild("someChild").limitToLast(1).addChildEventListener(... 
1

@Blundell имеет представление о решении вашей проблемы. Я просто хочу предложить вам аналогичный подход с addValueEventListener.

The value event listener will fire once for the initial state of the data, and then again every time the value of that data changes.

Вы должны выйти на firebase запрос от onClick функции. Таким образом, ваш запрос может выглядеть следующим образом ..

// Declare the variable names as public 
private String names[]; 

private void addFirebaseListener() { 
    ref = mDatabase.child("child").child(anotherChild).child("yetAnotherChild"); 
    ref. userRef.addListenerForSingleValueEvent(new ValueEventListener() { 
     @Override 
     public void onDataChange(DataSnapshot snapshot) { 
      Map<String, String> newD = (Map<String, String>) dataSnapshot.getValue(); 

      ArrayList<String> l = new ArrayList<String>(); 
      l.add(newD.get("lol").substring(30)); 

      names[] = l.toArray(new String[0]); 

      // Call notifyDataSetChanged each time your array gets updated 
      adapter.notifyDataSetChanged(); 
     } 

     @Override public void onCancelled(FirebaseError error) { } 
    }); 
} 

Теперь напишем функцию, чтобы показать ListView в AlertDialog

// Declare the adapter as public and initialize it with null 
private ArrayAdapter<String> adapter = null; 

private void showListInDialog() { 
    AlertDialog.Builder alertDialog = new AlertDialog.Builder(Activity.this); 
    LayoutInflater inflater = getLayoutInflater(); 
    View convertView = inflater.inflate(R.layout.dialog_list, null); 
    alertDialog.setView(convertView); 
    alertDialog.setTitle("title"); 
    ListView lv = (ListView) convertView.findViewById(R.id.lv); 

    if(adapter == null) 
     adapter = new ArrayAdapter<String>(getBaseContext(), android.R.layout.simple_list_item_1, names); 

    // Now set the adapter 
    lv.setAdapter(adapter); 

    alertDialog.setPositiveButton("OK", new DialogInterface.OnClickListener() { 
     @Override 
     public void onClick(DialogInterface dialogInterface, int i) { 
      alertDialog.dismiss(); 
     } 
    }); 

    alertDialog.show(); 
} 

Теперь внутри onCreate функции вы должны установить Firebase слушателя, а затем установить onClick функция как это.

uProfile.setOnClickListener(new View.OnClickListener() { 
    @Override 
    public void onClick(View view) { 
     showListInDialog(); 
    } 
}); 
+0

см. Отредактированный вопрос .. он показывает, почему я не могу использовать 'valueEventListener()'. –

+0

ответьте пожалуйста .. спасибо. –

+0

'Я не могу использовать valueEventListener() здесь, поскольку у меня нет доступа к inaccessibleChild' - Это не совсем понятно. Почему вы хотите прочитать некоторые данные, когда у вас есть недоступный узел? –

1

@Hammad Попробуйте этот модифицированный код, основываясь на ваших требованиях.

query = mDatabase.child("child").child(anotherChild).child("yetAnotherChild"); 

    AlertDialog alertDialog; 
    ArrayList<String> l; 

    uProfile.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      query.orderByChild("someChild").addChildEventListener(new ChildEventListener() { 
       @Override 
       public void onChildAdded(DataSnapshot dataSnapshot, String s) { 
        if (dataSnapshot != null) { 

         Map<String, String> newD = (Map<String, String>) dataSnapshot.getValue(); 

    if(l == null) { 
         l = new ArrayList<String>(); 
    } 
         l.add(newD.get("lol").substring(30)); 

    String names[] = new String[l.size()]; 
    for(int length=0; length < l.size(); l++) { 
     names[length] = l.get(length); 
    } 

    if(alertDialog == null) { 
         alertDialog = new AlertDialog.Builder(Activity.this).create(); 
         LayoutInflater inflater = getLayoutInflater(); 
         View convertView = inflater.inflate(R.layout.dialog_list, null); 
         alertDialog.setView(convertView); 
         alertDialog.setTitle("title"); 
         ListView lv = (ListView) convertView.findViewById(R.id.lv); 

    } ArrayAdapter<String> adapter = new ArrayAdapter<String>(getBaseContext(), android.R.layout.simple_list_item_1, names); 
         lv.setAdapter(adapter); 

         alertDialog.setPositiveButton("OK", new DialogInterface.OnClickListener() { 
          @Override 
          public void onClick(DialogInterface dialogInterface, int i) { 

          } 
         }); 

if(!alertDialog.isShowing()) { 
         alertDialog.show(); 
} 
        } else { 
         Toast.makeText(getBaseContext(), "NULLLLL", Toast.LENGTH_SHORT).show(); 
        } 
       } 

       ... 
       ... 
      }); 

     } 
    }); 
+0

получение этой ошибки: 'java.lang.IllegalStateException: указанный ребенок уже имеет родителя. Сначала вы должны вызвать removeView() для родительского родителя. 'При нажатии' uProfile'. –

+0

Я отредактировал свой ответ и добавил if (! AlertDialog.isShowing()). Если какой-либо вопрос, пожалуйста, укажите точную строку вопроса. – ChaitanyaAtkuri

+0

по-прежнему та же проблема ... здесь в строке 'alertDialog.show();' –

3

Предел Put при использовании valueEventListener или addChildEventListener. например,

int limit = 100; 
databaseRef.child("chats").limitToLast(limit).addValueEventListener(listener); 

И всегда удаляйте слушателя, когда вы закончили работу, связанную с firebase. например,

databaseRef.child("chats").limitToLast(limit).removeEventListener(listener); 

Спасибо.

1
ChildEventListener childEventListener = new ChildEventListener() { 
@Override 
public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) { 
    Log.d(TAG, "onChildAdded:" + dataSnapshot.getKey()); 

/**

Получить списки элементов или слушать дополнения к списку элементов. Этот обратный вызов запускается один раз для каждого существующего дочернего элемента, а затем снова каждый раз, когда новый ребенок добавляется к указанному пути. DataSnapshot, переданный слушателю, содержит данные нового ребенка.

**/

} 

@Override 
public void onChildChanged(DataSnapshot dataSnapshot, String previousChildName) { 
    Log.d(TAG, "onChildChanged:" + dataSnapshot.getKey()); 
} 

@Override 
public void onChildRemoved(DataSnapshot dataSnapshot) { 
    Log.d(TAG, "onChildRemoved:" + dataSnapshot.getKey()); 
} 

@Override 
public void onChildMoved(DataSnapshot dataSnapshot, String previousChildName) { 
    Log.d(TAG, "onChildMoved:" + dataSnapshot.getKey()); 
} 

@Override 
public void onCancelled(DatabaseError databaseError) { 
} 

}; ref.addChildEventListener (childEventListener); Использование ChildEventListener onChildAdded - это вызов на каждого дочернего вас в этом узле. Означает, что ваш код запускается 3 раза, поэтому диалоговое окно 3 раза.

Это проблема Таким образом, решение:

While using a ChildEventListener is the recommended way to read lists of data, there are situations where attaching a ValueEventListener to a list reference is useful.

Attaching a ValueEventListener to a list of data will return the entire list of data as a single DataSnapshot, which you can then loop over to access individual children.

Even when there is only a single match for the query, the snapshot is still a list; it just contains a single item. To access the item, you need to loop over the result:

inaccessibleChild.addValueEventListener(new ValueEventListener() { 
@Override 
public void onDataChange(DataSnapshot dataSnapshot) { 
    for (DataSnapshot postSnapshot: dataSnapshot.getChildren()) { 
     //here you can access the each child of that node. 
    } 
} 

@Override 
public void onCancelled(DatabaseError databaseError) { 
    // Getting Post failed, log a message 
    Log.w(TAG, "loadPost:onCancelled", databaseError.toException()); 
    // ... 
} 

});

2

Создать и показать AlertDialog перед вызовом .addChildEventListener()

Затем используйте внутри addChildEventListener называют notifyDatasetChanged() после того, как вы загрузили необходимые данные. Не создавайте AlertDialog внутри addChildEventListener

 Смежные вопросы

  • Нет связанных вопросов^_^