Message from "Empty Child" on an Expandable Listview on Android

Asked

Viewed 102 times

2

I want to create a statement to the user stating that a Group of an Expansible Listview does not contain any Child (That the group is empty) as in the image below.

inserir a descrição da imagem aqui

Searching the net, I noticed some methods, but I found it very confusing because it is in another language. I’m trying it in the code below, but I’m not getting it. For when the group is empty, my listview Expandable does not inflate the custom layout.

import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Build;
import android.support.annotation.RequiresApi;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;

public class ExpandableListAdapter extends BaseExpandableListAdapter {

    private List<Construtor_Perfil_Usuario> modelList;
    private HashMap<Construtor_Perfil_Usuario,List<Construtor_Medicamentos>> listHashMap;
    private Context context;

    ExpandableListAdapter(Context context, List<Construtor_Perfil_Usuario> modelList, HashMap<Construtor_Perfil_Usuario, List<Construtor_Medicamentos>> listHashMap) {

        this.modelList = modelList;
        this.listHashMap = listHashMap;
        this.context = context;
    }

    @Override
    public int getGroupCount() {
        return modelList.size();
    }

    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    @Override
    public int getChildrenCount(int i) {
        return Objects.requireNonNull(listHashMap.get(modelList.get(i))).size();
    }

    @Override
    public Object getGroup(int i) {
        return modelList.get(i);
    }

    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    @Override
    public Object getChild(int i, int i1) {

        return Objects.requireNonNull(listHashMap.get(modelList.get(i))).get(i1);

    }

    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    List<String> getValues(int groupPosition, int childPosition){

        List<String> listStrings = new ArrayList<>();
        listStrings.add(modelList.get(groupPosition).getNomeUsuario());
        listStrings.add(Objects.requireNonNull(listHashMap.get(modelList.get(groupPosition))).get(childPosition).getNome());
        listStrings.add(Objects.requireNonNull(listHashMap.get(modelList.get(groupPosition))).get(childPosition).getTipo());
        listStrings.add(Objects.requireNonNull(listHashMap.get(modelList.get(groupPosition))).get(childPosition).getStatus());
        listStrings.add(Objects.requireNonNull(listHashMap.get(modelList.get(groupPosition))).get(childPosition).getDosagem());
        listStrings.add(Objects.requireNonNull(listHashMap.get(modelList.get(groupPosition))).get(childPosition).getEstoque());
        listStrings.add(Objects.requireNonNull(listHashMap.get(modelList.get(groupPosition))).get(childPosition).getUso());
        listStrings.add(Objects.requireNonNull(listHashMap.get(modelList.get(groupPosition))).get(childPosition).getDataInicial());
        listStrings.add(Objects.requireNonNull(listHashMap.get(modelList.get(groupPosition))).get(childPosition).getDataFinal());
        listStrings.add(Objects.requireNonNull(listHashMap.get(modelList.get(groupPosition))).get(childPosition).getHoraInicial());
        listStrings.add(Objects.requireNonNull(listHashMap.get(modelList.get(groupPosition))).get(childPosition).getHoraIntervalo());

        return listStrings;
    }

    @Override
    public long getGroupId(int i) {
        return i;
    }

    @Override
    public long getChildId(int i, int i1) {
        return i1;
    }

