I am VERY new to android programming and even newer to kotlin, but I am trying to implement a simple activity as a proof of concept where a map fragment is part of a scrollable list that will later be used to capture user information (and a marker location on the map).
I used a google developer tutorial to get my map fragment to display the map, and I've now embedded that map fragment inside a scroll view. Everything works except for the fact that when I try to pan my map vertically (north/south), my scroll view starts to scroll.
How do I prevent the scrollview from moving if I touch on the map fragment area? Thanks in advance for the help!
Here is the XML code of the activity:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
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"
android:orientation="vertical">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorAccent">
<TextView
android:id="@ id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="TextView1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@ id/editTextTextPersonName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="60dp"
android:ems="10"
android:inputType="textPersonName"
android:text="Name"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.497"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@ id/textView2" />
<TextView
android:id="@ id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="172dp"
android:text="TextView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@ id/editTextTextPersonName" />
<fragment
android:id="@ id/map_fragment"
android:layout_width="match_parent"
android:layout_height="300dp"
android:layout_marginTop="28dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@ id/textView3" />
<TextView
android:id="@ id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="200dp"
android:layout_marginBottom="16dp"
android:text="HELLO WORLD DOWN HERE"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.497"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@ id/map_fragment" />
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
</LinearLayout>
and here is the koitlin activity MainActivity.kt:
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.codelabs.buildyourfirstmap
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.google.android.gms.maps.CameraUpdateFactory
import com.google.android.gms.maps.GoogleMap
import com.google.android.gms.maps.SupportMapFragment
import com.google.android.gms.maps.UiSettings
import com.google.android.gms.maps.model.LatLngBounds
import com.google.android.gms.maps.model.MarkerOptions
import com.google.codelabs.buildyourfirstmap.place.Place
import com.google.codelabs.buildyourfirstmap.place.PlacesReader
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val mapFragment = supportFragmentManager.findFragmentById(R.id.map_fragment) as? SupportMapFragment
mapFragment?.getMapAsync {
googleMap->addMarkers(googleMap)
}
mapFragment?.getMapAsync { googleMap ->
// Ensure all places are visible in the map.
googleMap.setOnMapLoadedCallback {
val bounds = LatLngBounds.builder()
places.forEach { bounds.include(it.latLng) }
googleMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds.build(), 20))
val uisettings = googleMap.uiSettings
googleMap.uiSettings.isZoomControlsEnabled = true
}
}
}
private val places: List<Place> by lazy {
PlacesReader(this).read()
}
/**
* Adds marker representations of the places list on the provided GoogleMap object
*/
private fun addMarkers(googleMap: GoogleMap) {
places.forEach { place ->
val marker = googleMap.addMarker(
MarkerOptions()
.title(place.name)
.position(place.latLng)
)
}
}
}
CodePudding user response:
You should add these lines as soon as map is ready:
googleMap.setOnCameraMoveStartedListener(OnCameraMoveStartedListener { i ->
if (i == OnCameraMoveStartedListener.REASON_GESTURE) {
blockScrollView()
}
})
googleMap.setOnCameraMoveCanceledListener(OnCameraMoveCanceledListener { enableScrollView() })
Declare your scrollview and disable, enable it inside blockScrollView()
, enableScrollView()
methods.
Optional step: Declare GoogleMap map;
at class level and initialize googleMap
in getMapAsync method to it. And use map instead of calling getMapAsync every time you use map. Calling getMapAsync multiple times is wrong.