ExpandableListView always returns 0 when counting the groups

1

I'm listing blocks which have activities. Everything works perfectly, except that the group counter does not work, it always returns 0. The data is charged from an external server with volley.

Activity my blocks

package cl.saval.emc.emc;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ExpandableListView;
import android.widget.Toast;

import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

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

public class MyBlocksActivity extends BaseActivity
{
    private ExpandableListView listViewMyCoursesBlocks;
    private ExpandableListAdapter listAdapter;
    private List<String> listDataHeader = new ArrayList<>();
    private HashMap<String,List<Activity>> listHash = new HashMap<>();
    private Course myCourse;

@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_my_blocks);

    Intent i = getIntent();
    myCourse = i.getExtras().getParcelable("myCourse");

    listViewMyCoursesBlocks = (ExpandableListView)findViewById(R.id.listViewMyCoursesBlocks);

    //Init Data
    initData();

    listAdapter = new ExpandableListAdapter(getApplicationContext(),listDataHeader,listHash);
    listViewMyCoursesBlocks.setAdapter(listAdapter);


    //listViewMyCoursesBlocks.setGroupIndicator(null);

    //Solo un grupo, se muestran todas las actividades por defecto
    Toast.makeText(getApplicationContext(), "size: " + listAdapter.getGroupCount(), Toast.LENGTH_SHORT).show(); //-> here always show 0
    /*if( listAdapter.getGroupCount() == 1 ){
        //listViewMyCoursesBlocks.e;
    }*/

    listViewMyCoursesBlocks.setOnChildClickListener(new ExpandableListView.OnChildClickListener()
    {
        @Override
        public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id)
        {
            Activity myActivity = (Activity)parent.getExpandableListAdapter().getChild(groupPosition,childPosition);
            if( myActivity.getIsBlocked() == 0 )
            {
                Intent i = new Intent(getApplicationContext(), MyClassActivity.class);
                i.putExtra("myActivity", myActivity);
                startActivity(i);
                return true;
            }
            return  false;
        };
    });
}
public void initData()
{
    //listDataHeader  = new ArrayList<>();
    //listHash = new HashMap<>();

    final String url   = Globals.APIACTIVIDADES_URL;
    RequestQueue queue = Volley.getInstance(this).getRequestQueue();
    StringRequest req = new StringRequest(Request.Method.POST, url, new Response.Listener<String>()
    {
        @Override
        public void onResponse(String response)
        {
            try
            {
                JSONObject JSONresponse = new JSONObject(response);
                if ( !JSONresponse.has("error") )
                {
                    int actividadesArr_length = 0;
                    int bloquesActividadesArr_length = 0;
                    int bloquesArr_length = 0;

                    if ( JSONresponse.has("actividades") && JSONresponse.get("actividades") instanceof JSONArray )
                    {
                        JSONArray actividadesArr = JSONresponse.getJSONArray("actividades");
                        actividadesArr_length = actividadesArr.length();

                        listDataHeader.add("BLOQUE I");

                        List<Activity> actividades = new ArrayList<>();

                        for (int i = 0; i < actividadesArr_length; i++)
                        {
                            JSONObject activity = new JSONObject(actividadesArr.getString(i));
                            Integer id   = activity.getInt("id");
                            String title = activity.getString("titulo");
                            String titlePref = activity.getString("tituloprefijo");
                            String teacher = activity.getString("expositores");
                            Integer isAccomplished = activity.getInt("cumplida");
                            Integer isBlocked = activity.getInt("bloqueo");
                            Integer hvVideo = activity.getInt("tienevideo");

                            actividades.add(new Activity(id, titlePref, title, teacher, isAccomplished, isBlocked, hvVideo));
                        }
                        listHash.put(listDataHeader.get(0),actividades);
                    }
                    if ( JSONresponse.has("bloques") && JSONresponse.get("bloques") instanceof JSONArray )
                    {
                        JSONArray bloquesArr = JSONresponse.getJSONArray("bloques");
                        bloquesArr_length = bloquesArr.length();

                        int ini = 0;
                        if( actividadesArr_length > 0 ){
                            ini = 1;
                        }

                        int romanNumber = 1;
                        for (int i = ini; i < bloquesArr_length; i++)
                        {
                            JSONObject bloque = new JSONObject(bloquesArr.getString(i));
                            String titulo_bloque  = bloque.getString("titulo");

                            listDataHeader.add("BLOQUE " + RomanNumerals.toRoman(romanNumber) + ": " + titulo_bloque);

                            List<Activity> actividades = new ArrayList<>();

                            if (bloque.has("actividades") && bloque.get("actividades") instanceof JSONArray)
                            {
                                JSONArray actividadesArr = bloque.getJSONArray("actividades");
                                bloquesActividadesArr_length = actividadesArr.length();

                                for (int j = 0; j < bloquesActividadesArr_length; j++)
                                {
                                    JSONObject activity = new JSONObject(actividadesArr.getString(j));

                                    Integer id   = activity.getInt("id");
                                    String title = activity.getString("titulo");
                                    String titlePref = activity.getString("tituloprefijo");
                                    String teacher = activity.getString("expositores");
                                    Integer isAccomplished = activity.getInt("cumplida");
                                    Integer isBlocked = activity.getInt("bloqueo");
                                    Integer hvVideo = activity.getInt("tienevideo");

                                    actividades.add(new Activity(id, titlePref, title, teacher, isAccomplished, isBlocked, hvVideo));
                                } //for actividades
                            }
                            romanNumber++;
                            listHash.put(listDataHeader.get(i),actividades);
                        } // for bloques
                    }
                    Toast.makeText(getApplicationContext(), "size: " + listAdapter.getGroupCount(), Toast.LENGTH_SHORT).show(); //-> here always show correct value
                }
                else
                {
                    JSONObject error = JSONresponse.getJSONObject("error");
                    Toast.makeText(getApplicationContext(), "Error: [" + error.getString("num") + "] " + error.getString("msg"), Toast.LENGTH_SHORT).show();
                }
            } catch (JSONException e)
            {
                e.printStackTrace();
                Toast.makeText(getApplicationContext(), "Error al recuperar sus datos", Toast.LENGTH_SHORT).show();
            }
            listAdapter.notifyDataSetChanged();
        }
    },
    new Response.ErrorListener()
    {
        @Override
        public void onErrorResponse(VolleyError error)
        {
            String message = "Error de conexión";
            if (!error.getMessage().isEmpty()) {
                message += ": [" + error.getMessage() + "]";
            }
            Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
        }
    })
    {
        @Override
        protected Map<String, String> getParams() {
            Map<String, String> params = new HashMap<>();
            HashMap<String, String> user = sesion.getUserDetails();

            // get user data from session
            params.put("sesion", user.get(sesion.getKEY_CODE()));
            params.put("curso", myCourse.getId().toString());
            return checkParams(params);
        }
    };
    queue.add(req);
}
}

