使用来自 firebase 的数据创建 ExpandableListView
Creating ExpandableListView with data from firebase
我正在创建一个任务管理器应用程序。我在 ExpandableListView
中显示这些任务时遇到问题,我使用它是因为每个任务都可能有子任务。这是我的数据库结构:
.
ExpandableListView 适配器可能运行良好。但是我在 fillData()
方法中从 firebase 读取数据时遇到问题。
Activity
与 ExpandableListView
:
public class Tasks extends AppCompatActivity {
ExpandableListView expandableListView;
CustomExpandableListAdapter expandableListAdapter;
List<String> tasks;
Map<String, List<String>> subtasks;
private FirebaseDatabase firebasedatabase;
private DatabaseReference databaseReference;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tasks);
BottomNavigationView bottomNav = findViewById(R.id.bottom_nav);
bottomNav.setSelectedItemId(R.id.tasks);
expandableListView = (ExpandableListView) findViewById(R.id.tasks_list);
firebasedatabase = FirebaseDatabase.getInstance();
databaseReference = firebasedatabase.getReference("Tasks");
fillData();
expandableListAdapter = new CustomExpandableListAdapter(this, tasks, subtasks);
expandableListView.setAdapter(expandableListAdapter);
bottomNav.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()){
case R.id.notes:
startActivity(new Intent(getApplicationContext(), Notes.class));
overridePendingTransition(0,0);
return true;
case R.id.tasks:
return true;
case R.id.goals:
startActivity(new Intent(getApplicationContext(), Goals.class));
overridePendingTransition(0,0);
return true;
case R.id.statistics:
startActivity(new Intent(getApplicationContext(), Statistics.class));
overridePendingTransition(0,0);
return true;
case R.id.add:
startActivity(new Intent(getApplicationContext(), Add.class));
overridePendingTransition(0,0);
return true;
}
return false;
}
});
}
public void fillData()
{
databaseReference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
if(tasks.size() > 0) tasks.clear();
for(DataSnapshot ds : dataSnapshot.getChildren())
{
String taskName = (String) ds.child("Tasks").getValue();
tasks.add(taskName);
}
expandableListAdapter.notifyDataSetChanged();
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}
}
ExpandableListView 适配器:
public class CustomExpandableListAdapter extends BaseExpandableListAdapter {
private Context context;
private List<String> listHeader;
private Map<String, List<String>> listChildren;
public CustomExpandableListAdapter(Context context, List<String> listHeader, Map<String, List<String>> listChildren){
this.context = context;
this.listHeader = listHeader;
this.listChildren = listChildren;
}
@Override
public int getGroupCount() {
return this.listHeader.size();
}
@Override
public int getChildrenCount(int groupPosition) {
return this.listChildren.get(listHeader.get(groupPosition)).size();
}
@Override
public Object getGroup(int groupPosition) {
return this.listHeader.get(groupPosition);
}
@Override
public Object getChild(int groupPosition, int childPosition) {
return this.listChildren.get(this.listHeader.get(groupPosition));
}
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
@Override
public boolean hasStableIds() {
return false;
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
String header = (String) getGroup(groupPosition);
if(convertView == null)
{
LayoutInflater inflater = (LayoutInflater) context.getSystemService(context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.list_view_header, null);
}
TextView headerOfGroup = (TextView) convertView.findViewById(R.id.header_text);
headerOfGroup.setText(header);
return convertView;
}
@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
String child = (String) getChild(groupPosition, childPosition);
if(convertView == null)
{
LayoutInflater inflater = (LayoutInflater) context.getSystemService(context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.list_view_child, null);
}
TextView childText = (TextView) convertView.findViewById(R.id.child_text);
childText.setText(child);
return convertView;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
}
据我所知,你问题中的相关代码是:
firebasedatabase = FirebaseDatabase.getInstance();
databaseReference = firebasedatabase.getReference("Tasks");
databaseReference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
if(tasks.size() > 0) tasks.clear();
for(DataSnapshot ds : dataSnapshot.getChildren())
{
String taskName = (String) ds.child("Tasks").getValue();
tasks.add(taskName);
}
expandableListAdapter.notifyDataSetChanged();
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
您的代码将侦听器附加到 /Tasks
,然后遍历其子节点,并获取每个子节点的 Tasks
子节点。但是,如果我们查看您的数据库结构,每个任务下都没有 Tasks
子节点。所以这可能会导致空项目列表,每个子节点一次 /Tasks
如果你想显示 /Tasks
的每个子节点的键(所以你的屏幕截图中 make a aolication
和 Shoping
),你需要使用 getKey()
每个子节点:
firebasedatabase = FirebaseDatabase.getInstance();
databaseReference = firebasedatabase.getReference("Tasks");
databaseReference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
if(tasks.size() > 0) tasks.clear();
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String taskName = ds.getKey();
tasks.add(taskName);
}
expandableListAdapter.notifyDataSetChanged();
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
throw databaseError.toException()
}
});
如果要显示每个子节点 Subtasks
下的所有值,则需要为此添加另一个嵌套循环:
firebasedatabase = FirebaseDatabase.getInstance();
databaseReference = firebasedatabase.getReference("Tasks");
databaseReference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
if(tasks.size() > 0) tasks.clear();
for(DataSnapshot taskSnapshot: dataSnapshot.getChildren()) {
DataSnapshot subtasksSnapshot = taskSnapshot.child("Subtasks");
for(DataSnapshot subtaskSnapshot: subtasksSnapshot.getChildren()) {
String taskName = subtaskSnapshot.getValue(String.class);
tasks.add(taskName);
}
}
expandableListAdapter.notifyDataSetChanged();
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
throw databaseError.toException()
}
});
我正在创建一个任务管理器应用程序。我在 ExpandableListView
中显示这些任务时遇到问题,我使用它是因为每个任务都可能有子任务。这是我的数据库结构:
ExpandableListView 适配器可能运行良好。但是我在 fillData()
方法中从 firebase 读取数据时遇到问题。
Activity
与 ExpandableListView
:
public class Tasks extends AppCompatActivity {
ExpandableListView expandableListView;
CustomExpandableListAdapter expandableListAdapter;
List<String> tasks;
Map<String, List<String>> subtasks;
private FirebaseDatabase firebasedatabase;
private DatabaseReference databaseReference;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tasks);
BottomNavigationView bottomNav = findViewById(R.id.bottom_nav);
bottomNav.setSelectedItemId(R.id.tasks);
expandableListView = (ExpandableListView) findViewById(R.id.tasks_list);
firebasedatabase = FirebaseDatabase.getInstance();
databaseReference = firebasedatabase.getReference("Tasks");
fillData();
expandableListAdapter = new CustomExpandableListAdapter(this, tasks, subtasks);
expandableListView.setAdapter(expandableListAdapter);
bottomNav.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()){
case R.id.notes:
startActivity(new Intent(getApplicationContext(), Notes.class));
overridePendingTransition(0,0);
return true;
case R.id.tasks:
return true;
case R.id.goals:
startActivity(new Intent(getApplicationContext(), Goals.class));
overridePendingTransition(0,0);
return true;
case R.id.statistics:
startActivity(new Intent(getApplicationContext(), Statistics.class));
overridePendingTransition(0,0);
return true;
case R.id.add:
startActivity(new Intent(getApplicationContext(), Add.class));
overridePendingTransition(0,0);
return true;
}
return false;
}
});
}
public void fillData()
{
databaseReference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
if(tasks.size() > 0) tasks.clear();
for(DataSnapshot ds : dataSnapshot.getChildren())
{
String taskName = (String) ds.child("Tasks").getValue();
tasks.add(taskName);
}
expandableListAdapter.notifyDataSetChanged();
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}
}
ExpandableListView 适配器:
public class CustomExpandableListAdapter extends BaseExpandableListAdapter {
private Context context;
private List<String> listHeader;
private Map<String, List<String>> listChildren;
public CustomExpandableListAdapter(Context context, List<String> listHeader, Map<String, List<String>> listChildren){
this.context = context;
this.listHeader = listHeader;
this.listChildren = listChildren;
}
@Override
public int getGroupCount() {
return this.listHeader.size();
}
@Override
public int getChildrenCount(int groupPosition) {
return this.listChildren.get(listHeader.get(groupPosition)).size();
}
@Override
public Object getGroup(int groupPosition) {
return this.listHeader.get(groupPosition);
}
@Override
public Object getChild(int groupPosition, int childPosition) {
return this.listChildren.get(this.listHeader.get(groupPosition));
}
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
@Override
public boolean hasStableIds() {
return false;
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
String header = (String) getGroup(groupPosition);
if(convertView == null)
{
LayoutInflater inflater = (LayoutInflater) context.getSystemService(context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.list_view_header, null);
}
TextView headerOfGroup = (TextView) convertView.findViewById(R.id.header_text);
headerOfGroup.setText(header);
return convertView;
}
@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
String child = (String) getChild(groupPosition, childPosition);
if(convertView == null)
{
LayoutInflater inflater = (LayoutInflater) context.getSystemService(context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.list_view_child, null);
}
TextView childText = (TextView) convertView.findViewById(R.id.child_text);
childText.setText(child);
return convertView;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
}
据我所知,你问题中的相关代码是:
firebasedatabase = FirebaseDatabase.getInstance();
databaseReference = firebasedatabase.getReference("Tasks");
databaseReference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
if(tasks.size() > 0) tasks.clear();
for(DataSnapshot ds : dataSnapshot.getChildren())
{
String taskName = (String) ds.child("Tasks").getValue();
tasks.add(taskName);
}
expandableListAdapter.notifyDataSetChanged();
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
您的代码将侦听器附加到 /Tasks
,然后遍历其子节点,并获取每个子节点的 Tasks
子节点。但是,如果我们查看您的数据库结构,每个任务下都没有 Tasks
子节点。所以这可能会导致空项目列表,每个子节点一次 /Tasks
如果你想显示 /Tasks
的每个子节点的键(所以你的屏幕截图中 make a aolication
和 Shoping
),你需要使用 getKey()
每个子节点:
firebasedatabase = FirebaseDatabase.getInstance();
databaseReference = firebasedatabase.getReference("Tasks");
databaseReference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
if(tasks.size() > 0) tasks.clear();
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String taskName = ds.getKey();
tasks.add(taskName);
}
expandableListAdapter.notifyDataSetChanged();
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
throw databaseError.toException()
}
});
如果要显示每个子节点 Subtasks
下的所有值,则需要为此添加另一个嵌套循环:
firebasedatabase = FirebaseDatabase.getInstance();
databaseReference = firebasedatabase.getReference("Tasks");
databaseReference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
if(tasks.size() > 0) tasks.clear();
for(DataSnapshot taskSnapshot: dataSnapshot.getChildren()) {
DataSnapshot subtasksSnapshot = taskSnapshot.child("Subtasks");
for(DataSnapshot subtaskSnapshot: subtasksSnapshot.getChildren()) {
String taskName = subtaskSnapshot.getValue(String.class);
tasks.add(taskName);
}
}
expandableListAdapter.notifyDataSetChanged();
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
throw databaseError.toException()
}
});