Advertisement
tuomasvaltanen

Untitled

Feb 3rd, 2023 (edited)
124
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 17.36 KB | None | 0 0
  1. // Edistynyt mobiiliohjelmointi, 3.2.2023
  2.  
  3. // data haetaan osoitteesta:
  4. // https://jsonplaceholder.typicode.com/comments
  5.  
  6. // CommentApiFragment -pohja:
  7.  
  8.  
  9. class CommentApiFragment : Fragment() {
  10. // change this to match your fragment name
  11. private var _binding: FragmentCommentApiBinding? = null
  12.  
  13. // This property is only valid between onCreateView and
  14. // onDestroyView.
  15. private val binding get() = _binding!!
  16.  
  17. override fun onCreateView(
  18. inflater: LayoutInflater,
  19. container: ViewGroup?,
  20. savedInstanceState: Bundle?
  21. ): View? {
  22. _binding = FragmentCommentApiBinding.inflate(inflater, container, false)
  23. val root: View = binding.root
  24.  
  25.  
  26.  
  27. // the binding -object allows you to access views in the layout, textviews etc.
  28.  
  29. return root
  30. }
  31.  
  32. override fun onDestroyView() {
  33. super.onDestroyView()
  34. _binding = null
  35. }
  36. }
  37.  
  38. // muokataan CommentFragmentApin ulkoasua (xml)
  39.  
  40. <?xml version="1.0" encoding="utf-8"?>
  41. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  42. xmlns:tools="http://schemas.android.com/tools"
  43. android:layout_width="match_parent"
  44. android:layout_height="match_parent"
  45. android:orientation="vertical"
  46. tools:context=".CommentApiFragment">
  47.  
  48. <Button
  49. android:id="@+id/button_get_comments"
  50. android:layout_width="wrap_content"
  51. android:layout_height="wrap_content"
  52. android:layout_margin="10dp"
  53. android:text="Get data" />
  54.  
  55. </LinearLayout>
  56.  
  57. // CommentApiFragment, ladataan data Volleylla
  58.  
  59. package com.example.edistynytmobiiliohjelmointi2023b
  60.  
  61. import android.os.Bundle
  62. import android.util.Log
  63. import androidx.fragment.app.Fragment
  64. import android.view.LayoutInflater
  65. import android.view.View
  66. import android.view.ViewGroup
  67. import androidx.navigation.findNavController
  68. import com.android.volley.AuthFailureError
  69. import com.android.volley.Request
  70. import com.android.volley.Response
  71. import com.android.volley.toolbox.StringRequest
  72. import com.android.volley.toolbox.Volley
  73. import com.example.edistynytmobiiliohjelmointi2023b.databinding.FragmentCommentApiBinding
  74. import com.example.edistynytmobiiliohjelmointi2023b.databinding.FragmentDataReadBinding
  75.  
  76. class CommentApiFragment : Fragment() {
  77. // change this to match your fragment name
  78. private var _binding: FragmentCommentApiBinding? = null
  79.  
  80. // This property is only valid between onCreateView and
  81. // onDestroyView.
  82. private val binding get() = _binding!!
  83.  
  84. override fun onCreateView(
  85. inflater: LayoutInflater,
  86. container: ViewGroup?,
  87. savedInstanceState: Bundle?
  88. ): View? {
  89. _binding = FragmentCommentApiBinding.inflate(inflater, container, false)
  90. val root: View = binding.root
  91.  
  92. binding.buttonGetComments.setOnClickListener {
  93. Log.d("TESTI", "Nappi toimii!")
  94. // haetaan kommentit rajapinnasta
  95. getComments()
  96. }
  97.  
  98. // the binding -object allows you to access views in the layout, textviews etc.
  99. return root
  100. }
  101.  
  102. // apunfunktio, joka hakee Volleylla dataa fragmenttiin
  103. fun getComments()
  104. {
  105. // this is the url where we want to get our data from
  106. val JSON_URL = "https://jsonplaceholder.typicode.com/comments"
  107.  
  108. // Request a string response from the provided URL.
  109. val stringRequest: StringRequest = object : StringRequest(
  110. Request.Method.GET, JSON_URL,
  111. Response.Listener { response ->
  112.  
  113. // print the response as a whole
  114. // we can use GSON to modify this response into something more usable
  115. Log.d("ADVTECH", response)
  116.  
  117. },
  118. Response.ErrorListener {
  119. // typically this is a connection error
  120. Log.d("ADVTECH", it.toString())
  121. })
  122. {
  123. @Throws(AuthFailureError::class)
  124. override fun getHeaders(): Map<String, String> {
  125.  
  126. // basic headers for the data
  127. val headers = HashMap<String, String>()
  128. headers["Accept"] = "application/json"
  129. headers["Content-Type"] = "application/json; charset=utf-8"
  130. return headers
  131. }
  132. }
  133.  
  134. // Add the request to the RequestQueue. This has to be done in both getting and sending new data.
  135. // if using this in an activity, use "this" instead of "context"
  136. val requestQueue = Volley.newRequestQueue(context)
  137. requestQueue.add(stringRequest)
  138. }
  139.  
  140. override fun onDestroyView() {
  141. super.onDestroyView()
  142. _binding = null
  143. }
  144. }
  145.  
  146. // GSONia varten tarvitaan data class, joka esittää yksittäistä kommenttidataa. tässä voi käyttää
  147. // json2kt.com -palvelua. esim.
  148.  
  149. import com.google.gson.annotations.SerializedName
  150.  
  151.  
  152. data class Comment (
  153.  
  154. @SerializedName("postId" ) var postId : Int? = null,
  155. @SerializedName("id" ) var id : Int? = null,
  156. @SerializedName("name" ) var name : String? = null,
  157. @SerializedName("email" ) var email : String? = null,
  158. @SerializedName("body" ) var body : String? = null
  159.  
  160. )
  161.  
  162. // Muutetaan GSONilla raaka JSON-data Kotlin-dataksi
  163.  
  164. class CommentApiFragment : Fragment() {
  165. // change this to match your fragment name
  166. private var _binding: FragmentCommentApiBinding? = null
  167.  
  168. // This property is only valid between onCreateView and
  169. // onDestroyView.
  170. private val binding get() = _binding!!
  171.  
  172. override fun onCreateView(
  173. inflater: LayoutInflater,
  174. container: ViewGroup?,
  175. savedInstanceState: Bundle?
  176. ): View? {
  177. _binding = FragmentCommentApiBinding.inflate(inflater, container, false)
  178. val root: View = binding.root
  179.  
  180. binding.buttonGetComments.setOnClickListener {
  181. Log.d("TESTI", "Nappi toimii!")
  182. // haetaan kommentit rajapinnasta
  183. getComments()
  184. }
  185.  
  186. // the binding -object allows you to access views in the layout, textviews etc.
  187. return root
  188. }
  189.  
  190. // apunfunktio, joka hakee Volleylla dataa fragmenttiin
  191. fun getComments()
  192. {
  193. // this is the url where we want to get our data from
  194. val JSON_URL = "https://jsonplaceholder.typicode.com/comments"
  195.  
  196. // alustetaan GSON-plugin
  197. val gson = GsonBuilder().setPrettyPrinting().create()
  198.  
  199. // Request a string response from the provided URL.
  200. val stringRequest: StringRequest = object : StringRequest(
  201. Request.Method.GET, JSON_URL,
  202. Response.Listener { response ->
  203.  
  204. // print the response as a whole
  205. // we can use GSON to modify this response into something more usable
  206. // Log.d("ADVTECH", response)
  207. var rows : List<Comment> = gson.fromJson(response, Array<Comment>::class.java).toList()
  208.  
  209. for(item in rows)
  210. {
  211. Log.d("ADVTECH", item.email.toString())
  212. }
  213.  
  214. },
  215. Response.ErrorListener {
  216. // typically this is a connection error
  217. Log.d("ADVTECH", it.toString())
  218. })
  219. {
  220. @Throws(AuthFailureError::class)
  221. override fun getHeaders(): Map<String, String> {
  222.  
  223. // basic headers for the data
  224. val headers = HashMap<String, String>()
  225. headers["Accept"] = "application/json"
  226. headers["Content-Type"] = "application/json; charset=utf-8"
  227. return headers
  228. }
  229. }
  230.  
  231. // Add the request to the RequestQueue. This has to be done in both getting and sending new data.
  232. // if using this in an activity, use "this" instead of "context"
  233. val requestQueue = Volley.newRequestQueue(context)
  234. requestQueue.add(stringRequest)
  235. }
  236.  
  237. override fun onDestroyView() {
  238. super.onDestroyView()
  239. _binding = null
  240. }
  241. }
  242.  
  243. // RecyclerView tarvitsee oman ulkoasu-xml:n jokaista kommenttia varten (eli miltä yksittäinen kommentti listassa näyttää)
  244.  
  245. <?xml version="1.0" encoding="utf-8"?>
  246. <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
  247. xmlns:app="http://schemas.android.com/apk/res-auto"
  248. xmlns:tools="http://schemas.android.com/tools"
  249. android:layout_width="match_parent"
  250. android:layout_height="140dp">
  251.  
  252. <TextView
  253. android:id="@+id/textView_comment_name"
  254. android:layout_width="wrap_content"
  255. android:layout_height="wrap_content"
  256. android:layout_margin="10dp"
  257. android:text="Kommentin name"
  258. android:textColor="#AB4CC5"
  259. android:textStyle="bold"
  260. app:layout_constraintStart_toStartOf="parent"
  261. app:layout_constraintTop_toTopOf="parent" />
  262.  
  263. <TextView
  264. android:id="@+id/textView_comment_email"
  265. android:layout_width="wrap_content"
  266. android:layout_height="wrap_content"
  267. android:layout_margin="10dp"
  268. android:text="Kommentin email"
  269. android:textColor="#3EA8BC"
  270. android:textStyle="bold|italic"
  271. app:layout_constraintEnd_toEndOf="parent"
  272. app:layout_constraintTop_toTopOf="parent" />
  273.  
  274. <TextView
  275. android:id="@+id/textView_comment_body"
  276. android:layout_width="wrap_content"
  277. android:layout_height="wrap_content"
  278. android:layout_margin="10dp"
  279. android:text="Kommentin body"
  280. app:layout_constraintStart_toStartOf="parent"
  281. app:layout_constraintTop_toBottomOf="@+id/textView_comment_name" />
  282. </androidx.constraintlayout.widget.ConstraintLayout>
  283.  
  284. // CommentAdapter
  285.  
  286. package com.example.edistynytmobiiliohjelmointi2023b
  287.  
  288. import android.view.LayoutInflater
  289. import android.view.View
  290. import android.view.ViewGroup
  291. import androidx.recyclerview.widget.RecyclerView
  292. import com.example.edistynytmobiiliohjelmointi2023b.databinding.RecyclerviewItemRowBinding
  293.  
  294. // aloitetaan luomalla uusi luokka CommentHolder
  295. class CommentAdapter(private val comments: List<Comment>) : RecyclerView.Adapter<CommentAdapter.CommentHolder>() {
  296. // tähän väliin tulee kaikki RecyclerView-adapterin vaatimat metodit
  297. // kuten onCreateViewHolder, onBindViewHolder sekä getItemCount
  298.  
  299. // binding layerin muuttujien alustaminen
  300. private var _binding: RecyclerviewItemRowBinding? = null
  301. private val binding get() = _binding!!
  302.  
  303. // ViewHolderin onCreate-metodi. käytännössä tässä kytketään binding layer
  304. // osaksi CommentHolder-luokkaan (adapterin sisäinen luokka)
  305. // koska CommentAdapter pohjautuu RecyclerViewin perusadapteriin, täytyy tästä
  306. // luokasta löytyä metodi nimeltä onCreateViewHolder
  307. override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CommentHolder {
  308. // binding layerina toimii yksitätinen recyclerview_item_row.xml -instanssi
  309. _binding = RecyclerviewItemRowBinding.inflate(LayoutInflater.from(parent.context), parent, false)
  310. return CommentHolder(binding)
  311. }
  312.  
  313. // tämä metodi kytkee yksittäisen Comment-objektin yksittäisen CommentHolder-instanssiin
  314. // koska CommentAdapter pohjautuu RecyclerViewin perusadapteriin, täytyy tästä
  315. // luokasta löytyä metodi nimeltä onBindViewHolder
  316. override fun onBindViewHolder(holder: CommentHolder, position: Int) {
  317. val itemComment = comments[position]
  318. holder.bindComment(itemComment)
  319. }
  320.  
  321. // Adapterin täytyy pysty tietämään sisältämänsä datan koko tämän metodin avulla
  322. // koska CommentAdapter pohjautuu RecyclerViewin perusadapteriin, täytyy tästä
  323. // luokasta löytyä metodi nimeltä getItemCount
  324. override fun getItemCount(): Int {
  325. return comments.size
  326. }
  327.  
  328. // CommentHolder, joka määritettiin oman CommentAdapterin perusmäärityksessä (ks. luokan yläosa)
  329. // Holder-luokka sisältää logiikan, jolla data ja ulkoasu kytketään toisiinsa
  330. class CommentHolder(v: RecyclerviewItemRowBinding) : RecyclerView.ViewHolder(v.root), View.OnClickListener {
  331.  
  332. // tämän kommentin ulkoasu ja varsinainen data
  333. private var view: RecyclerviewItemRowBinding = v
  334. private var comment: Comment? = null
  335.  
  336. // mahdollistetaan yksittäisen itemin klikkaaminen tässä luokassa
  337. init {
  338. v.root.setOnClickListener(this)
  339. }
  340.  
  341. // metodi, joka kytkee datan yksityiskohdat ulkoasun yksityiskohtiin
  342. fun bindComment(comment : Comment)
  343. {
  344. this.comment = comment
  345.  
  346. // asetetaan oikeat datat oikeaan kohtaan
  347. // ulkoasussa
  348. view.textViewCommentEmail.text = comment.email.toString()
  349. view.textViewCommentName.text = comment.name.toString()
  350. view.textViewCommentBody.text = comment.body.toString()
  351.  
  352. }
  353.  
  354. // jos itemiä klikataan käyttöliittymässä, ajetaan tämä koodio
  355. override fun onClick(v: View) {
  356.  
  357. }
  358. }
  359. }
  360.  
  361. // lisätään RecyclerView fragmentin ulkoasuun (CommentApiFragment)
  362.  
  363. <?xml version="1.0" encoding="utf-8"?>
  364. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  365. xmlns:tools="http://schemas.android.com/tools"
  366. android:layout_width="match_parent"
  367. android:layout_height="match_parent"
  368. android:orientation="vertical"
  369. tools:context=".CommentApiFragment">
  370.  
  371.  
  372. <Button
  373. android:id="@+id/button_get_comments"
  374. android:layout_width="wrap_content"
  375. android:layout_height="wrap_content"
  376. android:layout_margin="10dp"
  377. android:text="Get data" />
  378.  
  379. <androidx.recyclerview.widget.RecyclerView
  380. android:id="@+id/recyclerView_comments"
  381. android:layout_width="match_parent"
  382. android:layout_height="match_parent">
  383.  
  384. </androidx.recyclerview.widget.RecyclerView>
  385. </LinearLayout>
  386.  
  387. // CommentApiFragment, kytketään adapteri recyclerviewiin:
  388.  
  389. class CommentApiFragment : Fragment() {
  390. // change this to match your fragment name
  391. private var _binding: FragmentCommentApiBinding? = null
  392.  
  393. // alustetaan viittaus adapteriin sekä luodaan LinearLayoutManager
  394. // RecyclerView tarvitsee jonkin LayoutManagerin, joista yksinkertaisin on Linear
  395. private lateinit var adapter: CommentAdapter
  396. private lateinit var linearLayoutManager: LinearLayoutManager
  397.  
  398. // This property is only valid between onCreateView and
  399. // onDestroyView.
  400. private val binding get() = _binding!!
  401.  
  402. override fun onCreateView(
  403. inflater: LayoutInflater,
  404. container: ViewGroup?,
  405. savedInstanceState: Bundle?
  406. ): View? {
  407. _binding = FragmentCommentApiBinding.inflate(inflater, container, false)
  408. val root: View = binding.root
  409.  
  410. // asetetaan RecyclerViewille linear layout manager
  411. linearLayoutManager = LinearLayoutManager(context)
  412. binding.recyclerViewComments.layoutManager = linearLayoutManager
  413.  
  414. binding.buttonGetComments.setOnClickListener {
  415. Log.d("TESTI", "Nappi toimii!")
  416. // haetaan kommentit rajapinnasta
  417. getComments()
  418. }
  419.  
  420. // the binding -object allows you to access views in the layout, textviews etc.
  421. return root
  422. }
  423.  
  424. // apunfunktio, joka hakee Volleylla dataa fragmenttiin
  425. fun getComments()
  426. {
  427. // this is the url where we want to get our data from
  428. val JSON_URL = "https://jsonplaceholder.typicode.com/comments"
  429.  
  430. // alustetaan GSON-plugin
  431. val gson = GsonBuilder().setPrettyPrinting().create()
  432.  
  433. // Request a string response from the provided URL.
  434. val stringRequest: StringRequest = object : StringRequest(
  435. Request.Method.GET, JSON_URL,
  436. Response.Listener { response ->
  437.  
  438. // print the response as a whole
  439. // we can use GSON to modify this response into something more usable
  440. // Log.d("ADVTECH", response)
  441. var rows : List<Comment> = gson.fromJson(response, Array<Comment>::class.java).toList()
  442.  
  443. for(item in rows)
  444. {
  445. Log.d("ADVTECH", item.email.toString())
  446. }
  447.  
  448. // kytketään rajapinnasta ladattu data recyclerviewin adapteriin
  449. adapter = CommentAdapter(rows)
  450. binding.recyclerViewComments.adapter = adapter
  451.  
  452. },
  453. Response.ErrorListener {
  454. // typically this is a connection error
  455. Log.d("ADVTECH", it.toString())
  456. })
  457. {
  458. @Throws(AuthFailureError::class)
  459. override fun getHeaders(): Map<String, String> {
  460.  
  461. // basic headers for the data
  462. val headers = HashMap<String, String>()
  463. headers["Accept"] = "application/json"
  464. headers["Content-Type"] = "application/json; charset=utf-8"
  465. return headers
  466. }
  467. }
  468.  
  469. // Add the request to the RequestQueue. This has to be done in both getting and sending new data.
  470. // if using this in an activity, use "this" instead of "context"
  471. val requestQueue = Volley.newRequestQueue(context)
  472. requestQueue.add(stringRequest)
  473. }
  474.  
  475. override fun onDestroyView() {
  476. super.onDestroyView()
  477. _binding = null
  478. }
  479. }
  480.  
  481. // Com
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement