我从FirebaseDatabase
获取一些数据,然后将它们放入array
,然后尝试在自定义List
中的AlertDialog
中显示它们}。
以下是代码:
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
的列表中,而是在 3 >中逐个显示strong>单独AlertDialog
。
这里出了什么问题?
请告诉我。
答案 0 :(得分:3)
Firebase事务是异步的,因此在设置侦听器后会发生添加3个孩子的初始行,因此您的回调会被调用3次。 (制作3个对话框)。
将此行移到点击之外:
query = mDatabase.child("child").child(anotherChild).child("yetAnotherChild");
然后当你添加下面的监听器时(在点击内部)它应该没问题
query.orderByChild("someChild").addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
答案 1 :(得分:3)
使用<div id="app"><!-- vue mounted at this div -->
<div v-cloak>
<!-- your actual code / content -->
</div>
</div>
或[v-cloak] { display: none; }
时设置限制。像这样,
valueEventListener
当你完成与firebase相关的工作后,总是删除监听器。像这样,
addChildEventListener
感谢。
答案 2 :(得分:2)
在调用之前创建并显示AlertDialog .addChildEventListener()
然后在下载相应数据后使用addChildEventListener调用notifyDatasetChanged()。不要在addChildEventListener
中创建AlertDialog答案 3 :(得分:1)
您可以使用Firebase查询来限制侦听器下载的数据。
query.orderByChild("someChild").limitToLast(1).addChildEventListener(...
答案 4 :(得分:1)
@Blundell有解决问题的洞察力。我只是想建议你使用addValueEventListener
的类似方法。
值事件侦听器将针对初始状态触发一次 数据,然后每当数据的值发生变化时再次出现。
您需要从onClick
函数中移出firebase查询。所以你的查询可能看起来像这样..
// 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();
}
});
答案 5 :(得分: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();
}
}
...
...
});
}
});
答案 6 :(得分: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次。
这是问题 所以解决方案是:
虽然建议使用ChildEventListener来读取数据列表,但有时会将ValueEventListener附加到列表引用中。
将ValueEventListener附加到数据列表会将整个数据列表作为单个DataSnapshot返回,然后您可以循环访问以访问各个子项。
即使查询只有一个匹配项,快照仍然是一个列表;它只包含一个项目。要访问该项目,您需要循环结果:
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());
// ...
}
});
答案 7 :(得分: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();
}
});
无论如何,我要感谢所有回答这个问题的人。
和平。