Jump to content
carcleo

Preencher Spinner

Recommended Posts

carcleo

Tenho a seguinte saída JSON vinda de uma API:

{
  "status":"ok",
  "equipamentos":
     [
       {
         "equipamento":
           "{
             \"id\":7,
             \"cliente\":1,
             \"tipo\":\"Celular\",
             \"marca\":\"Motorola\",
             \"modelo\":\"Moto G 7\",
             \"serial\":\"Aparelho n\\u00e3o liga\",
             \"caracteristicas\":\"P\\u00c9SSIMO\"
          }"
       },
       {
         "equipamento":
           "{
             \"id\":8,
             \"cliente\":1,
             \"tipo\":\"Celular\",
             \"marca\":\"Motorola\",
             \"modelo\":\"Moto G 7\",
             \"serial\":\"Aparelho n\\u00e3o liga\",
             \"caracteristicas\":\"P\\u00c9SSIMO\"
            }"
        }
     ]
}

E o seguinte método para gerar um novo objeto à partir do índice "equipamentos" gerado do JSON recebido da API

@Override
protected void onPostExecute(String str) {

    progressDialog.cancel();

    JSONObject retorno = null;

    try {

        retorno = new JSONObject(str);

        if ( retorno.has("equipamentos"))
            preencherComboEquipamentos(retorno.getJSONObject("equipamentos"));
            


    } catch (JSONException e) {
        e.printStackTrace();
    }
    
}

Com ele, o método preencherComboEquipamentos receberá um objeto como abaixo:

 

[
   {
     "equipamento":
       "{
         \"id\":7,
         \"cliente\":1,
         \"tipo\":\"Celular\",
         \"marca\":\"Motorola\",
         \"modelo\":\"Moto G 7\",
         \"serial\":\"Aparelho n\\u00e3o liga\",
         \"caracteristicas\":\"P\\u00c9SSIMO\"
      }"
   },
   {
     "equipamento":
       "{
         \"id\":8,
         \"cliente\":1,
         \"tipo\":\"Celular\",
         \"marca\":\"Motorola\",
         \"modelo\":\"Moto G 7\",
         \"serial\":\"Aparelho n\\u00e3o liga\",
         \"caracteristicas\":\"P\\u00c9SSIMO\"
        }"
    }
 ]


 
 Agora preciso criar um JSONArray de JSONObjects com apenas 2 campos trazidos do JSONObject anterior que são id e cliente.
 
 Estou tentando assim mas não está dando certo
 

private void preencheComboClientes(JSONObject JSClientes) throws JSONException {

    JSONObject clientes = null;
    ArrayList<JSONObject> clientesList = null;

    for (int i = 0; i < JSClientes.length(); i++) {

        clientes.put("id", JSClientes.getJSONObject(i).getInt("id"));
        clientes.put("nome", JSClientes.getJSONObject(i).getInt("nome"));
        
        clientesList[clientes];

    }

    ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, clientes);
    spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    spCliente.setAdapter(spinnerArrayAdapter);

}

A ideia é preencher um spinner.

Edited by carcleo

Share this post


Link to post
Share on other sites
antseq

Viva,

Por favor verifique o seu código. 
Assim por alto há umas partes que não parecem fazer sentido:

1. Tem um objecto "null" (a) e depois utiliza o mesmo (b) sem nenhuma inicialização ( new ArrayList ) + não deveria ser "clientesList.add(clientes)":
(a) ArrayList<JSONObject> clientesList = null;
..
(b) clientesList[clientes];

2. Tem uma lista do tipo "JSONObject" (c) e depois um adapter do tipo "String":
(c) ArrayList<JSONObject> clientesList...
...
(d) ArrayAdapter<String> spinnerArrayAdapter...

3. Preenche a lista "clientesList" (e) mas não a utiliza em lado algum, quando deveria se utilizada no adapter (f):
(e) ArrayList<JSONObject> clientesList...
...
(f) ... new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, clientes);

cps

Share this post


