Docsity
Docsity

Prepara i tuoi esami
Prepara i tuoi esami

Studia grazie alle numerose risorse presenti su Docsity


Ottieni i punti per scaricare
Ottieni i punti per scaricare

Guadagna punti aiutando altri studenti oppure acquistali con un piano Premium


Guide e consigli
Guide e consigli


Android (kotlin) - reclycler list, Dispense di Sviluppo di Applicazioni Web

recycler view, recycler list, kotlin, android

Tipologia: Dispense

2022/2023

In vendita dal 04/09/2023

carla-boscolo
carla-boscolo 🇮🇹

4.5

(13)

520 documenti

1 / 45

Toggle sidebar

Questa pagina non è visibile nell’anteprima

Non perderti parti importanti!

bg1
cmd+ option + l indenta codice
APPLICARE TEMA SCURO APP 1
CREAZIONE PROGETTO DA ZERO CON RECYCLERVIEW E VIEWMODEL 2
AGGIUNGERE UN ELEMENTO 11
MODIFICA UN ELEMENTO 13
ELIMINA ELEMENTO 15
CREARE UNA TOPBAR 16
AGGIUNGERE LA PROGRESSBAR DI CARICAMENTO 21
AGGIUNGO I PREFERITI 29
AGGIUNGO IL MENU IN BASSO (BOTTOM NAVIGATION) 36
APPLICARE TEMA SCURO APP
res/values/themes
tema scuro
<style name="Base.Theme.Recycler"
parent="Theme.Material3.DayNight.NoActionBar">
<!-- Aggiungi questa riga per impostare il colore di sfondo scuro -->
<item
name="android:windowBackground">@android:color/background_dark</item>
<!-- Customize your light theme here. -->
<!-- <item name="colorPrimary">@color/my_light_primary</item> -->
</style>
<style name="Theme.Recycler" parent="Base.Theme.Recycler" /> -
tema chiaro
<style name="Base.Theme.Recycler"
parent="Theme.Material3.DayNight.NoActionBar">
<!-- Customize your light theme here. -->
<!-- <item name="colorPrimary">@color/my_light_primary</item> -->
</style>
<style name="Theme.Recycler" parent="Base.Theme.Recycler" />
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14
pf15
pf16
pf17
pf18
pf19
pf1a
pf1b
pf1c
pf1d
pf1e
pf1f
pf20
pf21
pf22
pf23
pf24
pf25
pf26
pf27
pf28
pf29
pf2a
pf2b
pf2c
pf2d

Anteprima parziale del testo

Scarica Android (kotlin) - reclycler list e più Dispense in PDF di Sviluppo di Applicazioni Web solo su Docsity!

cmd+ option + l → indenta codice APPLICARE TEMA SCURO APP 1 CREAZIONE PROGETTO DA ZERO CON RECYCLERVIEW E VIEWMODEL 2 AGGIUNGERE UN ELEMENTO 11 MODIFICA UN ELEMENTO 13 ELIMINA ELEMENTO 15 CREARE UNA TOPBAR 16 AGGIUNGERE LA PROGRESSBAR DI CARICAMENTO 21 AGGIUNGO I PREFERITI 29 AGGIUNGO IL MENU IN BASSO (BOTTOM NAVIGATION) 36

APPLICARE TEMA SCURO APP

res/values/themes tema scuro

CREAZIONE PROGETTO DA ZERO CON

