終於到了重頭戲,來替我們的專案建立 Google 地圖 !
今天實作的官方文件 :
新增地圖有以下幾個基本步驟 :
FragmentContainer
SupportMapFragment
物件新增至處理地圖的 Activity。OnMapReadyCallback
介面,並取得 GoogleMap
的實例。在開始之前,先來調整目前的畫面
main_activity.xml
:
先將 RecyclerView 的程式碼註解,並加入 FragmentContainer
:
<!-- <androidx.recyclerview.widget.RecyclerView-->
<!-- android:id="@+id/recycler_view"-->
<!-- android:layout_width="0dp"-->
<!-- android:layout_height="wrap_content"-->
<!-- app:layout_constraintBottom_toBottomOf="parent"-->
<!-- app:layout_constraintEnd_toEndOf="parent"-->
<!-- app:layout_constraintStart_toStartOf="parent"-->
<!-- app:layout_constraintTop_toTopOf="parent"-->
<!-- tools:listitem="@layout/item_cafe" />-->
<androidx.fragment.app.FragmentContainerView
android:id="@+id/fragment_container"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
目前的 main_activity.xml
:
<?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"
android:padding="5dp"
tools:context=".MainActivity">
<TextView
android:id="@+id/tv_err"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:textSize="16sp"
app:layout_constraintBottom_toTopOf="@+id/button"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="GET"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<ProgressBar
android:id="@+id/progressbar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="50dp"
android:minHeight="50dp"
android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<!-- <androidx.recyclerview.widget.RecyclerView-->
<!-- android:id="@+id/recycler_view"-->
<!-- android:layout_width="0dp"-->
<!-- android:layout_height="wrap_content"-->
<!-- app:layout_constraintBottom_toBottomOf="parent"-->
<!-- app:layout_constraintEnd_toEndOf="parent"-->
<!-- app:layout_constraintStart_toStartOf="parent"-->
<!-- app:layout_constraintTop_toTopOf="parent"-->
<!-- tools:listitem="@layout/item_cafe" />-->
<androidx.fragment.app.FragmentContainerView
android:id="@+id/fragment_container"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
MainActivity 修改 initView()
程式碼,把 RecyclerView 的初始化也註解 :
private fun initView() {
adapter = MainAdapter(mutableListOf())
// binding.recyclerView.apply {
//
// layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
// adapter = this@MainActivity.adapter
// }
}
建立 Fragment
可以分為靜態和動態,這邊直接使用動態新增 :
在 MainActivity 內的 init() 內建立 SupportMapFragment
:
private fun initView() {
adapter = MainAdapter(mutableListOf())
// TODO: MapFragment
val mapFragment = SupportMapFragment.newInstance()
supportFragmentManager
.beginTransaction()
.add(R.id.fragment_container, mapFragment)
.commit()
}
這邊的 fragment_container
是剛剛在 main_activity.xml 加入的 fragment 容器 FragmentContainerView
class MainActivity : AppCompatActivity(), OnMapReadyCallback {
// ...
}
覆寫 callback
的方法,以取得 GoogleMap
實例 :
override fun onMapReady(googleMap: GoogleMap) {
googleMap.addMarker(
MarkerOptions()
.position(LatLng(0.0, 0.0))
.title("Marker")
)
}
輸入上面的經緯度會出現「空虛島」,超酷的 !
最後就是最重要的事情,我們需要和使用者取得權限,這邊新增 requestPermissions()
:
private fun requestPermissions() {
val REQUEST_EXTERNAL = 1;
val PERMISSIONS_LIST = arrayOf(
Manifest.permission.INTERNET,
Manifest.permission.ACCESS_NETWORK_STATE,
Manifest.permission.READ_PHONE_STATE,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION
)
var permission =
ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
permission += ActivityCompat.checkSelfPermission(
this,
Manifest.permission.ACCESS_COARSE_LOCATION
)
if (permission != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, PERMISSIONS_LIST, REQUEST_EXTERNAL)
}
}
在 onCreate()
初始化的時候,動態的和使用者取得專案需要的權限。
現在準備得差不多,來運行一下 !