Je crée une application de gestionnaire de tâches. Et j'ai un problème avec l'affichage de ces tâches dans ExpandableListView, je l'utilise car chaque tâche peut avoir des sous-tâches. Voici ma structure de base de données :

Structure de la base de données.

L'adaptateur ExpandableListView peut bien fonctionner. Mais j'ai un problème avec la lecture des données de firebase dans la méthode fillData().

Activity avec 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) {

            }
        });
    }
}

Adaptateur 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;
}

}

0
Vadim PAnkiv 8 oct. 2020 à 14:59

1 réponse

Meilleure réponse

D'après ce que je peux voir, le code pertinent dans votre question est:

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) {
    }
});

Votre code attache un écouteur à /Tasks, puis boucle sur ses nœuds enfants et obtient l'enfant Tasks de chacun de ces nœuds enfants. Pourtant, si nous regardons la structure de votre base de données, il n'y a pas de sous-nœud Tasks sous chaque tâche. Cela se traduit donc probablement par une liste d'éléments vides, une fois pour chaque nœud enfant de /Tasks


Si vous souhaitez afficher la clé de chaque nœud enfant de /Tasks (donc make a aolication et Shoping dans votre capture d'écran), vous devrez utiliser le getKey() de chaque enfant nœud:

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()
    }
});

Si vous souhaitez afficher toutes les valeurs sous le Subtasks de chaque nœud enfant, vous devrez ajouter une autre boucle imbriquée pour cela :

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()
    }
});
1
Frank van Puffelen 8 oct. 2020 à 14:29