RECYCLERVIEW E VIEWMODEL

  1. build.gradle(app) android { .. buildFeatures{ viewBinding true } }

  2. manifests

  3. inizializza inflater in mainActivity class MainActivity : AppCompatActivity() { private lateinit var binding: ActivityMainBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // setContentView(R.layout.activity_main) binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) } } In Android, a quale scopo viene utilizzato il LayoutInflater? Creare un’istanza di un file XML all’interno di una View

  4. recycler nel xml

android:layout_height="wrap_content" android:src="@drawable/edit_icon"/>

  1. inserire icone (drawable/new/vector asset) clicca clipart scegli nome da mettere in xml (se fosse invece icona app -> mimpap e setti in manifest, android:icon="@mipmap/ic_launcher)
  2. new-> kotlin class data class Product(var title: String?, var description: String?) : Serializable
  3. creare il viewmodel package com.example.recycler.ViewModel class ProductViewModel { private var products: ArrayList = arrayListOf() fun createProduct(){ val product = Product(title = "postino", description = "ciao") products.add(product) } }
  4. creo adapter package com.example.recycler.ViewModel import android.view.LayoutInflater import android.view.ViewGroup

import androidx.recyclerview.widget.RecyclerView import com.example.recycler.databinding.ViewProductBinding class ProductAdapter( var products: ArrayList) : RecyclerView.Adapter() { // Metodo chiamato quando viene creato un nuovo ViewHolder override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val binding = ViewProductBinding.inflate(LayoutInflater.from(parent.context), parent, false) return ViewHolder(binding) } // Metodo chiamato quando si legano i dati ad un ViewHolder esistente override fun onBindViewHolder(holder: ViewHolder, position: Int) { val product = products[position] holder.bind(product) } // Metodo chiamato per ottenere il numero totale di elementi nella lista override fun getItemCount(): Int { return products.size } // ViewHolder che rappresenta la vista di un singolo elemento nella RecyclerView inner class ViewHolder( private val binding: ViewProductBinding) : RecyclerView.ViewHolder(binding.root) { fun bind(product: Product) { // Effettua il binding dei dati del prodotto alla vista del ViewHolder binding.title.text = product.title binding.description.text = product.description.toString() } } }

  1. aggiungere il get in viewModel fun getProducts(): ArrayList { return products }
  2. inizializzo il viewModel e istanzio la lista dei prodotti package com.example.recycler import androidx.appcompat.app.AppCompatActivity

private var itemClickCallback: ItemClickCallback? = null fun setOnItemClickCallback(callback: ItemClickCallback) { itemClickCallback = callback } // Metodo chiamato quando viene creato un nuovo ViewHolder override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val binding = ViewProductBinding.inflate(LayoutInflater.from(parent.context), parent, false) return ViewHolder(binding) } // Metodo chiamato quando si legano i dati ad un ViewHolder esistente override fun onBindViewHolder(holder: ViewHolder, position: Int) { val product = products[position] holder.bind(product) holder.itemView.setOnClickListener { itemClickCallback?.onItemClick(position) } } // Metodo chiamato per ottenere il numero totale di elementi nella lista override fun getItemCount(): Int { return products.size } // ViewHolder che rappresenta la vista di un singolo elemento nella RecyclerView inner class ViewHolder( private val binding: ViewProductBinding) : RecyclerView.ViewHolder(binding.root) { fun bind(product: Product) { // Effettua il binding dei dati del prodotto alla vista del ViewHolder binding.title.text = product.title binding.description.text = product.description } } }

  1. aggiungere il layout manager per visualizzare la lista nell’activity

Quando si imposta il LayoutManager di un RecyclerView, si definisce come gli

elementi all'interno della RecyclerView devono essere visualizzati. Nel caso

specifico, LinearLayoutManager viene utilizzato per disporre gli elementi della

RecyclerView in un elenco verticale o orizzontale, a seconda del costruttore

utilizzato.

package com.example.recycler import android.content.Intent import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.util.Log import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.example.recycler.ViewModel.ProductAdapter import com.example.recycler.ViewModel.ProductViewModel import com.example.recycler.databinding.ActivityMainBinding class MainActivity : AppCompatActivity() { private lateinit var binding: ActivityMainBinding private lateinit var recyclerView: RecyclerView private lateinit var productViewModel: ProductViewModel private lateinit var productAdapter: ProductAdapter override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // setContentView(R.layout.activity_main) binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) // Inizializzazione del ProductViewModel productViewModel = ProductViewModel() productViewModel.createProduct() val productList = productViewModel.getProducts() /* for (product in productList) { Log.d("Prodotti", "Titolo del prodotto: ${product.title}") } */ //inizializza recycler recyclerView = binding.recyclerView //recyclerView = findViewById(R.id.recyclerView) stessa cosa //inizializza adapter productAdapter = ProductAdapter(ArrayList()) productAdapter.products = productList productAdapter.notifyDataSetChanged()

override fun onItemClick(position: Int) { val product = productAdapter.products[position] Log.d("Cliccato", "Ho cliccato la cella $position $product") val intent = Intent( this @MainActivity, DetailActivity::class.java) intent.putExtra("product", product) startActivity(intent) } })

  1. prendere i valori di product e assegnarli nei detail controllando che non arrivi null package com.example.recycler import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.util.Log import com.example.recycler.ViewModel.Product import com.example.recycler.databinding.ActivityDetailBinding class DetailActivity : AppCompatActivity() { private lateinit var binding: ActivityDetailBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) //setContentView(R.layout.activity_detail) binding = ActivityDetailBinding.inflate(layoutInflater) setContentView(binding.root) var product = intent.getSerializableExtra("product") as? Product Log.d("DetailProdotti", "Ecco i prodotti ${product?.title}") product?.let { param -> binding.title.text = param.title binding.description.text = param.description } } }

AGGIUNGERE UN ELEMENTO

  1. aggiungi bottone a main xml
  1. crea la strutture per il popup (dialog_add_item)

MODIFICA UN ELEMENTO

  1. aggiungo interfaccia in adapter e click sul tasto edit interface ItemClickCallback { fun onItemClick(position: Int) fun onEditClick(position: Int) } .. // ViewHolder che rappresenta la vista di un singolo elemento nella RecyclerView inner class ViewHolder( private val binding: ViewProductBinding) : RecyclerView.ViewHolder(binding.root) { fun bind(product: Product) { // Effettua il binding dei dati del prodotto alla vista del ViewHolder binding.title.text = product.title binding.description.text = product.description binding.editButton.setOnClickListener { itemClickCallback?.onEditClick(adapterPosition) } } }
  2. aggiungo implementazione del metodo dell’interfaccia //usare l'interfaccia per aprire detail quando clicco sulla cella productAdapter.setOnItemClickCallback(object : ProductAdapter.ItemClickCallback { override fun onItemClick(position: Int) { val product = productAdapter.products[position] Log.d("Cliccato", "Ho cliccato la cella $position $product") val intent = Intent( this @MainActivity, DetailActivity::class.java) intent.putExtra("product", product) startActivity(intent) } override fun onEditClick(position: Int) { val product = productAdapter.products[position] showAddItemDialog(product) } })
  1. aggiungo il metodo per modificare nel viewModel //modifica il prodotto fun editProduct(product: Product, newTitle: String , newDescription: String ) { product.title = newTitle product.description = newDescription }
  2. modifica la logica del popup add per inserire i campi precompilando private fun showAddItemDialog(productToEdit: Product? = null) { val dialogBinding = DialogAddItemBinding.inflate(layoutInflater) val titleEditText = dialogBinding.titleEditText val descriptionEditText = dialogBinding.descriptionEditText //li inserisce nel popup se esistono già if (productToEdit != null) { titleEditText.setText(productToEdit.title) descriptionEditText.setText(productToEdit.description) } val dialogBuilder = AlertDialog.Builder( this ) .setView(dialogBinding.root) .setTitle(if (productToEdit != null) "Modifica elemento" else "Aggiungi elemento") .setPositiveButton(if (productToEdit != null) "Salva" else "Aggiungi") { dialog, which -> val title = titleEditText.text.toString() val description = descriptionEditText.text.toString() if (productToEdit != null) { // Modifica l'elemento esistente productViewModel.editProduct(productToEdit, title, description) productAdapter.notifyDataSetChanged() } else { // Aggiungi un nuovo elemento val product = Product(title, description) productList.add(product) productAdapter.notifyDataSetChanged() } } .setNegativeButton("Annulla", null) val addItemDialog = dialogBuilder.create() addItemDialog.show() }

fun deleteProduct(product: Product) { products.remove(product) } }

  1. implemento interfaccia nel main //usare l'interfaccia per aprire detail quando clicco sulla cella productAdapter.setOnItemClickCallback(object : ProductAdapter.ItemClickCallback { override fun onItemClick(position: Int) { val product = productAdapter.products[position] Log.d("Cliccato", "Ho cliccato la cella $position $product") val intent = Intent( this @MainActivity, DetailActivity::class.java) intent.putExtra("product", product) startActivity(intent) } override fun onEditClick(position: Int) { val product = productAdapter.products[position] showAddItemDialog(product) } override fun onDeleteClick(position: Int) { val product = productAdapter.products[position] productViewModel.deleteProduct(product) productAdapter.notifyDataSetChanged() } })

CREARE UNA TOPBAR

topbar con un bottone + che aggiunge un elementio e un cestino che cancella tutti gli elementi in MainActivity

  1. aggiungo la topBar in xml come custom in un nuovo file (sarà vuota petchè i bottoni verranno aggiunti dalla risorsa menu)

android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/ThemeOverlay.AppCompat.ActionBar">

  1. creo risorsa per la topBar custom menu (cioè i bottoni che verranno inseriti nella topBar) res/new/resources file in “directory name” inserisco “menu”, lo chiamo “toolbar_menu” - aggiungo le icone necessarie
  1. inserisco la topBar custom in activity e detail xml activity
  1. aggiungo la topBar in MainActivity (solo con titolo) onCreate.. // Imposta la Toolbar come ActionBar utilizzando il binding setSupportActionBar(binding.topBar.toolbar) supportActionBar?.title = "Home"
  2. aggiungo la topBar in Detail (solo con titolo e tasto back) onCreate.. // Imposta la Toolbar come ActionBar utilizzando il binding setSupportActionBar(binding.topBar.toolbar) //serve per inserire tasto back supportActionBar?.setDisplayHomeAsUpEnabled(true) var product = intent.getSerializableExtra("product") as? Product Log.d("DetailProdotti", "Ecco i prodotti ${product?.title}") product?.let { param -> //inserisici il titolo alla pagina in base a quello cliccato

supportActionBar?.title = param.title binding.title.text = param.title binding.description.text = param.description } per far funzionare il tasto back, sotto onCreate //topBar back button override fun onOptionsItemSelected(item: MenuItem): Boolean { return when (item.itemId) { android.R.id.home -> { onBackPressed() // Torna alla schermata precedente quando viene selezionato l'elemento home true } else -> super.onOptionsItemSelected(item) } }

  1. creo logica per eliminare tutti gli elementi nel viewModel //cancella tutti i prodotti fun deleteAllProducts() { products.clear() }
  2. implemento il menu in MainActivity dove cliccando sul cestino apre funzione per eliminare tutti i dati (usando la funzione del viewModel), mentre con + usa la logica esistente per aggiungere un elemento. sotto onCreate.. //Gestione dei bottoni della topBar override fun onCreateOptionsMenu(menu: Menu): Boolean { menuInflater.inflate(R.menu.toolbar_menu, menu) return true } override fun onOptionsItemSelected(item: MenuItem): Boolean { return when (item.itemId) { //altro modo di aggiungere un elemento R.id.action_add -> { showAddItemDialog() true