22 - Biblioteca Volley - Recuperar los datos de una tabla en formato Json (PHP y MySQL)

Problema

Implementar una aplicación que permita recuperar todas las filas de una tabla de articulos.

Tenemos la tabla en un servidor web llamada:

create table articulos (
    codigo int primary key AUTO_INCREMENT,
    descripcion varchar(50),
    precio float
);

Crearemos el proyecto 'Compose24'

Agregamos las dependencias de la biblioteca Volley:

dependencies {
        ...
        implementation 'com.android.volley:volley:1.2.0'
    }

Nuestra aplicación debe acceder a internet por lo que debemos pedir dicho permiso:

<uses-permission android:name="android.permission.INTERNET"/>

Debemos llamar a la URL:

    https://scratchya.com.ar/videosandroidjava/volley/listararticulos.php

En el servidor hay un archivo en PHP llamado 'listararticulos.php':

<?php
header('Content-Type: application/json');

require("conexion.php");

$conexion = retornarConexion();

$datos = mysqli_query($conexion, "select codigo,descripcion,precio from articulos");
$resultado = mysqli_fetch_all($datos, MYSQLI_ASSOC);
echo '{"lista":'.json_encode($resultado).'}';
?>

Y un segundo archivo 'conexion.php'

<?php
function retornarConexion() {
    $server="localhost";
    $usuario="xxxx";
    $clave="xxxx";
    $base="xxxx";
    $con=mysqli_connect($server,$usuario,$clave,$base) or die("problemas") ;
    mysqli_set_charset($con,'utf8'); 
    return $con;
}
?>

La interfaz visual final debe ser similar a:

biblioteca Volley Jetpack Compose

El código a implementar en Kotlin para obtener dicha funcionalidad es:

package com.tutorialesprogramacionya.compose24



import android.app.Activity
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.android.volley.Request
import com.android.volley.toolbox.JsonObjectRequest
import com.android.volley.toolbox.Volley


class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ListadoArticulos(this)
        setContent {
            PantallaPrincipal()
        }
    }
}

data class Articulo(val codigo: Int, val descripicon: String, val precio: Float)

val articulos = mutableStateListOf<Articulo>()

fun ListadoArticulos(activity: Activity) {
    val url = "https://scratchya.com.ar/videosandroidjava/volley/listararticulos.php"
    val requestQueue = Volley.newRequestQueue(activity)
    val jsonObjectRequest = JsonObjectRequest(
        Request.Method.GET,
        url,
        null,
        { response ->
            val jsonArray = response.getJSONArray("lista")
            articulos.clear()
            for (i in 0 until jsonArray.length()) {
                val registro = jsonArray.getJSONObject(i)
                val codigo = registro.getString("codigo")
                val descripcion = registro.getString("descripcion")
                val precio = registro.getString("precio")
                articulos.add(Articulo(codigo.toInt(), descripcion, precio.toFloat()))
            }
        },
        { error ->
        }
    )
    requestQueue.add(jsonObjectRequest)
}

@Composable
fun PantallaPrincipal() {
    LazyColumn() {
        items(articulos) { articulo ->
            Card(
                elevation = 5.dp,
                modifier = Modifier
                    .padding(10.dp)
                    .fillMaxWidth()
            ) {
                Column() {
                    Text(
                        text = "Codigo: ${articulo.codigo}",
                        fontSize = 18.sp,
                        modifier = Modifier.padding(start = 10.dp, end = 10.dp, bottom = 5.dp)
                    )
                    Text(
                        text = "Descripcion: ${articulo.descripicon}",
                        fontSize = 18.sp,
                        modifier = Modifier.padding(10.dp)
                    )
                    Text(
                        text = "Precio:${articulo.precio}",
                        fontSize = 16.sp,
                        modifier = Modifier.padding(10.dp)
                    )
                }
            }
        }
    }
}

Inmediatamente se inicia la aplicación procedemos a recuperar del servidor los datos que nos provee la url:

    val url = "https://scratchya.com.ar/videosandroidjava/volley/listararticulos.php"

El formato es un Json similar a:

biblioteca Volley Jetpack Compose

Creamos un objeto JsonObjectRequest y cuando recibimos la respuesta procedemos a cargar los datos en nuestra variable 'articulos', que como sabemos automáticamente actualizará la pantalla con la función composable 'PantallaPrincipal':

fun ListadoArticulos(activity: Activity) {
    val url = "https://scratchya.com.ar/videosandroidjava/volley/listararticulos.php"
    val requestQueue = Volley.newRequestQueue(activity)
    val jsonObjectRequest = JsonObjectRequest(
        Request.Method.GET,
        url,
        null,
        { response ->
            val jsonArray = response.getJSONArray("lista")
            articulos.clear()
            for (i in 0 until jsonArray.length()) {
                val registro = jsonArray.getJSONObject(i)
                val codigo = registro.getString("codigo")
                val descripcion = registro.getString("descripcion")
                val precio = registro.getString("precio")
                articulos.add(Articulo(codigo.toInt(), descripcion, precio.toFloat()))
            }
        },
        { error ->
        }
    )
    requestQueue.add(jsonObjectRequest)
}

La función composable PantallaPrincipal procede a mostrar en una tarjeta (Card) individual los datos de cada artículo:

@Composable
fun PantallaPrincipal() {
    LazyColumn() {
        items(articulos) { articulo ->
            Card(
                elevation = 5.dp,
                modifier = Modifier
                    .padding(10.dp)
                    .fillMaxWidth()
            ) {
                Column() {
                    Text(
                        text = "Codigo: ${articulo.codigo}",
                        fontSize = 18.sp,
                        modifier = Modifier.padding(start = 10.dp, end = 10.dp, bottom = 5.dp)
                    )
                    Text(
                        text = "Descripcion: ${articulo.descripicon}",
                        fontSize = 18.sp,
                        modifier = Modifier.padding(10.dp)
                    )
                    Text(
                        text = "Precio:${articulo.precio}",
                        fontSize = 16.sp,
                        modifier = Modifier.padding(10.dp)
                    )
                }
            }
        }
    }
}

Este proyecto lo puede descargar en un zip desde este enlace: Compose24.zip