2

Estoy intentando acceder a los valores de una HashMap<> pero la aplicación se detiene cuando desde un custom adapter trato de tomar los valores que pasé al HashMap, mostrando este mensaje en el logcat:

E/AndroidRuntime: FATAL EXCEPTION: main java.lang.NullPointerException
    at mi.app.ejemplo.app.adapterstack.getView(adapterstack.java:41)

Se detiene en esta línea de código:

nombre.setText(item.getCodigo().get(i).getId());

Éste es mi código:

Adaptador:

public class adapterstack extends BaseAdapter {
    List<stack.ItemsBean> itemlist;
    Context sContext;
    public adapterstack(Context sContext, List<stack.ItemsBean> itemlist) {
        this.sContext = sContext;
        this.itemlist = itemlist;}
    @Override
    public int getCount() {return itemlist.size();}

    @Override
    public Object getItem(int i) {return itemlist.get(i);}

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

    @Override
    public View getView(int i, View view, ViewGroup viewGroup) {
        LayoutInflater inflater = (LayoutInflater) sContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        final View rootView = inflater.inflate(R.layout.item_act, viewGroup, false);
        final stack.ItemsBean item = (stack.ItemsBean) getItem(i);
        TextView nombre = (TextView) rootView.findViewById(R.id.txtname);
        TextView genero = (TextView) rootView.findViewById(R.id.txtid);

        //TODO: En esta linea de código la app se detiene.

        nombre.setText(item.getCodigo().get(i).getId());
        genero.setText(item.getCodigo().get(i).getStrong());
        return rootView;
    }
}

Clase donde paso el JSON a Java:

public class stack {
    private int id;
    private String name;
    private UserBean user;
    private List<ItemsBean> items;

    public int getId() {return id;}
    public void setId(int id) {this.id = id;}
    public String getName() {return name;}
    public void setName(String name) {this.name = name;}
    public UserBean getUser() {return user;}
    public void setUser(UserBean user) {this.user = user;}
    public List<ItemsBean> getItems() {return items;}
    public void setItems(List<ItemsBean> items) {this.items = items;}

    public static class UserBean {
        private String name;
        public String getName() {return name;}
        public void setName(String name) {this.name = name;}
    }

    public static class ItemsBean {
        private HashMap<String, CodigoBean> codigo = new HashMap<String,CodigoBean>();
        public HashMap<String, CodigoBean> getCodigo(){return codigo;}
        public void setCodigo(HashMap<String, CodigoBean> codigo) {this.codigo = codigo;}

        public static class CodigoBean {
            private int id;
            private int strong;
            private boolean active;
            private String sell;

            public int getId() {return id;}
            public void setId(int id) {this.id = id;}
            public int getStrong() {return strong;}
            public void setStrong(int strong) {this.strong = strong;}
            public boolean isActive() {return active;}
            public void setActive(boolean active) {this.active = active;}
            public String getSell() {return sell;}
            public void setSell(String sell) {this.sell = sell;}
        }
    }
}

El JSON:

{
  "id": 1001,
  "name": "Super1",
  "user": {
    "name": "The Super 1"
  },
  "items": [{
    "987987M7812b163eryrt": {
      "id": 1,
      "strong": 456,
      "active": true,
      "sell": "te"
    },
    "90812bn120893juuh": {
      "id": 2,
      "strong": 4700,
      "active": true,
      "sell": "tt"
    },
    "981273jn19203nj123rg": {
      "id": 3,
      "strong": 3000,
      "active": true,
      "sell": "ti"
    }
  }]
}
Alvaro Montoro
  • 48,157
  • 26
  • 100
  • 179
