I have read from Firebase the following JSON:
"categorias" : {
"Telas de Hogar" : {
"descripcion" : "",
"estado" : "invisible",
"nombre" : "Telas de Hogar",
"paginas" : {
"Loneta" : {
"descripcion" : "",
"estado" : "invisible",
"nombre" : "Loneta",
"productos" : {
"0000-0001" : {
"numero" : "0000-0001"
},
"0000-0002" : {
"numero" : "0000-0002"
},
"0000-0003" : {
"numero" : "0000-0003"
},
"0000-0004" : {
"numero" : "0000-0004"
}
}
}
},
"productos" : {
"0000-0001" : {
"numero" : "0000-0001"
},
"0000-0002" : {
"numero" : "0000-0002"
},
"0000-0003" : {
"numero" : "0000-0003"
},
"0000-0004" : {
"numero" : "0000-0004"
},
"0000-0005" : {
"numero" : "0000-0005"
},
"0000-0006" : {
"numero" : "0000-0006"
}
}
}
}
And I have assigned it to a java class with the following structure:
public class Category {
private String nombre;
private String descripcion;
private String estado;
private Map<String, ProductReference> productos;
private Map<String, Page> paginas;
public Category(){}
public Category(String nombre) {
this.nombre = nombre;
this.descripcion = "";
this.estado = "";
}
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
public String getDescripcion() {
return descripcion;
}
public void setDescripcion(String descripcion) {
this.descripcion = descripcion;
}
public String getEstado() {
return estado;
}
public void setEstado(String estado) {
this.estado = estado;
}
public Map<String, ProductReference> getProductos() {
return this.productos;
}
public void setProductos(Map<String, ProductReference> productos) {
this.productos = productos;
}
public Map<String, Page> getPaginas() {
return this.paginas;
}
public void setPaginas(Map<String, Page> paginas) {
this.paginas = paginas;
}
@Override
public String toString() {
return nombre;
}
}
Now what I want is to display categorias and their paginas in a ExpandableListView. I have managed to display the object categoria in the GroupView, but when I try to assign the list of pages to the ChildView I have this error:
java.lang.NullPointerException: Attempt to invoke interface method 'int java.util.Map.size()' on a null object reference
at com.example.tejidospulido_app.Presentador.Adapter.AdapterCategories.getChildrenCount(AdapterCategories.java:42)...
The Fragment that the ExpandedListView belongs to is this:
public class MenuFragment extends Fragment {
private static final String TAG = "Menu";
private ExpandableListView exp_list_view;
private ArrayList<Category> list_categories;
private HashMap<String, Map<String, Page>> list_pages;
private AdapterCategories adapter;
public MenuFragment(){
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_menu, container, false);
setViews(view);
return view;
}
private void setViews(View view) {
list_categories = new ArrayList<>();
list_pages = new HashMap<>();
exp_list_view = (ExpandableListView) view.findViewById(R.id.exp_list_view);
adapter = new AdapterCategories(list_categories, list_pages);
handleChargeCategoryList();
}
public void handleChargeCategoryList() {
FirebaseDatabase.getInstance().getReference().child("categorias").addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
list_categories.clear();
for (DataSnapshot snapshot : dataSnapshot.getChildren()){
Category c = snapshot.getValue(Category.class);
list_categories.add(c);
list_pages.put(c.getNombre(), c.getPaginas());
adapter = new AdapterCategories(list_categories, list_pages);
exp_list_view.setAdapter(adapter);
}
}
@Override
public void onCancelled(DatabaseError error) {
// Failed to read value
Toast.makeText(getContext(), error.getMessage(), Toast.LENGTH_LONG).show();
}
});
}
}
And the Adapter:
public class AdapterCategories extends BaseExpandableListAdapter {
private ArrayList<Category> list_categories;
private HashMap<String, Map<String, Page>> list_pages;
public AdapterCategories(ArrayList<Category> categoryList, HashMap<String, Map<String, Page>> list_pages){
this.list_categories = categoryList;
this.list_pages = list_pages;
}
@Override
public int getGroupCount() {
return list_categories.size();
}
@Override
public int getChildrenCount(int groupPosition) {
return list_pages.get(list_categories.get(groupPosition).getNombre()).size();
}
@Override
public Category getGroup(int groupPosition) {
return list_categories.get(groupPosition);
}
@Override
public Page getChild(int groupPosition, int childPosition) {
return list_pages.get(list_categories.get(groupPosition).getNombre()).get(childPosition);
}
@Override
public long getGroupId(int groupPosition) {
return 0;
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return 0;
}
@Override
public boolean hasStableIds() {
return false;
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
convertView = LayoutInflater.from(parent.getContext()).inflate(android.R.layout.simple_expandable_list_item_1, parent, false);
TextView textView = convertView.findViewById(android.R.id.text1);
//Initialize string
String categoryName = getGroup(groupPosition).getNombre();
textView.setText(categoryName);
textView.setTypeface(null, Typeface.BOLD);
textView.setTextColor(Color.BLACK);
return convertView;
}
@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
convertView = LayoutInflater.from(parent.getContext()).inflate(android.R.layout.simple_selectable_list_item, parent, false);
TextView textView = convertView.findViewById(android.R.id.text1);
//Initialize string
String pageName = getChild(groupPosition, childPosition).getNombre();
textView.setText(pageName);
textView.setTextColor(Color.BLACK);
textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(parent.getContext(), pageName, Toast.LENGTH_SHORT).show();
}
});
return convertView;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return false;
}
}
This is the result if I debug with a breakpoint at the getChild() function.
Source: Android Questions