| 1 |
1 |
Back to subject |
Mobile Application Development Lab - 20A05706 (Lab) |
Sept. 16, 2025 |
RECYCLERVIEW dynamic Maps |
RECYCLERVIEW dynamic Maps
E:\android\MyApplication\app\build.gradle.kts
android {
dataBinding{
enable=true
//enabled=true old version of android sdk Do it
}
}
dependencies {
implementation("org.osmdroid:osmdroid-android:6.1.14")
implementation("androidx.preference:preference-ktx:1.2.1")
}
E:\android\MyApplication\app\src\main\AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.MyApplication">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
E:\android\MyApplication\app\src\main\res\values\strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">List</string>
<string-array name="xyz">
<item>ATK</item>
<item>NLR</item>
<item>KDP</item>
<item>ANTHASAGARAM</item>
<item>Chilakalamarri</item>
<item>Mangupalli</item>
<item>Gudugunta</item>
<item>Yeguvapalli</item>
<item>HYD</item>
<item>CHE</item>
<item>KOL</item>
<item>ATK</item>
<item>NLR</item>
<item>KDP</item>
<item>ANTHASAGARAM</item>
<item>Chilakalamarri</item>
<item>Mangupalli</item>
<item>Gudugunta</item>
<item>Yeguvapalli</item>
<item>HYD</item>
<item>CHE</item>
<item>KOL</item>
<item>ATK</item>
<item>NLR</item>
<item>KDP</item>
<item>ANTHASAGARAM</item>
<item>Chilakalamarri</item>
<item>Mangupalli</item>
<item>Gudugunta</item>
<item>Yeguvapalli</item>
<item>HYD</item>
<item>CHE</item>
<item>KOL</item>
<item>ATK</item>
<item>NLR</item>
<item>KDP</item>
<item>ANTHASAGARAM</item>
<item>Chilakalamarri</item>
<item>Mangupalli</item>
<item>Gudugunta</item>
<item>Yeguvapalli</item>
<item>HYD</item>
<item>CHE</item>
<item>KOL</item>
<item>ATK</item>
<item>NLR</item>
<item>KDP</item>
<item>ANTHASAGARAM</item>
<item>Chilakalamarri</item>
<item>Mangupalli</item>
<item>Gudugunta</item>
<item>Yeguvapalli</item>
<item>HYD</item>
<item>CHE</item>
<item>KOL</item>
</string-array>
<string-array name="tile_sources">
<item>OSM Standard</item>
<item>USGS Topo</item>
<item>Watercolor</item>
</string-array>
</resources>
E:\android\MyApplication\app\src\main\res\layout\activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<layout>
<RelativeLayout
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:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Recycler view example"
android:id="@+id/tv1"
/>
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/rec"
android:layout_below="@id/tv1"
android:layout_margin="10dp"/>
</RelativeLayout>
</layout>
E:\android\MyApplication\app\src\main\res\layout\custom.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="horizontal">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/iv"
android:layout_margin="5dp"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/linear"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/name"
android:layout_margin="5dp"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/mobile"
android:layout_margin="5dp"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/email"
android:layout_margin="5dp"/>
<!-- Spinner to switch tile sources -->
<Spinner
android:id="@+id/spinnerTile"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:entries="@array/tile_sources"
android:layout_margin="5dp"/>
<org.osmdroid.views.MapView
android:id="@+id/map"
android:layout_width="match_parent"
android:layout_height="200dp"/>
</LinearLayout>
</LinearLayout>
E:\android\MyApplication\app\src\main\java\com\example\myapplication\MainActivity.kt
package com.example.myapplication
import android.annotation.SuppressLint
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.provider.MediaStore
import android.widget.ArrayAdapter
import android.widget.Toast
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.myapplication.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
var binding: ActivityMainBinding? = null
// var Names=arrayOf("AAA","BBB","CCC")
// var Mobile=arrayOf("5253","87567","7565")
// var Emails=arrayOf("aaa@gmail.com","bbb@yamil.com","ccc@hotmail.com")
// var Profile=arrayOf(R.mipmap.ic_launcher,R.mipmap.ic_launcher_round,R.mipmap.ic_launcher)
var Names = arrayOf(
"AAA","BBB","CCC","DDD","EEE","FFF","GGG","HHH","III","JJJ",
"KKK","LLL","MMM","NNN","OOO","PPP","QQQ","RRR","SSS","TTT"
)
var Mobile = arrayOf(
"5253","87567","7565","1234","9876","5432","6789","3456","7890","2345",
"4567","6781","2346","9872","5643","6784","3457","9873","4568","7891"
)
var Emails = arrayOf(
"aaa@gmail.com","bbb@yamil.com","ccc@hotmail.com","ddd@gmail.com","eee@yahoo.com",
"fff@hotmail.com","ggg@gmail.com","hhh@yahoo.com","iii@hotmail.com","jjj@gmail.com",
"kkk@yahoo.com","lll@hotmail.com","mmm@gmail.com","nnn@yahoo.com","ooo@hotmail.com",
"ppp@gmail.com","qqq@yahoo.com","rrr@hotmail.com","sss@gmail.com","ttt@yahoo.com"
)
var Profile = arrayOf(
R.mipmap.ic_launcher, R.mipmap.ic_launcher_round, R.mipmap.ic_launcher,
R.mipmap.ic_launcher_round, R.mipmap.ic_launcher, R.mipmap.ic_launcher_round,
R.mipmap.ic_launcher, R.mipmap.ic_launcher_round, R.mipmap.ic_launcher, R.mipmap.ic_launcher_round,
R.mipmap.ic_launcher, R.mipmap.ic_launcher_round, R.mipmap.ic_launcher, R.mipmap.ic_launcher_round,
R.mipmap.ic_launcher, R.mipmap.ic_launcher_round, R.mipmap.ic_launcher, R.mipmap.ic_launcher_round,
R.mipmap.ic_launcher, R.mipmap.ic_launcher_round
)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Enable edge-to-edge content
enableEdgeToEdge()
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
var linearlayoutmanager= LinearLayoutManager(this@MainActivity,LinearLayoutManager.VERTICAL, false)
binding?.rec?.layoutManager=linearlayoutmanager
var customAdapter=CustomAdapter(this@MainActivity, Names,Mobile, Emails, Profile)
binding?.rec?.adapter=customAdapter
}
}
E:\android\MyApplication\app\src\main\java\com\example\myapplication\CustomAdapter.kt
package com.example.myapplication
import android.content.Context
import android.graphics.Color
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.*
import androidx.recyclerview.widget.RecyclerView
import org.osmdroid.config.Configuration
import org.osmdroid.tileprovider.tilesource.TileSourceFactory
import org.osmdroid.tileprovider.tilesource.XYTileSource
import org.osmdroid.util.GeoPoint
import org.osmdroid.views.MapView
import org.osmdroid.views.overlay.Marker
import org.osmdroid.views.overlay.Polygon
import org.osmdroid.views.overlay.Polyline
import org.osmdroid.views.overlay.ScaleBarOverlay
import org.osmdroid.views.overlay.compass.CompassOverlay
import org.osmdroid.views.overlay.compass.InternalCompassOrientationProvider
class CustomAdapter(
mainActivity: Context,
private val names: Array<String>,
private val mobile: Array<String>,
private val emails: Array<String>,
private val profile: Array<Int>
) : RecyclerView.Adapter<CustomAdapter.MyViewHolder>() {
private val context = mainActivity
init {
Configuration.getInstance().load(
context,
android.preference.PreferenceManager.getDefaultSharedPreferences(context)
)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.custom, parent, false)
return MyViewHolder(view)
}
override fun getItemCount(): Int = names.size
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
// Set user info
holder.name.text = names[position]
holder.email.text = emails[position]
holder.mobile.text = mobile[position]
holder.profile.setImageResource(profile[position])
holder.profile.setOnClickListener {
Toast.makeText(
context,
"Name: ${names[position]}\nEmail: ${emails[position]}\nMobile: ${mobile[position]}",
Toast.LENGTH_LONG
).show()
}
holder.linearLayout.setOnClickListener {
Toast.makeText(
context,
"Name: ${names[position]}\nEmail: ${emails[position]}\nMobile: ${mobile[position]}",
Toast.LENGTH_LONG
).show()
}
// MapView setup
holder.mapView.setMultiTouchControls(true)
holder.mapView.controller.setZoom(10.0)
// Compass overlay
val compassOverlay = CompassOverlay(context, InternalCompassOrientationProvider(context), holder.mapView)
compassOverlay.enableCompass()
holder.mapView.overlays.add(compassOverlay)
// Scale bar overlay
val scaleBarOverlay = ScaleBarOverlay(holder.mapView)
scaleBarOverlay.setCentred(true)
holder.mapView.overlays.add(scaleBarOverlay)
// Default tile source
holder.mapView.setTileSource(TileSourceFactory.MAPNIK)
// Dummy location for each item
val latitude = 12.9716 + (position * 0.01)
val longitude = 77.5946 + (position * 0.01)
val geoPoint = GeoPoint(latitude, longitude)
holder.mapView.controller.setCenter(geoPoint)
// Marker overlay
val marker = Marker(holder.mapView)
marker.position = geoPoint
marker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM)
marker.title = names[position]
// Polyline overlay
val polyline = Polyline()
polyline.addPoint(GeoPoint(latitude, longitude))
polyline.addPoint(GeoPoint(latitude + 0.01, longitude + 0.01))
polyline.addPoint(GeoPoint(latitude + 0.02, longitude))
polyline.width = 5f
polyline.color = Color.BLUE
// Polygon overlay
val polygon = Polygon()
val polygonPoints = listOf(
GeoPoint(latitude + 0.01, longitude - 0.01),
GeoPoint(latitude + 0.01, longitude + 0.01),
GeoPoint(latitude - 0.01, longitude + 0.01),
GeoPoint(latitude - 0.01, longitude - 0.01)
)
polygon.points = polygonPoints
polygon.fillColor = Color.parseColor("#3300FF00") // semi-transparent green
polygon.strokeColor = Color.GREEN
polygon.strokeWidth = 3f
// Clear previous overlays and add new ones
holder.mapView.overlays.clear()
holder.mapView.overlays.add(marker)
holder.mapView.overlays.add(polyline)
holder.mapView.overlays.add(polygon)
holder.mapView.overlays.add(compassOverlay)
holder.mapView.overlays.add(scaleBarOverlay)
holder.mapView.invalidate()
// Spinner for tile sources
val tileNames = context.resources.getStringArray(R.array.tile_sources)
val adapter = ArrayAdapter(context, android.R.layout.simple_spinner_item, tileNames)
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
holder.spinnerTile.adapter = adapter
holder.spinnerTile.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>, view: View?, pos: Int, id: Long) {
when (pos) {
0 -> holder.mapView.setTileSource(TileSourceFactory.MAPNIK)
1 -> holder.mapView.setTileSource(TileSourceFactory.USGS_TOPO)
2 -> holder.mapView.setTileSource(
XYTileSource(
"Watercolor",
0, 20, 256, ".png",
arrayOf("http://tile.stamen.com/watercolor/"),
"© Stamen Design"
)
)
3 -> holder.mapView.setTileSource(
XYTileSource(
"OpenTopoMap",
0, 17, 256, ".png",
arrayOf("https://tile.opentopomap.org/{z}/{x}/{y}.png"),
"© OpenTopoMap"
)
)
}
holder.mapView.invalidate()
}
override fun onNothingSelected(parent: AdapterView<*>) {}
}
}
inner class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val name: TextView = itemView.findViewById(R.id.name)
val mobile: TextView = itemView.findViewById(R.id.mobile)
val email: TextView = itemView.findViewById(R.id.email)
val profile: ImageView = itemView.findViewById(R.id.iv)
val linearLayout: LinearLayout = itemView.findViewById(R.id.linear)
val mapView: MapView = itemView.findViewById(R.id.map)
val spinnerTile: Spinner = itemView.findViewById(R.id.spinnerTile)
}
}
Output:

|