LuDev
  • 63
  • 6
  • 2
    ¿"Se detiene" o es que lanza una excepción? Revisa el logcat para ver mensajes de error, mira si eso te explica cuál es el problema, y si no es así actualiza la pregunta con la información del logcat. – SJuan76 Mar 11 '18 at 11:26
  • Una excepción, sabrá por que esta causada?, le añadí el mensaje del logcat – LuDev Mar 11 '18 at 12:16
  • ¿`rootView` tiene un `TextView` cuyo id es `txtname` y otro `TextView` cuyo id es `txtid`? – A. Cedano Mar 11 '18 at 12:48
  • @A.Cedano si, es correcto, ambos TextViews están en el layout: item_act – LuDev Mar 11 '18 at 13:03
  • 1
    Esto es un `nullPointerException`, ocurre porque estás intentando acceder a una propiedad o método de una variable que es null (generalmente porque no se le ha asignado ningún valor o el valor asignado fue null). Debes depurar tu aplicación para ver el valor de `item` y asegurarte que se puede hacer esa secuencia de comandos (por ejemplo, ¿qué devuelve `get(i)` para `item.getCodigo()`?). [Esta pregunta](https://es.stackoverflow.com/q/42977/250) contiene diferentes consejos para evitar este tipo de problemas. Te recomiendo que le eches un ojo y los apliques al código. – Alvaro Montoro Mar 11 '18 at 13:18
  • 3
    Posible duplicado de [¿Cuál es la solución a todos los errores NullPointerException presentes, pasados y futuros?](https://es.stackoverflow.com/questions/42977/cu%c3%a1l-es-la-soluci%c3%b3n-a-todos-los-errores-nullpointerexception-presentes-pasados) – Pablo Lozano Mar 11 '18 at 13:31
  • Gracias por la aclaración, la duda radica en si estoy mapeando los códigos de forma correcta o si estoy iterando en el `HashMap<>` desde el customa adapter de forma correcta, ya que trate de mostrar mediante `Toast` una variable del JSON externa a lo que esta en `HashMap<>` y logre acceder sin `NullPointerException`, debo crear una nueva pregunta? – LuDev Mar 11 '18 at 14:15
  • 1
    Buenas tardes, estas instanciando mal la clase stack, que es la que devuelve los `getters` que necesitas usar con el `item` final stack.ItemsBean item = (stack.ItemsBean) getItem(i); cambialo por final stack.ItemsBean item = new (stack.ItemsBean); , despues en item le agregas el getItem(i) ; tambien – Gastón Saillén Mar 11 '18 at 20:27
  • @GastónSaillén quedaria de la siguiente forma? lo hice asi pero me marca error de sistaxis: `final stack.ItemsBean item = new (stack.ItemsBean);` , antes del punto y coma me dice que hace falta una expresión, alguna idea de porque? gracias por la ayuda – LuDev Mar 11 '18 at 20:55

1 Answers1

0

Es muy claro el error.

1) La variable i corresponde a la posición del elemento enlistado, y ya está siendo usado en getItem(i), que al devolver un Object, el casteo es necesario.

2) ItemsBean.getCodigo() devuelve un HashMap de tipo < String, CodigoBean>, por lo que contiene llaves de tipo String, es decir que su método get, recibe una llave de tipo String, pero le estás pasando la variable i, que corresponde a la posición del objeto ItemsBean en la lista de ItemsBean, y un HashMap devuelve null si no encuentra un objeto asociado con la llave dada, por eso al hacer .getId() se genera un NullPointerException

3) Ya que no conoces la llave que vendrá en el hashmap, debes obtener el conjunto de valores del HashMap con .values(), lo cual devolverá un Collection de tipo CodigoBean, es decir:

Collection<CodigoBean> values = item.getCodigo().values();

4) Ahora puedes Iterar la colección para asignar los valores del objeto que hay dentro, esperando que sólo contenga un elemento:

for (CodigoBean codigoBean: values) {
  nombre.setText(String.valueOf(codigoBean.getId()));
  genero.setText(String.valueOf(codigoBean.getStrong()));
}

5) ¿Por qué usé String.valueOf()? Porque setText(int i) interpreta la variable entera i, como la referencia de un texto definido en el archivo strings.xml, por ejemplo R.string.myString, en cambio setText(String s) sólo muestra la cadena s en el campo de texto.

Happy Pat
  • 1
  • 2