I am getting this error:
FATAL EXCEPTION: main
Process: com.example.app, PID: 2902
java.lang.IllegalStateException: Could not find method showSublayersDialog(View) in a parent or ancestor Context for android:onClick attribute defined on view class androidx.appcompat.widget.AppCompatImageButton with id 'ellipsisButton'
I've added an ellipsis button to the front of my app to control sub layer visibility and to change map style. Everything worked great until I tried implementing the map style buttons. Any help would be appreciated.
Here is my MainActivity
package com.example.app
import android.os.Bundle
import android.view.LayoutInflater
import android.widget.CheckBox
import android.widget.ImageView
import android.widget.LinearLayout
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import com.arcgismaps.ApiKey
import com.arcgismaps.ArcGISEnvironment
import com.arcgismaps.mapping.ArcGISMap
import com.arcgismaps.mapping.BasemapStyle
import com.arcgismaps.mapping.Viewpoint
import com.arcgismaps.mapping.ViewpointType
import com.arcgismaps.mapping.layers.ArcGISMapImageLayer
import com.arcgismaps.mapping.view.MapView
import com.example.app.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
private val activityMainBinding: ActivityMainBinding by lazy {
DataBindingUtil.setContentView(this, R.layout.activity_main)
}
private val mapView: MapView by lazy {
activityMainBinding.mapView
}
private lateinit var arcgisImageryIcon: ImageView
private lateinit var osmStreetsIcon: ImageView
private lateinit var map: ArcGISMap
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding: ActivityMainBinding =
DataBindingUtil.setContentView(this, R.layout.activity_main)
val versionTextView = binding.versionTextView
val versionName = packageManager.getPackageInfo(packageName, 0).versionName
val versionText = resources.getString(R.string.version_text) + versionName
versionTextView.text = versionText
lifecycle.addObserver(mapView)
setApiKey()
setupMap()
}
private fun setupMap() {
val map = ArcGISMap(BasemapStyle.ArcGISImagery)
mapView.map = map
val mapServiceUrl =
"https://...../MapServer"
val mapImageLayer = ArcGISMapImageLayer(mapServiceUrl)
map.operationalLayers.add(mapImageLayer)
val viewpoint = Viewpoint(xx.xxx, -xxx.xxx, 420000.0)
mapView.setViewpoint(viewpoint)
}
private fun setApiKey() {
ArcGISEnvironment.apiKey =
ApiKey.create("xxx")
}
fun showSublayersDialog() {
val dialogView = LayoutInflater.from(this).inflate(R.layout.sublayers_dialog, null)
val builder = AlertDialog.Builder(this)
.setTitle("Sublayers")
.setView(dialogView)
.setPositiveButton("Close") { dialog, _ -> dialog.dismiss() }
val dialog = builder.create()
dialog.show()
val sublayersContainer: LinearLayout =
dialogView.findViewById(R.id.checkBoxGroup)
val mapImageLayer =
mapView.map?.operationalLayers?.get(0) as ArcGISMapImageLayer
if (mapImageLayer.mapImageSublayers.isNotEmpty()) {
for (sublayer in mapImageLayer.mapImageSublayers) {
val checkBox = CheckBox(this)
checkBox.text = sublayer.name
checkBox.isChecked = sublayer.isVisible
checkBox.setOnCheckedChangeListener { _, isChecked ->
sublayer.isVisible = isChecked
}
sublayersContainer.addView(checkBox)
}
arcgisImageryIcon.setOnClickListener {
val savedViewpoint =
mapView.getCurrentViewpoint(viewpointType = ViewpointType.CenterAndScale)
?.toJson()
map = ArcGISMap(BasemapStyle.ArcGISImagery)
mapView.map = map
if (savedViewpoint != null) {
val newViewpoint = Viewpoint.fromJsonOrNull(savedViewpoint)
if (newViewpoint != null) {
mapView.setViewpoint(newViewpoint)
}
}
arcgisImageryIcon.setBackgroundResource(R.drawable.selected_style_border)
osmStreetsIcon.setBackgroundResource(0)
}
osmStreetsIcon.setOnClickListener {
val savedViewpoint =
mapView.getCurrentViewpoint(viewpointType = ViewpointType.CenterAndScale)
?.toJson()
map = ArcGISMap(BasemapStyle.OsmStreets)
mapView.map = map
if (savedViewpoint != null) {
val newViewpoint = Viewpoint.fromJsonOrNull(savedViewpoint)
if (newViewpoint != null) {
mapView.setViewpoint(newViewpoint)
}
}
osmStreetsIcon.setBackgroundResource(R.drawable.selected_style_border)
arcgisImageryIcon.setBackgroundResource(0)
}
}
}
}
activities_main.xml
<layout xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.arcgismaps.mapping.view.MapView
android:id="@+id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:layout_editor_absoluteX="-37dp"
tools:layout_editor_absoluteY="173dp" />
<ImageButton
android:id="@+id/ellipsisButton"
android:layout_width="64dp"
android:layout_height="58dp"
android:layout_margin="16dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/layer_one"
android:onClick="showSublayersDialog"
android:src="@drawable/ic_ellipsis"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/versionTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/version_text"
android:layout_margin="16dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
sublayers_dialog.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:contentDescription="@string/sublayers_scrollview_description">
<LinearLayout
android:id="@+id/checkBoxGroup"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
</LinearLayout>
</ScrollView>
<TextView
android:id="@+id/styleTitleTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/map_style"
android:layout_marginTop="16dp" />
<!-- ArcGIS Imagery Icon -->
<ImageView
android:id="@+id/arcgisImageryIcon"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginTop="8dp"
android:src="@drawable/ic_satellite"
android:contentDescription="@string/arcgis_imagery"
android:background="?attr/selectableItemBackgroundBorderless" />
<!-- OSM Streets Icon -->
<ImageView
android:id="@+id/osmStreetsIcon"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginTop="8dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/osm_streets"
android:src="@drawable/ic_streets" />
</LinearLayout>
Solved! Go to Solution.
Current error is
FATAL EXCEPTION: main
Process: com.example.app, PID: 13858
java.lang.IllegalStateException: Could not execute method for android:onClick
I'm not an Android/Kotlin developer, but it looks like your signature for showSublayersDialog() is wrong. It looks like you need it to accept a View parameter (e.g. showSublayersDialog(View v)). See this documentation on the android:onClick attribute.
The doc indicates that method should be public, but it looks like that's the default visibility for Kotlin, so you could be OK there.
I previously had fun showSublayersDialog as
fun showSublayersDialog(view: View) {
val dialogView = LayoutInflater.from(this).inflate(R.layout.sublayers_dialog, null)
but Android Studio threw a warning that the parameter "view" wasn't being used. So I removed it. Adding it back in still causes a crash.
What's the crash once you have the correct signature for showSublayersDialog()? It should be different to the one in your original posting.
Current error is
FATAL EXCEPTION: main
Process: com.example.app, PID: 13858
java.lang.IllegalStateException: Could not execute method for android:onClick