Link to post
Share on other sites
carcleo
private void preencheComboClientes(JSONObject JSClientes) throws JSONException {

    ArrayList<JSONObject> clientesList = new ArrayList<JSONObject>();

    for (int i = 0; i < JSClientes.length(); i++) {

        JSONObject cliente = new JSONObject();

        cliente.put("id", JSClientes.getJSONObject("cliente").getInt("id"));
        cliente.put("nome", JSClientes.getJSONObject("cliente").getString("nome"));

        clientesList.add(cliente);

    }

    ArrayAdapter<ArrayList<JSONObject>> adapter = new ArrayAdapter< ArrayList<JSONObject>>(this, android.R.layout.simple_spinner_dropdown_item, clientesList);
    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    spCliente.setAdapter(adapter);

      
Ainda não funcionou!

Tem erro aqui:

JSClientes.getJSONObject(i)

O que eu desejo é criar um elemento que imite o Select Option do html que possui, para cada item, 2 elementos: 

um value para enviar junto com o formulário, geralmente o id do cliente no banco

um text que vai mostrar o nome do cliente para o usuário

 

Como disse, a saída JSON da API é como segue:

[
   {
     "equipamento":
       "{
         \"id\":7,
         \"cliente\":1,
         \"tipo\":\"Celular\",
         \"marca\":\"Motorola\",
         \"modelo\":\"Moto G 7\",
         \"serial\":\"Aparelho n\\u00e3o liga\",
         \"caracteristicas\":\"P\\u00c9SSIMO\"
      }"
   },
   {
     "equipamento":
       "{
         \"id\":8,
         \"cliente\":1,
         \"tipo\":\"Celular\",
         \"marca\":\"Motorola\",
         \"modelo\":\"Moto G 7\",
         \"serial\":\"Aparelho n\\u00e3o liga\",
         \"caracteristicas\":\"P\\u00c9SSIMO\"
        }"
    }
 ]

Esse foi o mais longe que cheguei!

Mas não faz sentido aquele for no código se não tem como pegar o índice i do objeto

Edited by carcleo

Share this post


Link to post
Share on other sites
antseq

Viva,

1. neste seu novo código está a fazer "getJSONObject("cliente")" e não "getJSONObject(i)" !?

2. em princípio o adapter é do tipo "ArrayAdapter<JSONObject>" e não do tipo "ArrayAdapter<ArrayList<JSONObject>>"

nota:

como as vezes tenho "id" (int ou string) utilizo uma class KeyValue para guardar os items do spinner do tipo:

public class SpinnerKV<K,V> {
    protected K mKey;
    protected V mValue;

    public SpinnerKV(K key, V value) {
        mKey = key;
        mValue = value;
    }

    public void setKey (K key) {
        this.mKey = key;
    }
    public K getKey () {
        return mKey;
    }

    public void setValue (V value) {
        this.mValue = value;
    }
    public V getValue () {
        return mValue;
    }

    @Override
    public String toString() {
        return mValue.toString();
    }
}

depois utilizo:

new ArrayAdapter<SpinnerKV<String, String>>(...)

new ArrayAdapter<SpinnerKV<Int, String>>(...)

 

Share this post


Link to post
Share on other sites
carcleo

Então, eu não criei uma classe como você fez. Mas fiz algo parecido!

Deu certo.

Agora falta popular o Spinner. Veja:

private void preencheComboClientes(JSONArray jsClientes) throws JSONException {

    ArrayList<JSONObject> lista = new ArrayList<JSONObject>();

    for (Integer i = 0; i < jsClientes.length(); i++) {

        JSONObject jsonObject = new JSONObject();
        JSONObject cliente = new JSONObject();
        jsonObject = jsClientes.getJSONObject(i).getJSONObject("cliente");

        cliente.put("id",jsonObject.getString("id"));
        cliente.put("nome",jsonObject.getString("nome"));

        lista.add(cliente);

    }

    ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, lista);
    spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    spCliente.setAdapter(spinnerArrayAdapter);

}

lista está retornando:

[
  {
    "id":"1",
  "nome":"Carlos"
  }, 
  {
    "id":"2,
  "nome":"Cleonice Rocha"
  }
]

Na verdade, o que eu preciso é fazer como se fosse um Select Opiton do HTML com o Spinner com essa lista

Algo d tipo:

<selec id="meuSelect" >

       <option id="meuId">          Meu Texto valor para aquele id          </option>

</select>

 

Edited by carcleo

Share this post


Link to post
Share on other sites
antseq

Viva,

Continua a usar uma lista de um tipo <JSONObject> e um adapter de outro tipo <string>.

1) Vamos por partes e começar com algo "simples". Se alterar o seu código para:

ArrayList<String> lista = new ArrayList<String>();
..
lista.add(jsonObject.getString("nome"));

