Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Edistynyt mobiiliohjelmointi, 6.2.2023
- // hienosäätöjä, lyhennettään kommentin nimeä jos liian pitkä, CommentHolder::
- fun bindComment(comment : Comment)
- {
- // otetaan kommentti talteen ylätasolle, että voimme käyttää sitä myös esim. onClickissä
- this.comment = comment
- // tallennetaan kommentin nimi Stringiksi
- var commentName : String = comment.name as String
- // jos kommentin nimi on yli 20 merkkiä,
- // lyhennetään se 20:een merkkiin ja lisätään kolme pistettä
- if(commentName.length > 20)
- {
- commentName = commentName.substring(0, 20) + "..."
- }
- // oli kommentin nimi mitä tahansa, asetetaan se käyttöliittymään
- view.textViewCommentName.text = commentName
- // asetetaan muut tiedot ulkoasuun
- view.textViewCommentEmail.text = comment.email
- view.textViewCommentBody.text = comment.body
- }
- // RecyclerView, itemin klikkaaminen ja siirtyminen toiseen fragmentiin
- // tätä varten on tehty ApiDetailFragment
- // tarkista että seuraava on asetettu init:iin, jotta
- // onClick ylipäätänsä toimii
- init {
- v.root.setOnClickListener(this)
- }
- // jos itemiä klikataan käyttöliittymässä, ajetaan tämä koodio
- override fun onClick(v: View) {
- Log.d("ADVTECH", "RecyclerView CLICK!!! " + comment?.id.toString())
- // muutetaan Int? => Int
- val commentId = comment?.id as Int
- // navigoidaan ApiFragmentista -> ApiDetailFragment, parametrina kommentin id
- val action = ApiFragmentDirections.actionApiFragmentToApiDetailFragment(commentId)
- v.findNavController().navigate(action)
- }
- // ApiDetailFragmentissa voidaan ottaa muuttuja vastaan
- class ApiDetailFragment : Fragment() {
- private var _binding: FragmentApiDetailBinding? = null
- // get fragment parameters from previous fragment
- val args: DataDetailFragmentArgs by navArgs()
- // This property is only valid between onCreateView and
- // onDestroyView.
- private val binding get() = _binding!!
- override fun onCreateView(
- inflater: LayoutInflater,
- container: ViewGroup?,
- savedInstanceState: Bundle?
- ): View? {
- _binding = FragmentApiDetailBinding.inflate(inflater, container, false)
- val root: View = binding.root
- // print out the given parameter into logs
- Log.d("ADVTECH", "ID = " + args.id.toString())
- val JSON_URL = "https://jsonplaceholder.typicode.com/comments/" + args.id.toString()
- Log.d("ADVTECH", JSON_URL)
- // Tästä eteenpäin datan voi hakea kolmella tavalla:
- // 1. Käydä id:tä URLin muodostamisessa (ks. ylempää JSON_URL) ja hae Volleylla sen avulla
- // pelkästään kyseisen id:n takana oleva kommenttidata (yksittäinen JSON-objekti)
- // huomaa tässä tapauksessa että GSON -muunnoksessa pitää käyttää yhden objektin esimerkkiä
- // var item : Comment = gson.fromJson(response, Comment::class.java)
- // hyvät puolet: aina ajantasainen data
- // huono puoli: enemmän koodia
- // 2. laita fragmenttien välille lisää parametreja (esim. kommentin id, name, email, body jne)
- // ja aseta nämä argumentit suoraan omiin TextVieweihin ApiDetailFragmentin koodissa
- // hyvät puolet: yksinkertainen koodi, huomattavasti vähemmän tietoliikennettä
- // huono puoli: data voi olla vanhentunut
- // 3. muuta koko comment-olio aiemmassa fragmentissa JSON-formaattiin, ja siirrä vain
- // JSON-muuttuja tähän fragmenttiin
- // hyvät ja huonot puolet samat kuin vaihtoehdossa 2, mutta lisäksi vaatii GSON-muunnoksen
- // molemmissa fragmenteissa
- // ApiFragment -> comment-olio -> JSON ..... ja myöhemmin ApiDetailFragment: JSON -> comment-olio
- return root
- }
- override fun onDestroyView() {
- super.onDestroyView()
- _binding = null
- }
- }
- // Google MapsFragment, xml-ulkoasu
- // Siirretään MapsFragment ConstraintLayoutin sisälle, että voidaan laittaa lisää
- // Viewejä kartan päälle
- // HUOM: attribuutti "tools:layout="@layout/fragment_home" avulla
- // XML-virhe poistuu (unknown fragments), koska asetamme ulkoasueditoria varten
- // placeholderiksi home-fragmentin
- <?xml version="1.0" encoding="utf-8"?>
- <androidx.constraintlayout.widget.ConstraintLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- tools:context=".MapsFragment">
- <fragment
- android:id="@+id/map"
- android:name="com.google.android.gms.maps.SupportMapFragment"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- tools:layout="@layout/fragment_home" />
- </androidx.constraintlayout.widget.ConstraintLayout>
- // MapsFragment, lisätään binding-layer
- class MapsFragment : Fragment() {
- // change this to match your fragment name
- private var _binding: FragmentMapsBinding? = null
- // This property is only valid between onCreateView and
- // onDestroyView.
- private val binding get() = _binding!!
- private val callback = OnMapReadyCallback { googleMap ->
- /**
- * Manipulates the map once available.
- * This callback is triggered when the map is ready to be used.
- * This is where we can add markers or lines, add listeners or move the camera.
- * In this case, we just add a marker near Sydney, Australia.
- * If Google Play services is not installed on the device, the user will be prompted to
- * install it inside the SupportMapFragment. This method will only be triggered once the
- * user has installed Google Play services and returned to the app.
- */
- val sydney = LatLng(-34.0, 151.0)
- googleMap.addMarker(MarkerOptions().position(sydney).title("Marker in Sydney"))
- val rovaniemi = LatLng(66.50352001528042, 25.727189822733095)
- googleMap.addMarker(MarkerOptions().position(rovaniemi).title("Rovaniemi!"))
- // newLatLngZoomin avulla voidaan siirtää kameraa ja myös zoomata
- googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(rovaniemi, 15f))
- }
- override fun onCreateView(
- inflater: LayoutInflater,
- container: ViewGroup?,
- savedInstanceState: Bundle?
- ): View? {
- _binding = FragmentMapsBinding.inflate(inflater, container, false)
- val root: View = binding.root
- return root
- }
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- super.onViewCreated(view, savedInstanceState)
- val mapFragment = childFragmentManager.findFragmentById(R.id.map) as SupportMapFragment?
- mapFragment?.getMapAsync(callback)
- }
- }
- // MapsFragment, xml, lisätään CheckBox
- <?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=".MapsFragment">
- <fragment
- android:id="@+id/map"
- android:name="com.google.android.gms.maps.SupportMapFragment"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- tools:layout="@layout/fragment_home" />
- <CheckBox
- android:id="@+id/checkBox_zoom_controls"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_margin="10dp"
- android:text="Zoom ON/OFF"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toTopOf="parent" />
- </androidx.constraintlayout.widget.ConstraintLayout>
- // MapsFragment, otetaan googleMap-olio talteen että pääsemme siihen käsiksi muualla luokassa
- // esim. checkboxit ja radiobuttonit
- class MapsFragment : Fragment() {
- // change this to match your fragment name
- private var _binding: FragmentMapsBinding? = null
- // This property is only valid between onCreateView and
- // onDestroyView.
- private val binding get() = _binding!!
- private val callback = OnMapReadyCallback { googleMap ->
- // laitetaan googleMap-olio talteen luokan tasolle (gMap)
- gMap = googleMap
- val sydney = LatLng(-34.0, 151.0)
- googleMap.addMarker(MarkerOptions().position(sydney).title("Marker in Sydney"))
- val rovaniemi = LatLng(66.50352001528042, 25.727189822733095)
- googleMap.addMarker(MarkerOptions().position(rovaniemi).title("Rovaniemi!"))
- // newLatLngZoomin avulla voidaan siirtää kameraa ja myös zoomata
- googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(rovaniemi, 15f))
- }
- // jotta pääsemme käsiksi googleMap-objektiin myöhemmin
- private lateinit var gMap : GoogleMap
- override fun onCreateView(
- inflater: LayoutInflater,
- container: ViewGroup?,
- savedInstanceState: Bundle?
- ): View? {
- _binding = FragmentMapsBinding.inflate(inflater, container, false)
- val root: View = binding.root
- binding.checkBoxZoomControls.setOnCheckedChangeListener { compoundButton, b ->
- }
- return root
- }
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- super.onViewCreated(view, savedInstanceState)
- val mapFragment = childFragmentManager.findFragmentById(R.id.map) as SupportMapFragment?
- mapFragment?.getMapAsync(callback)
- }
- }
- // MapsFragment XML, lisätään RadioGroup + Radiobuttoneita
- <?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=".MapsFragment">
- <fragment
- android:id="@+id/map"
- android:name="com.google.android.gms.maps.SupportMapFragment"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- tools:layout="@layout/fragment_home" />
- <CheckBox
- android:id="@+id/checkBox_zoom_controls"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_margin="10dp"
- android:text="Zoom ON/OFF"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toTopOf="parent" />
- <RadioGroup
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_margin="10dp"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintTop_toTopOf="parent">
- <RadioButton
- android:id="@+id/radioButton_normal_map"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:checked="true"
- android:text="Normal" />
- <RadioButton
- android:id="@+id/radioButton_hybrid_map"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="Hybrid" />
- </RadioGroup>
- </androidx.constraintlayout.widget.ConstraintLayout>
- // lisätään myös RadioButtonit koodiin, MapsFragment.kt
- override fun onCreateView(
- inflater: LayoutInflater,
- container: ViewGroup?,
- savedInstanceState: Bundle?
- ): View? {
- _binding = FragmentMapsBinding.inflate(inflater, container, false)
- val root: View = binding.root
- // kun checkboxia klikataan -> zoom-kontrollit päälle tai pois
- binding.checkBoxZoomControls.setOnCheckedChangeListener { compoundButton, b ->
- gMap.uiSettings.isZoomControlsEnabled = b
- }
- // radio button -> muutetaan kartan tyyppi VAIN SILLOIN, jos
- // radio button on valittu (oletuksena setOnChecked käynnistyy molemmissa
- // tapauksissa, eli on tai off, mikä tuo bugeja tähän tilanteeseen)
- binding.radioButtonNormalMap.setOnCheckedChangeListener { compoundButton, b ->
- if(compoundButton.isChecked) {
- gMap.mapType = GoogleMap.MAP_TYPE_NORMAL
- }
- }
- // ... ja sama hybrid-kartalle
- binding.radioButtonHybridMap.setOnCheckedChangeListener { compoundButton, b ->
- if(compoundButton.isChecked) {
- gMap.mapType = GoogleMap.MAP_TYPE_HYBRID
- }
- }
- return root
- }
- // Lisätään MapsFragmentiin ONMarkerClick -tuki:
- class MapsFragment : Fragment(), GoogleMap.OnMarkerClickListener {
- // lisätään vaadittava funktio MapsFragmentin pohjalle:
- // jos mitä tahansa markeria klikataan, ajetaan tämä funktio
- override fun onMarkerClick(p0: Marker): Boolean {
- Log.d("ADVTECH", "MARKKERI!")
- // onMarkerClick vaatii lopussa että palautetaan boolean
- return false
- }
- // lisää myös tämä OnMapReadyCallbackiin, esim. gMap = googleMap -kohdan jälkeen:
- // käytetään MapsFragmentissa olevaa onMarkerClick-funktiota
- // käytetään MapsFragmentissa olevaa onMarkerClick-funktiota
- // jos markeria klikataan
- googleMap.setOnMarkerClickListener(this)
- // Markereihin voi lisätä myös dataa tageilla:
- private val callback = OnMapReadyCallback { googleMap ->
- // laitetaan googleMap-olio talteen luokan tasolle (gMap)
- gMap = googleMap
- // käytetään MapsFragmentissa olevaa onMarkerClick-funktiota
- // jos markeria klikataan
- googleMap.setOnMarkerClickListener(this)
- // asetetaan markerit muuttujiin, jotta saamme
- // asettaa niihin omaa dataa mukaan tagin avulla
- // tässä tapauksessa kaupungin nimi
- val sydney = LatLng(-34.0, 151.0)
- var marker1 : Marker? = googleMap.addMarker(MarkerOptions().position(sydney).title("Marker in Sydney"))
- marker1?.tag = "Sydney"
- val rovaniemi = LatLng(66.50352001528042, 25.727189822733095)
- var marker2 : Marker? = googleMap.addMarker(MarkerOptions().position(rovaniemi).title("Rovaniemi!"))
- marker2?.tag = "Rovaniemi"
- // newLatLngZoomin avulla voidaan siirtää kameraa ja myös zoomata
- googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(rovaniemi, 15f))
- }
- // markerin datat voidaan ottaa onMarkerClickissä vastaan näin:
- // jos mitä tahansa markeria klikataan, ajetaan tämä funktio
- override fun onMarkerClick(p0: Marker): Boolean {
- Log.d("ADVTECH", "MARKKERI!")
- // lokitetaan/tulostetaan markeriin liitetyt koordinaatit sekä
- // tagi, jossa pitäisi olla kaupungin nimi
- Log.d("ADVTECH", p0.position.latitude.toString())
- Log.d("ADVTECH", p0.position.longitude.toString())
- Log.d("ADVTECH", p0.tag.toString())
- // onMarkerClick vaatii lopussa että palautetaan boolean
- return false
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement