Autore Topic: Ricevere dati da Json e creare lista  (Letto 535 volte)

Offline konan_ 65

  • Nuovo arrivato
  • *
  • Post: 18
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Google Nexus 5
  • Sistema operativo:
    Windows 8.1
Ricevere dati da Json e creare lista
« il: 23 Aprile 2015, 17:25:26 CEST »
0
Ciao a tutti, premetto che sono alle prime armi con la programmazione in android, ma ho un problema, come da titolo del topic dovrei leggere i dati contenuti in un json (link oppure testo) e, in base a questi, implementare dinamicamente una listview con quello che la json mi risponde (bottoni per i link, immagini per i link alle immagini, testo per il testo), ma non ho davvero la più pallida idea di come si faccia  :'(

ho pensato di aprire la connessione con
Codice: [Seleziona]
HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();dove url è l'urlo della json, ma non ho idea poi di come prendere i dati che ricevo, e sopratutto di come costruire la listview dinamicamente

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:Ricevere dati da Json e creare lista
« Risposta #1 il: 23 Aprile 2015, 19:06:43 CEST »
0
A occhio ti mancano le basi su diversi concetti (networking su android, parsing json, listview eterogenee), per cui ti consiglio come affrontare uno alla volta questi concetti e costruire un passo alla volta la tua app.

PASSO 1 : networking

Purtroppo fare una richiesta di rete non è una sola riga di codice, se usi gli strumenti di base android. Però ci sono librerie (usate da TUTTI) che ti permettono di farlo quasi in una riga.

Parti dalla libreria OKHTTP (da qua OkHttp ), impara come usarla, richiama il tuo JSON e visualizzalo come testo in una TextView di prova della tua app. Raggiunto questo risultato, hai appreso come fare correttamente richieste di rete.


PASSO 2 : parsing JSON

Senza stare a gestire le stringhe ed i caratteri "a mano" impara ad usare strumenti già fatti per il parsing JSON (libreria GSON, oppure JSONArray/JSONObject).

Usa l'app precedente, però invece di visualizzare il JSON in formato testo, fanne il parsing e visualizza sullo schermo gli elementi acquisiti senza nella stessa TextView, così capisci rapidamente se lo fai correttamente.


PASSO 3 : costruzione dinamica della listview eterogenea

Il fatto che la TextView sia eterogenea, cioè contenga elementi diversi, complica un po' la cosa.

Però fossi io comincerei a fare una ListView omogenea, in cui tutte le righe sono uguali e contengono un bottone, un'immagine e del testo. A seconda se l'elemento è un bottone, un'immagine o un testo, vado a valorizzare la relativa parte e lascio "grigia" l'altra. In questo modo vedi rapidamente se tutta l'app funziona.

Il passo dopo è semplice, invece che lasciare grigi gli elementi usati, basta eliminarli dall'elemento riga (View.GONE). In questo modo di fatto tu costruisci una ListView omogenea ed elimini le parti che non usi, così da ottenere di fatto una ListView eterogenea.
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline konan_ 65

  • Nuovo arrivato
  • *
  • Post: 18
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Google Nexus 5
  • Sistema operativo:
    Windows 8.1
Re:Ricevere dati da Json e creare lista
« Risposta #2 il: 06 Maggio 2015, 18:56:36 CEST »
0
Intanto grazie mille per la risposta, purtroppo mi fermo al primo passo, non riesco a capire come fare la richiesta per il json, non c'è qualche guida che spieghi il funzionamento di okhttp?
« Ultima modifica: 06 Maggio 2015, 19:19:21 CEST da konan_ 65 »

Offline konan_ 65

  • Nuovo arrivato
  • *
  • Post: 18
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Google Nexus 5
  • Sistema operativo:
    Windows 8.1
Re:Ricevere dati da Json e creare lista
« Risposta #3 il: 12 Maggio 2015, 17:55:35 CEST »
0
Allora, sono andato avanti,credo di essere riuscito a risolvere la parte di chiamata del json, lo faccio in questo modo

Codice (Java): [Seleziona]
private class AsyncListViewLoader extends AsyncTask<String, Void, List<Json>> {
        private final ProgressDialog dialog = new ProgressDialog(Table.this);

        @Override
        protected void onPostExecute(List<Json> result) {
            super.onPostExecute(result);
            dialog.dismiss();
            adpt.setItemList(result);
            adpt.notifyDataSetChanged();
        }

        @Override
        protected List<Json> doInBackground(String... params) {
            List<Json> result = new ArrayList<Json>();

            try {
                URL u = new URL(params[0]);

                HttpURLConnection conn = (HttpURLConnection) u.openConnection();
                conn.setRequestMethod("GET");

                conn.connect();
                InputStream is = conn.getInputStream();

                // Read the stream
                byte[] b = new byte[1024];
                ByteArrayOutputStream baos = new ByteArrayOutputStream();

                while (is.read(b) != -1)
                    baos.write(b);

                String JSONResp = new String(baos.toByteArray());

                JSONArray arr = new JSONArray(JSONResp);
                for (int i = 0; i < arr.length(); i++) {
                    result.add(convertData(arr.getJSONObject(i)));
                }

                return result;
            } catch (Throwable t) {
                t.printStackTrace();
            }
            return null;
        }

        private Json convertData(JSONObject obj) throws JSONException {
            String description = obj.getString("description");
            String donwload_url = obj.getString("donwload_url");
            String file_size = obj.getString("file_size");
            String image_url = obj.getString("image_url");
            String name = obj.getString("name");
            String page_count = obj.getString("page_count");
            int id = obj.getInt("id");

            return new Json(description, donwload_url, file_size, id, image_url, name, page_count);
        }

    }

la parte che però non riesco a fare è quella di visualizzazione dei dati, ho creato un layout ed una adapter personalizzati, ma non riesco a visualizzare il codice

l'adapter è questo

Codice (Java): [Seleziona]
public class TableAdapter extends ArrayAdapter<Json> {

    private List<Json> itemList;
    private Context context;

    public TableAdapter(List<Json> itemList, Context ctx) {
        super(ctx, R.layout.table_layout, itemList);
        this.itemList = itemList;
        this.context = ctx;
    }

    public int getCount() {
        if (itemList != null)
            return itemList.size();
        return 0;
    }

    public Json getItem(int position) {
        if (itemList != null)
            return itemList.get(position);
        return null;
    }

    public long getItemId(int position) {
        if (itemList != null)
            return itemList.get(position).hashCode();
        return 0;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View v = convertView;

        JsonHolder holder = new JsonHolder();

        if (v == null) {
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = inflater.inflate(R.layout.table_layout, null);

            TextView name = (TextView) v.findViewById(R.id.name);
            TextView description = (TextView) v.findViewById(R.id.description);
            ImageView image = (ImageView) v.findViewById(R.id.imageView2);
            TextView size = (TextView) v.findViewById(R.id.size);
            TextView page = (TextView) v.findViewById(R.id.page);
            Button button = (Button) v.findViewById(R.id.pdf);

            holder.nameView = name;
            holder.descView = description;
            holder.imageView = image;
            holder.sizeView = size;
            holder.pageView = page;
            holder.buttonView = button;

        }else
            holder = (JsonHolder) v.getTag();

        Json p = itemList.get(position);
        holder.nameView.setText(p.getName());
        holder.descView.setText(p.getDescription());
        holder.imageView.setImageBitmap(p.getImage_url());
        holder.sizeView.setText(p.getFile_size());
        holder.pageView.setText(p.getPage_count());
        holder.buttonView.append(p.getDownload_url());

        return v;

    }

    public class JsonHolder {
        public TextView nameView;
        public TextView descView;
        public TextView pageView;
        public TextView sizeView;
        public ImageView imageView;
        public Button buttonView;
    }

    public List<Json> getItemList() {
        return itemList;
    }

    public void setItemList(List<Json> itemList) {
        this.itemList = itemList;
    }

}

mentre questo è il codice dell'activity nella parte in cui dovrebbe richiamare il layout

Codice (Java): [Seleziona]
TableAdapter adpt;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_table);


        adpt = new TableAdapter(new ArrayList<Json>(), this);
        ListView lView = (ListView) findViewById(R.id.listView);

        lView.setAdapter(adpt);
        (new AsyncListViewLoader()).execute(url);


    }

dov'è che sbaglio?