Vai criar uma lista de "string" para um adapter "string" e o seu Spinner terá de mostrar todos os "nomes" (perde o 'id').
Veja aqui exemplo (apenas descrição, sem 'id'):
https://stackoverflow.com/questions/11920754/android-fill-spinner-from-java-code-programmatically


2) como pretende ter items "complexos" (objecto) com "id", "nome", outros "campos":
- criar ObjectoComplexo : campos a, b, c, d , e, ...
- adiconar ao ObjectoComplexo o método "public String toString()" para devolver o nome a apresentar no "Spinner" (returnr campo"e")
- criar ArrayList<ObjectoComplexo>
- criar ArrayAdapter<ObjectoComplexo>
- atribuir ao adapter a respectiva lista

cps,

Share this post


Link to post
Share on other sites
carcleo

Agora preciso sair mas depois vou segui teu passo-a-passo mas já tentei

ArrayList<ArrayList<JSONObject>> lista = new ArrayList<ArrayList<JSONObject>>);

e deu erro também!

Talvez eu não esteja usando o componente certo para imitar o Select Option do HTNL

Share this post


Link to post
Share on other sites
carcleo

Obrigado pelo apoio mas vamos lá! Nova tentativa:

Esse é o JSON de entrada:

[
  {
    "id":"1",
  "nome":"Carlos"
  }, 
  {
    "id":"2",
  "nome":"Cleonice Rocha"
  }, 
  {
    "id":"3",
  "nome":"Cleonice Rocha"
  }
]

Então seguindo o tutorial abaixo
http://blog.mikeclassic.ca/post/android-populating-spinner-with-strings-and-id
fiz:


private static class StringWithTag {
    public String string;
    public Object tag;

    public StringWithTag(String string, Object tag) {
        this.string = string;
        this.tag = tag;
    }

    @Override
    public String toString() {
        return string;
    }
}
private void preencheComboClientes(JSONArray jsClientes) throws JSONException {

    HashMap<Integer, String> listaClientes = new HashMap<Integer, String>();

    for (Integer i = 0; i < jsClientes.length(); i++) {

        JSONObject jsonObject = jsClientes.getJSONObject(i).getJSONObject("cliente");

        Integer id = jsonObject.getInt("id");
        String nome = jsonObject.getString("nome");

        listaClientes.put(id, nome);

    }

    List<StringWithTag> itemList = new ArrayList<StringWithTag>();

    for (Map.Entry<Integer, String> entry : listaClientes.entrySet()) {

        Integer key = entry.getKey();
        String value = entry.getValue();

        itemList.add(new StringWithTag(value, key));
    }

    System.out.println(itemList);

    ArrayAdapter<StringWithTag> spinnerAdapter = new ArrayAdapter<StringWithTag>(this, android.R.layout.simple_spinner_item, itemList);
    spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    spCliente.setAdapter(spinnerAdapter);

}

Mas no final itemList saiu apenas com os nomes, sem os ids

I/System.out: [Carlos, Cleonice Rocha, Cleonice Rocha]

e, o spinner, apenas o primeiro nome!

Onde foi que eu errei?

Share this post


Link to post
Share on other sites
antseq

Viva,

1. o que está a ver no "out" é a representação "toString()" portanto não perdeu os Ids

2. estive a testar (repoduzir) o seu código com este exemplo (abaixo) e funciona perfeitamente. Inclusive nos "clicks" podemos visualizar no LOG os Ids de cada item:

        List<StringWithTag> itemList = new ArrayList<StringWithTag>();
        itemList.add(new StringWithTag("Carlos", 1));
        itemList.add(new StringWithTag("Cleonice Rocha", 2));
        itemList.add(new StringWithTag("Cleonice Rocha", 3));

        final ArrayAdapter<StringWithTag> spinnerAdapter = new ArrayAdapter<StringWithTag>(this, android.R.layout.simple_spinner_item, itemList);
        spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spCliente= (Spinner) findViewById(R.id..................);
        spCliente.setAdapter(spinnerAdapter);
        spCliente.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
                StringWithTag selItem = spinnerAdapter.getItem(i);
                Log.d("LOG", "onItemSelected: " + selItem.tag + ";" +  selItem.string );
            }
            @Override
            public void onNothingSelected(AdapterView<?> adapterView) {
            }
        });

cps

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.