Carlos Rocha 4 Posted January 8, 2020 Report Share Posted January 8, 2020 (edited) 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 January 8, 2020 by carcleo Link to post Share on other sites
antseq 82 Posted January 9, 2020 Report Share Posted January 9, 2020 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 Link to post Share on other sites
Carlos Rocha 4 Posted January 9, 2020 Author Report Share Posted January 9, 2020 (edited) 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 January 9, 2020 by carcleo Link to post Share on other sites
antseq 82 Posted January 9, 2020 Report Share Posted January 9, 2020 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>>(...) Link to post Share on other sites
Carlos Rocha 4 Posted January 10, 2020 Author Report Share Posted January 10, 2020 (edited) 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 January 10, 2020 by carcleo Link to post Share on other sites
antseq 82 Posted January 10, 2020 Report Share Posted January 10, 2020 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, Link to post Share on other sites
Carlos Rocha 4 Posted January 10, 2020 Author Report Share Posted January 10, 2020 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 Link to post Share on other sites
Carlos Rocha 4 Posted January 10, 2020 Author Report Share Posted January 10, 2020 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 abaixohttp://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? Link to post Share on other sites
antseq 82 Posted January 13, 2020 Report Share Posted January 13, 2020 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 Link to post Share on other sites
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now