    @Override
    public boolean hasStableIds() {
        return false;
    }

    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    @SuppressLint("InflateParams")
    @Override
    public View getGroupView(int groupPosition, boolean b, View convertView, ViewGroup viewGroup) {

        String string = modelList.get(groupPosition).getNomeUsuario();

        if(convertView == null){
            LayoutInflater inflater = (LayoutInflater)this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = Objects.requireNonNull(inflater).inflate(R.layout.expansive_listview_group,null); }


        TextView textView = convertView.findViewById(R.id.lblListHeader);
        textView.setText(string);

        TextView textName = convertView.findViewById(R.id.textViewInfoSex);
        if (modelList.get(groupPosition).getSexoUsuario().contains("Feminino")){
            textName.setBackgroundResource(R.drawable.shape_oval_pink);
        }else{
            textName.setBackgroundResource(R.drawable.shape_oval_blue);
        }

        String subString = string.substring(0, 1);
        textName.setText(subString);

        return convertView;
    }

    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    @SuppressLint("InflateParams")
    @Override
    public View getChildView(int groupPosition, int childPosition, boolean b, View convertView, ViewGroup viewGroup) {

        if (getChildrenCount(groupPosition) != 0) {

            String nomeMedicamento = Objects.requireNonNull(listHashMap.get(modelList.get(groupPosition))).get(childPosition).getNome();
            String statusMedicamento = Objects.requireNonNull(listHashMap.get(modelList.get(groupPosition))).get(childPosition).getStatus();
            String estoqueMedicamento = Objects.requireNonNull(listHashMap.get(modelList.get(groupPosition))).get(childPosition).getEstoque();
            String dosagemMedicamento = Objects.requireNonNull(listHashMap.get(modelList.get(groupPosition))).get(childPosition).getDosagem();


            if (convertView == null) {

                LayoutInflater inflater = (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                convertView = Objects.requireNonNull(inflater).inflate(R.layout.expansive_listview_child, null);

            }

            TextView textView = convertView.findViewById(R.id.lblListItem);
            textView.setText(nomeMedicamento);

            ImageView imageView = convertView.findViewById(R.id.imageView_status_medicamento);

            if (statusMedicamento.equals("ATIVO")) {
                float result = Float.parseFloat(estoqueMedicamento) / Float.parseFloat(dosagemMedicamento);
                if (result <= 3 && result > 1) {
                    imageView.setBackgroundResource(R.drawable.ic_atencion_yellow);
                } else if (result <= 1 && result >= 0) {
                    imageView.setBackgroundResource(R.drawable.ic_atencion_red);
                } else {
                    imageView.setBackgroundResource(R.drawable.ic_alarm_on);
                }
            } else if (statusMedicamento.equals("DESATIVADO")) {
                imageView.setBackgroundResource(R.drawable.ic_alarm_off);
            }

        }else{

            if (convertView == null) {

                LayoutInflater inflater = (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                convertView = Objects.requireNonNull(inflater).inflate(R.layout.expansive_listview_childempty, null);

            }

        }

        return convertView;
    }

    @Override
    public boolean isChildSelectable(int i, int i1) {
        return true;
    }


}

I don’t understand what I’m doing wrong.

1 answer

1


Friend in your code is almost ready.
See, the method that creates the Chield elements is the getChildView, and in it you already check if Chield is non-zero (if it is not empty):

if (getChildrenCount(groupPosition) != 0) ...

You already have the else to deal with when you don’t have Chield, but you stopped there, only put the code to deal with when convertView is null (which in this case is not only Chield which is empty):

}else{
    if (convertView == null) {
        LayoutInflater inflater = (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = Objects.requireNonNull(inflater).inflate(R.layout.expansive_listview_childempty, null);
    }
}

So what can be done is inside this else create a Chield with the message "Chield Empty" as you need, for example, the code below would be inside theelse which is in its method getChieldView:

}else{
    if (convertView == null) {
        LayoutInflater inflater = (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = Objects.requireNonNull(inflater).inflate(R.layout.expansive_listview_childempty, null);
    }

    TextView textView = convertView.findViewById(R.id.lblListItem);
    textView.setText("Chield Vazio");
    ImageView imageView = convertView.findViewById(R.id.imageView_status_medicamento);
    imageView.setBackgroundResource(R.drawable.ic_alarm_off);
}

Edited
In the test I created I found that the app broke when clicking on a group that didn’t have Child, and the problem wasn’t in the method getChildView but in the getChildrenCount. This method returns the number of children that that group has, if you pass a group that has no children, it does not return 0, from the error, because it is the same thing as taking the position greater than a vector.
Below is the example code:

package com.example.myapplication;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.TextView;

public class ExpandableListViewAdapter extends BaseExpandableListAdapter {

    String groupNames[] = {"Aluno1","Aluno2","Aluno3"};

    String[][] chieldNames= {{"Chield do Aluno1"},{"Chiel do aluno2"}};

    Context context;

    public ExpandableListViewAdapter(Context context){
        this.context = context;
    }

    @Override
    public int getGroupCount() {
        return groupNames.length;
    }

    @Override
    public int getChildrenCount(int i) {
        if(i>chieldNames.length-1){
            //Se o group não tiver filho, retorne 1,
            // se retornar 0 o grupo vai aparecer mas não vai expandir
            return 1;
        }
        return chieldNames[i].length;
    }

    @Override
    public Object getGroup(int i) {
        return groupNames[i];
    }

    @Override
    public Object getChild(int i, int i1) {

        return chieldNames[1][i1];
    }

    @Override
    public long getGroupId(int i) {
        return i;
    }

    @Override
    public long getChildId(int i, int i1) {
        return i1;
    }

    @Override
    public boolean hasStableIds() {
        return false;
    }

    @Override
    public View getGroupView(int i, boolean b, View view, ViewGroup viewGroup) {
        TextView txtv = new TextView(context);
        txtv.setText(groupNames[i]);
        txtv.setPadding(100,0,0,0);
        txtv.setTextSize(50);
        return txtv;
    }

    @Override
    public View getChildView(int i, int i1, boolean b, View convertView, ViewGroup viewGroup) {

        TextView txtv = new TextView(context);

        //Repare que aqui, para pegar se o grupo não tem filho, não utilizei o método
        // getChildrenCount, pois editamos o mesmo para retornar 1 no lugar de 0
        if (!(i>chieldNames.length-1)) {
            txtv.setText(chieldNames[i][i1]);
            txtv.setPadding(100, 0, 0, 0);
            txtv.setTextSize(30);
        }else{

            //layout.chield_empty é só um linearlayout simples com um único textview dentro
            // escrito "chield vazio!!"
            LayoutInflater layoutInflater = (LayoutInflater) this.context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

            convertView = layoutInflater.inflate(R.layout.chield_empty, null);

            //Infla e retorna o mesmo
            return convertView;
        }
        return txtv;
    }

    @Override
    public boolean isChildSelectable(int i, int i1) {
        return false;
    }
}
  • Sorry friend but I’ve tried this too... The big problem I’m facing is that when there are no children (Childs) my "layout_personalizado_empty" does not inflate.

  • Inside this my custom layout already exists a custom Textview with the message = "Nothing registered for the user". So for me it is not necessary to do this dynamically with setText()

  • What is stranger to me is that it does not inflate at all. The layout with the message of Empty

  • @Andréalas understood, but tonight I will create a test to try to reproduce what you are trying to do and I tell you, because I never created a layout just for this, I usually return only a textview even.

  • Perfect my friend. I hope you can help me... I’ll be waiting for you....

  • Friend if you can give an "UP" on the question please for me to gain a little reputation I will thank you very much because I spent a lot on this question. Consider also that this issue may not only be a problem for me and others may also have in the future. Also note that you have no similar question in Stackoverflow....

  • @Andréalas opa, beauty!!

  • @ Murilo Portugal Hi champion managed to do the project? If you can, send me the code running.... You can make a simple list and send me. Then I compare the code and see what I did wrong.... If you do this for me I’ll give you the reward.... vlw hugs

  • @Andréalas, yes I did, I will edit the answer and put the code!

  • Great my friend I’ll be waiting...

  • @Andrea, I’ve already posted the code and commented to make it better for you to understand

  • Great my friend... I will check the code here. But for having been interested in helping me, I will give you the reward..... Thank you and good work. I’ll enter your answer in my app and probably tomorrow I’ll give you an answer.

  • Thank you @Andréalas, and in need just call!

Show 8 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.