Adapter my blocks

package cl.saval.emc.emc;

import android.content.Context;
import android.graphics.Typeface;
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 android.widget.Toast;

import com.squareup.picasso.Picasso;

import java.util.HashMap;
import java.util.List;

/**
 * Created by daniel on 16-02-17.
 * Modified by felipe on 2-02-17
*/

public class ExpandableListAdapter extends BaseExpandableListAdapter
{
    private Context context;
    private List<String> listDataHeader;
    private HashMap<String,List<Activity>> listHashMap;

    public ExpandableListAdapter(Context context, List<String> listDataHeader, HashMap<String, List<Activity>> listHashMap)
{
    this.context = context;
    this.listDataHeader = listDataHeader;
    this.listHashMap = listHashMap;
}
@Override
public int getGroupCount() { return listDataHeader.size(); }
@Override
public int getChildrenCount(int i) {
    return listHashMap.get(listDataHeader.get(i)).size();
}
@Override
public Object getGroup(int i) {
    return listDataHeader.get(i);
}
@Override
public Object getChild(int i, int i1) {
    return listHashMap.get(listDataHeader.get(i)).get(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)
{
    String headerTitle = (String)getGroup(i);
    if(view == null)
    {
        LayoutInflater inflater = (LayoutInflater)this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        view = inflater.inflate(R.layout.listexpandable_group,null);
    }
    TextView lblListHeader = (TextView) view.findViewById(R.id.lblListHeader);
    lblListHeader.setTypeface(null, Typeface.BOLD);
    lblListHeader.setText(headerTitle);
    return view;
}

@Override
public View getChildView(int i, int i1, boolean b, View view, ViewGroup viewGroup)
{
    Activity activity = (Activity)getChild(i,i1);
    //Toast.makeText(this.context, "texto: " + childText, Toast.LENGTH_LONG).show();
    if(view == null)
    {
        LayoutInflater inflater = (LayoutInflater)this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        view = inflater.inflate(R.layout.listexpandable_item_row,null);
    }

    ImageView classImage = (ImageView)view.findViewById(R.id.classImage);
    TextView classTitlePref = (TextView)view.findViewById(R.id.classTitlePref);
    TextView classTitle = (TextView)view.findViewById(R.id.classTitle);
    TextView classTeacher = (TextView)view.findViewById(R.id.classTeacher);

    if( activity.getIsAccomplished() == 1 ) {
        Picasso.with(context).load(R.drawable.list_expandable_circle_checked).into(classImage);
    }else {
        Picasso.with(context).load(R.drawable.list_expandable_circle).into(classImage);
    }

    classTitlePref.setText(activity.getTitlePref());
    classTitle.setText(activity.getTitle());
    classTeacher.setText(activity.getTeacher());
    return view;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
    return true;
}
}

Within volley always returns the exact number of blocks, but within the oncreate is always 0.

Any help?

    
asked by Makeyourmove 04.04.2017 в 19:49
source

2 answers

0

Inside the onResponse volley, the data is filled correctly. But outside of this can not be accessed, because he does not know "that is full".

So it occurred to me to do something that I saw when I started programming on android and it stayed like this:

//InitData
    initData(new VolleyCallback()
    {
        @Override
        public void onResponse(HashMap<String,List<Activity>> lHash, List<String> lDataHeader)
        {
            listAdapter = new ExpandableListAdapter(getApplicationContext(),lDataHeader,lHash);
            listAdapter.notifyDataSetChanged();
            listViewMyCoursesBlocks.setAdapter(listAdapter);

            if( listAdapter.getGroupCount() == 1 ){
                listViewMyCoursesBlocks.expandGroup(0);
            }
        }
    });

That's what I modified, add the parameter in the function and once the elements are filled I return them like this:

public void initData(final VolleyCallback callback)
{
    final List<String> listDataHeader  = new ArrayList<>();
    final HashMap<String,List<Activity>> listHash = new HashMap<>();

    final String url   = Globals.APIACTIVIDADES_URL;
    RequestQueue queue = Volley.getInstance(this).getRequestQueue();
    StringRequest req = new StringRequest(Request.Method.POST, url, new Response.Listener<String>()
    {
        @Override
        public void onResponse(String response)
        {
            try
            {
                JSONObject JSONresponse = new JSONObject(response);
                if ( !JSONresponse.has("error") )
                {
                    int actividadesArr_length = 0;
                    int bloquesActividadesArr_length = 0;
                    int bloquesArr_length = 0;

                    if ( JSONresponse.has("actividades") && JSONresponse.get("actividades") instanceof JSONArray )
                    {
                        JSONArray actividadesArr = JSONresponse.getJSONArray("actividades");
                        actividadesArr_length = actividadesArr.length();

                        listDataHeader.add("BLOQUE I");

                        List<Activity> actividades = new ArrayList<>();

                        for (int i = 0; i < actividadesArr_length; i++)
                        {
                            JSONObject activity = new JSONObject(actividadesArr.getString(i));
                            Integer id   = activity.getInt("id");
                            String title = activity.getString("titulo");
                            String titlePref = activity.getString("tituloprefijo");
                            String teacher = activity.getString("expositores");
                            Integer isAccomplished = activity.getInt("cumplida");
                            Integer isBlocked = activity.getInt("bloqueo");
                            Integer hvVideo = activity.getInt("tienevideo");

                            actividades.add(new Activity(id, titlePref, title, teacher, isAccomplished, isBlocked, hvVideo));
                        }
                        listHash.put(listDataHeader.get(0),actividades);
                    }
                    if ( JSONresponse.has("bloques") && JSONresponse.get("bloques") instanceof JSONArray )
                    {
                        JSONArray bloquesArr = JSONresponse.getJSONArray("bloques");
                        bloquesArr_length = bloquesArr.length();

                        int ini = 0;
                        if( actividadesArr_length > 0 ){
                            ini = 1;
                        }

                        int romanNumber = 1;
                        for (int i = ini; i < bloquesArr_length; i++)
                        {
                            JSONObject bloque = new JSONObject(bloquesArr.getString(i));
                            String titulo_bloque  = bloque.getString("titulo");

                            listDataHeader.add("BLOQUE " + RomanNumerals.toRoman(romanNumber) + ": " + titulo_bloque);

                            List<Activity> actividades = new ArrayList<>();

                            if (bloque.has("actividades") && bloque.get("actividades") instanceof JSONArray)
                            {
                                JSONArray actividadesArr = bloque.getJSONArray("actividades");
                                bloquesActividadesArr_length = actividadesArr.length();

                                for (int j = 0; j < bloquesActividadesArr_length; j++)
                                {
                                    JSONObject activity = new JSONObject(actividadesArr.getString(j));

                                    Integer id   = activity.getInt("id");
                                    String title = activity.getString("titulo");
                                    String titlePref = activity.getString("tituloprefijo");
                                    String teacher = activity.getString("expositores");
                                    Integer isAccomplished = activity.getInt("cumplida");
                                    Integer isBlocked = activity.getInt("bloqueo");
                                    Integer hvVideo = activity.getInt("tienevideo");

                                    actividades.add(new Activity(id, titlePref, title, teacher, isAccomplished, isBlocked, hvVideo));
                                } //for actividades
                            }
                            romanNumber++;
                            listHash.put(listDataHeader.get(i),actividades);
                        } // for bloques
                    }
                    //Toast.makeText(getApplicationContext(), "size: " + listAdapter.getGroupCount(), Toast.LENGTH_SHORT).show(); //-> here always show correct value
                }
                else
                {
                    JSONObject error = JSONresponse.getJSONObject("error");
                    Toast.makeText(getApplicationContext(), "Error: [" + error.getString("num") + "] " + error.getString("msg"), Toast.LENGTH_SHORT).show();
                }
            } catch (JSONException e)
            {
                e.printStackTrace();
                Toast.makeText(getApplicationContext(), "Error al recuperar sus datos", Toast.LENGTH_SHORT).show();
            }
            callback.onResponse(listHash, listDataHeader);
        }
    },
    new Response.ErrorListener()
    {
        @Override
        public void onErrorResponse(VolleyError error)
        {
            String message = "Error de conexión";
            if (!error.getMessage().isEmpty()) {
                message += ": [" + error.getMessage() + "]";
            }
            Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
        }
    })
    {
        @Override
        protected Map<String, String> getParams() {
            Map<String, String> params = new HashMap<>();
            HashMap<String, String> user = sesion.getUserDetails();

            // get user data from session
            params.put("sesion", user.get(sesion.getKEY_CODE()));
            params.put("curso", myCourse.getId().toString());
            return checkParams(params);
        }
    };
    queue.add(req);
}

private static class VolleyCallback
{
    void onResponse(HashMap<String,List<Activity>> listHash, List<String> listDataHeader) {

    }
}

with callback.onResponse I return the data and I can access all the functions of the adapter without any errors. I do not know if it will be the best way, but it works correctly.

Greetings.

    
answered by 05.04.2017 / 16:24
source
0

The method that determines the number of groups within ExpandableListView is getGroupCount() within Adapter that in your case is ExpandableListAdapter :

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

in onResponse() of your Volley implementation I see that in the code according to certain considerations it adds elements to listDataHeader , ensures that in the end it actually contains elements, this before instantiating the Adapter:

  listAdapter = new ExpandableListAdapter(getApplicationContext(),listDataHeader,listHash);
    
answered by 04.04.2017 в 21:09