Lab Detail


Sno Back Back Subject subject date title note
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: