JSON en Kotlin
qué es JSON
Ejemplo:
xml | json |
<listado> <persona> <nombre>Juan</nombre> <apellidos>Palomo</apellidos> <fecha>20/10/1980</fecha> </persona> <persona> <nombre>Pepe</nombre> <apellidos>Gotera</apellidos> <fecha>7/8/1990</fecha> </persona> </listado> |
{"listado": [ { "nombre":"Juan", "apellidos":"Palomo", "fecha": "20/10/1980" }, { "nombre": "Pepe", "apellidos": "Gotera", "fecha": "7/8/1990" } ] } |
Ejemplo: repositorios de un usuario en GitHub
https://api.github.com/users/paco-portada/repos
Extensión JSONView: Permite abrir documentos JSON en el navegador Firefox.
Json y Android
Clase JSONObject
JSONObject(String json) | Creates a new JSONObject with name/value mappings from the JSON string. |
getInt(String name) | Returns the value mapped by name if it exists and is an int or can becoerced to an int, or throws otherwise. |
getString(String name) | Returns the value mapped by name if it exists, coercing it if necessary, or throws if no such mapping exists. |
getJSONObject(String name) | Returns the value mapped by name if it exists and is a JSONObject, or throws otherwise. |
put(String name, int value) | Maps name to value, clobbering any existing name/value mapping with the same name. |
toString() | Encodes this object as a compact JSON string. |
Clase JSONArray
JSONArray(String json) | Creates a new JSONArray with values from the JSON string. |
toString(int indentSpaces) | Encodes this array as a human readable JSON string for debugging |
getJSONArray(String name) | Returns the value mapped by name if it exists and is a JSONArray or throws otherwise |
Parsing JSON in Android
Ejemplo: Lista de contactos
Crear una aplicación que lea una lista de contactos almacenada en un fichero en formato json (situado en la carpeta res/raw o en la tarjeta de memoria).
Cada contacto contendrá los campos: nombre, dirección, email y teléfono. En el teléfono se podrán guardar tres valores (casa, móvil y trabajo).
Crear el proyecto Lista Contactos Kotlin
Estructura del proyecto
¿contactos.json?
añadir contactos.json a la carpeta assets
view Binding en build.gradle
buildFeatures { viewBinding = true }
acitvity_main.xml
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Lista de contactos" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintHorizontal_bias="0.498" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.022" /> <Switch android:id="@+id/switch1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:checked="false" android:text="Gson" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.95" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/textView" /> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="24dp" android:layout_marginBottom="16dp" android:text="Mostrar" app:layout_constraintBottom_toTopOf="@+id/recyclerView" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.462" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/textView" /> <androidx.recyclerview.widget.RecyclerView android:id="@+id/recyclerView" android:layout_width="362dp" android:layout_height="561dp" android:layout_marginBottom="28dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.326" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/button" /> </androidx.constraintlayout.widget.ConstraintLayout>
item_contact.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:paddingTop="10dp" android:paddingBottom="10dp"> <TextView android:id="@+id/contact_name" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:text="name" android:textAppearance="@style/TextAppearance.AppCompat.Large" android:textColor="#2196F3" /> <TextView android:id="@+id/mobile_phone" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:text="TextView" /> </LinearLayout>
Telefono.kt
data class Telefono ( var casa: String, var movil: String, var trabajo: String )
Contacto.kt
data class Contacto ( var nombre: String, var direccion: String, var email: String, var telefono: Telefono )
ContactosAdapter.kt
class ContactosAdapter(private var mContactos: List<Contacto>) : RecyclerView.Adapter<ContactosAdapter.ViewHolder>() { inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { val binding = ItemContactBinding.bind(itemView) } override fun onCreateViewHolder( parent: ViewGroup, viewType: Int ): ViewHolder { val context = parent.context val inflater = LayoutInflater.from(context) val contactView = inflater.inflate(R.layout.item_contact, parent, false) return ViewHolder(contactView) } override fun onBindViewHolder(holder: ViewHolder, position: Int) { // Get the data model based on position val contact = mContactos[position] // Set item views based on your views and data model holder.binding.contactName.text = contact.nombre holder.binding.mobilePhone.text = contact.telefono.movil } // Returns the total count of items in the list override fun getItemCount(): Int { return mContactos.size } fun actualizar(data: List<Contacto>) { mContactos = data notifyDataSetChanged() } }
MainActivity.kt
class MainActivity : Activity(), View.OnClickListener { private lateinit var binding: ActivityMainBinding lateinit var adapter: ContactosAdapter companion object { const val CONTACTOS = "contactos.json" const val CONTACTS = "contacts.json" } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // setContentView(R.layout.activity_main) binding = ActivityMainBinding.inflate(layoutInflater) val view: View = binding.root setContentView(view) binding.button.setOnClickListener(this) crearAdapter() // onClick(binding.button); } private fun crearAdapter() { // Create adapter passing in the sample user data adapter = ContactosAdapter(obtenerContactos()) // Attach the adapter to the recyclerview to populate items binding.recyclerView.adapter = adapter // Set layout manager to position the items binding.recyclerView.layoutManager = LinearLayoutManager(this) } override fun onClick(v: View) { var contactos: ArrayList<Contacto> = obtenerContactos() if (v === binding.button) { if (contactos.size > 0) // adapter.notifyDataSetChanged(); // adapter.notifyItemRangeChanged(0, contactos.size()); adapter.actualizar(contactos) else mostrarMensaje("Error al obtener los contactos") } } fun obtenerContactos(): ArrayList<Contacto> { var contactos: ArrayList<Contacto> = ArrayList() lateinit var contenido: String lateinit var gson: Gson lateinit var persona: Persona lateinit var telefono: Telefono try { if (!binding.switch1.isChecked) { // Analizar contactos contenido = leerAsset(applicationContext, CONTACTOS) contactos = analizarContactos(contenido) } else { // usar Gson } } catch (e: IOException) { Log.e("Error: ", e.message.toString()) mostrarMensaje("Error: " + e.message.toString()) //} catch (e: JsonSyntaxException) { // Log.e("Error: ", e.message.toString()) // mostrarMensaje("Error: " + e.message.toString()) } catch (e: JSONException) { //e.printStackTrace(); Log.e("Error: ", e.message.toString()) mostrarMensaje("Error: " + e.message.toString()) } return contactos } @Throws(IOException::class) fun leerAsset(context: Context, fileName: String): String { val jsonString: String jsonString = context.assets.open(fileName).bufferedReader().use { it.readText() } return jsonString } private fun mostrarMensaje(texto: String) { Toast.makeText(this, texto, Toast.LENGTH_SHORT).show() } }
Análisis del fichero json
Utils/Analisis.kt
object Analisis { @Throws(JSONException::class) fun analizarContactos(cadena: String?): ArrayList<Contacto> { val jAcontactos: JSONArray val objeto: JSONObject var jOcontacto: JSONObject var jOtelefono: JSONObject var contacto: Contacto var telefono: Telefono val personas = ArrayList<Contacto>() // añadir contactos (en formato JSON) a personas } }
Deja una respuesta
Lo siento, debes estar conectado para publicar un comentario.