Carlos Rocha Posted January 8, 2020 at 07:11 PM Report #617004 Posted January 8, 2020 at 07:11 PM (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 at 07:47 PM by carcleo
antseq Posted January 9, 2020 at 09:58 AM Report #617007 Posted January 9, 2020 at 09:58 AM 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
Carlos Rocha Posted January 9, 2020 at 10:40 AM Author Report #617008 Posted January 9, 2020 at 10:40 AM (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 at 10:52 AM by carcleo
antseq Posted January 9, 2020 at 12:01 PM Report #617009 Posted January 9, 2020 at 12:01 PM 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>>(...)
Carlos Rocha Posted January 10, 2020 at 10:32 AM Author Report #617016 Posted January 10, 2020 at 10:32 AM (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 at 10:36 AM by carcleo
antseq Posted January 10, 2020 at 10:55 AM Report #617017 Posted January 10, 2020 at 10:55 AM 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,
Carlos Rocha Posted January 10, 2020 at 11:36 AM Author Report #617022 Posted January 10, 2020 at 11:36 AM 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
Carlos Rocha Posted January 10, 2020 at 11:42 PM Author Report #617028 Posted January 10, 2020 at 11:42 PM 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?
antseq Posted January 13, 2020 at 09:54 AM Report #617043 Posted January 13, 2020 at 09:54 AM 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
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