Advertisement
tuomasvaltanen

Untitled

Jan 11th, 2023 (edited)
154
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.64 KB | None | 0 0
  1. Edistynyt mobiiliohjelmointi, luento, 16.1.2023
  2.  
  3. JSON comments data:
  4. https://jsonplaceholder.typicode.com/comments
  5.  
  6.  
  7. ApiFragmentin ulkoasu:
  8.  
  9. <?xml version="1.0" encoding="utf-8"?>
  10. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  11. xmlns:tools="http://schemas.android.com/tools"
  12. android:layout_width="match_parent"
  13. android:layout_height="match_parent"
  14. android:orientation="vertical"
  15. tools:context=".ApiFragment">
  16.  
  17. <Button
  18. android:id="@+id/button_get_comments"
  19. android:layout_width="match_parent"
  20. android:layout_height="wrap_content"
  21. android:text="Button" />
  22. </LinearLayout>
  23.  
  24. ApiFragment.kt
  25.  
  26. onCreateViewiin ->
  27.  
  28. binding.buttonGetComments.setOnClickListener{
  29. getComments()
  30. }
  31.  
  32. ja uusi oma funktio:
  33.  
  34. fun getComments()
  35. {
  36. val JSON_URL = "https://jsonplaceholder.typicode.com/comments"
  37.  
  38. // Request a string response from the provided URL.
  39. val stringRequest: StringRequest = object : StringRequest(
  40. Request.Method.GET, JSON_URL,
  41. Response.Listener { response ->
  42.  
  43. // print the response as a whole
  44. // we can use GSON to modify this response into something more usable
  45. Log.d("ADVTECH", response)
  46.  
  47. },
  48. Response.ErrorListener {
  49. // typically this is a connection error
  50. Log.d("ADVTECH", it.toString())
  51. })
  52. {
  53. @Throws(AuthFailureError::class)
  54. override fun getHeaders(): Map<String, String> {
  55.  
  56. // basic headers for the data
  57. val headers = HashMap<String, String>()
  58. headers["Accept"] = "application/json"
  59. headers["Content-Type"] = "application/json; charset=utf-8"
  60. return headers
  61. }
  62. }
  63.  
  64. // Add the request to the RequestQueue. This has to be done in both getting and sending new data.
  65. // if using this in an activity, use "this" instead of "context"
  66. val requestQueue = Volley.newRequestQueue(context)
  67. requestQueue.add(stringRequest)
  68. }
  69.  
  70. Työkalu: https://json2kt.com/
  71. Laita yksittäisen JSON-objektin data pelkästään
  72.  
  73. Kopioi Comment.kt -tiedosto projektiisi, ja käytä sitä Response.Listenerissä:
  74.  
  75. val gson = GsonBuilder().setPrettyPrinting().create()
  76. var rows : List<Comment> = gson.fromJson(response, Array<Comment>::class.java).toList()
  77.  
  78. for(item: Comment in rows)
  79. {
  80. Log.d("ADVTECH", item.email.toString())
  81. }
  82.  
  83.  
  84. RecyclerView-tutorial, jota käytetään pohjana:
  85. https://www.raywenderlich.com/1560485-android-recyclerview-tutorial-with-kotlin
  86.  
  87. Lisätään RecyclerView ulkoasuun:
  88.  
  89. <?xml version="1.0" encoding="utf-8"?>
  90. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  91. xmlns:tools="http://schemas.android.com/tools"
  92. android:layout_width="match_parent"
  93. android:layout_height="match_parent"
  94. android:orientation="vertical"
  95. tools:context=".ApiFragment">
  96.  
  97. <Button
  98. android:id="@+id/button_get_comments"
  99. android:layout_width="match_parent"
  100. android:layout_height="wrap_content"
  101. android:text="Button" />
  102.  
  103. <androidx.recyclerview.widget.RecyclerView
  104. android:id="@+id/recyclerView_comments"
  105. android:layout_width="match_parent"
  106. android:layout_height="500dp" />
  107. </LinearLayout>
  108.  
  109. Fragmentissa, lisää funktioiden ulkopuolelle:
  110.  
  111. // alustetaan layout manager recyclerviewille
  112. private lateinit var linearLayoutManager: LinearLayoutManager
  113.  
  114. Fragmentissa, onCreateViewin sisälle:
  115.  
  116. // luodaan layout manager ja kytketään se recyclerviewiin ulkoasussa
  117. // huom, koska käytämme fragmentia, this-sanan sijasta käytetään -> context
  118. linearLayoutManager = LinearLayoutManager(context)
  119. binding.recyclerViewComments.layoutManager = linearLayoutManager
  120.  
  121. Tehdään yksittäiselle kommentille oma layout xml, esim.
  122.  
  123. <?xml version="1.0" encoding="utf-8"?>
  124. <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
  125. xmlns:app="http://schemas.android.com/apk/res-auto"
  126. xmlns:tools="http://schemas.android.com/tools"
  127. android:layout_width="match_parent"
  128. android:layout_height="160dp">
  129.  
  130. <TextView
  131. android:id="@+id/textView_comment_name"
  132. android:layout_width="wrap_content"
  133. android:layout_height="wrap_content"
  134. android:layout_margin="20dp"
  135. android:text="Nimi"
  136. android:textColor="#3F51B5"
  137. android:textStyle="bold"
  138. app:layout_constraintStart_toStartOf="parent"
  139. app:layout_constraintTop_toTopOf="parent" />
  140.  
  141. <TextView
  142. android:id="@+id/textView_comment_content"
  143. android:layout_width="wrap_content"
  144. android:layout_height="wrap_content"
  145. android:layout_margin="20dp"
  146. android:text="Sisältö"
  147. app:layout_constraintStart_toStartOf="parent"
  148. app:layout_constraintTop_toBottomOf="@+id/textView_comment_name" />
  149.  
  150. <TextView
  151. android:id="@+id/textView_comment_email"
  152. android:layout_width="wrap_content"
  153. android:layout_height="wrap_content"
  154. android:layout_margin="20dp"
  155. android:text="email"
  156. android:textColor="#8BC34A"
  157. android:textStyle="bold|italic"
  158. app:layout_constraintEnd_toEndOf="parent"
  159. app:layout_constraintTop_toTopOf="parent" />
  160. </androidx.constraintlayout.widget.ConstraintLayout>
  161.  
  162. // RECYCLER ADAPTER, VERSIO 1
  163.  
  164. package com.example.android2023tv
  165.  
  166. import android.util.Log
  167. import android.view.LayoutInflater
  168. import android.view.View
  169. import android.view.ViewGroup
  170. import androidx.recyclerview.widget.RecyclerView
  171. import com.example.android2023tv.databinding.RecyclerviewItemRowBinding
  172.  
  173. class RecyclerAdapter(private val comments: List<Comment>) :
  174. RecyclerView.Adapter<RecyclerAdapter.CommentHolder>() {
  175.  
  176. // alustetaan binding layet -> recyclerview_item_row.xml
  177. private var _binding: RecyclerviewItemRowBinding? = null
  178. private val binding get() = _binding!!
  179.  
  180. // RecyclerAdapter vaatii, että luokassa on toteutettuna:
  181. // getItemCount, onCreateViewHolder, OnBindViewHolder
  182.  
  183. // jotta RecyclerView tietää kuinka monta itemiä listassa on
  184. override fun getItemCount() = comments.size
  185.  
  186. // tämä funktio kytkee jokaisen yksittäisen datan listassa omaan ulkoasuunsa
  187. // (recyclerview_item_row.xml)
  188. override fun onBindViewHolder(holder: RecyclerAdapter.CommentHolder, position: Int) {
  189. val itemComment = comments[position]
  190. holder.bindComment(itemComment)
  191. }
  192.  
  193. // luodaan binding layer ja kytketään se CommentHolderiin
  194. override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerAdapter.CommentHolder {
  195. _binding = RecyclerviewItemRowBinding.inflate(LayoutInflater.from(parent.context), parent, false)
  196. return CommentHolder(binding)
  197. }
  198.  
  199. // CommentHolder kytkee datan ulkoasuun jokaisen itemin kohdalla
  200. class CommentHolder(v: RecyclerviewItemRowBinding) : RecyclerView.ViewHolder(v.root), View.OnClickListener {
  201.  
  202. // view => binding layer
  203. // comment => yksittäinen comment-data
  204. private var view: RecyclerviewItemRowBinding = v
  205. private var comment: Comment? = null
  206.  
  207. // v.root tarvitaan siksi, koska v on tässä tapauksessa binding layer, ei View
  208. // v.root on binding layerin pohjimmainen View, eli ulkoasu
  209.  
  210. init {
  211. v.root.setOnClickListener(this)
  212. }
  213.  
  214. // tätä fuktiota kutsutaan jokaisen comment-datan kohdalla
  215. // kun se asetetaan listaan
  216. // toisin sanoen, tässä funktiossa päätetään mikä muuttuja
  217. // kytketään mihinkiin Viewiin, esim. TextViewiin
  218. fun bindComment(comment: Comment)
  219. {
  220.  
  221. }
  222.  
  223. override fun onClick(v: View) {
  224. Log.d("RecyclerView", "CLICK!")
  225. }
  226. }
  227. }
  228.  
  229. // bindCommentissa määritetään mikä data menee mihinkin TextViewiin, esim.
  230.  
  231. fun bindComment(comment: Comment)
  232. {
  233. view.textViewCommentName.text = comment.name
  234. view.textViewCommentContent.text = comment.body
  235. view.textViewCommentEmail.text = comment.email
  236. }
  237.  
  238. // Fragmentissa, lisätään adapteri funktioiden ulkopuolelle:
  239. private lateinit var adapter: RecyclerAdapter
  240.  
  241. // Response.Listenerissä, jos rows-muuttujassa on lista kommenteista, silloin:
  242. adapter = RecyclerAdapter(rows)
  243. binding.recyclerViewComments.adapter = adapter
  244.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement