AndroidのViewPager内でMapを利用する方法

ViewPagerの中にMapを配置するには、ViewPagerのAdapterとしてFragmentStatePagerAdapterを使用し、下記のような方法でFragmentを返します。

- [MapFragmentを返す](#mapfragmentを返す)
- [ListViewを入れたFragmentを返し、ListViewで自製セルを返す](#listviewを入れたfragmentを返しlistviewで自製セルを返す)
- [FrameLayoutを入れたFragmentを返す](#framelayoutを入れたfragmentを返す)

[GitHub](https://github.com/hitting1024/MapInPagerViewSample)で、それぞれのサンプルコードを公開しています。下記にその概要を示します。

# MapFragmentを返す

ViewPagerの中にMapのみを表示する場合はこの方法が一番簡単です。

サンプルコードでは、[SupportMapFragment](https://developers.google.com/android/reference/com/google/android/gms/maps/SupportMapFragment)を返しています。

[MapFragmentPagerAdapter](https://github.com/hitting1024/MapInPagerViewSample/blob/master/app/src/main/java/jp/hitting/mapinviewpagersample/FragmentPagerActivity.kt#L21)

```kotlin
class MapFragmentPagerAdapter(fragmentManager: FragmentManager) : FragmentStatePagerAdapter(fragmentManager) {

    override fun getItem(position: Int): Fragment {
        return SupportMapFragment.newInstance()
    }

    // omitted

}
```

# ListViewを入れたFragmentを返し、ListViewで自製セルを返す

ViewPagerの各ページではListViewを表示し、ListViewの中の自製セルでMapを表示する方法です。
自製セルは、ViewをFrameLayoutで定義し、そこにコンストラクタでSupportMapFragmentを追加しています。

[MapListViewAdapter](https://github.com/hitting1024/MapInPagerViewSample/blob/master/app/src/main/java/jp/hitting/mapinviewpagersample/MapListViewFragment.kt#L34)

```kotlin
class MapListViewAdapter(private val context: Context, private val fragmentManager: FragmentManager) : BaseAdapter() {

    private val inflater = LayoutInflater.from(context)

    override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
        
        // omitted

        val mapView = MyMapView(this.context, this.fragmentManager)
        val layoutParams = FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, 500)
        mapView.layoutParams = layoutParams
        return mapView
    }

    // omitted

}
```

[MyMapView](https://github.com/hitting1024/MapInPagerViewSample/blob/master/app/src/main/java/jp/hitting/mapinviewpagersample/MyMapView.kt#L10)

```kotlin
class MyMapView(context: Context, fragmentManager: FragmentManager) : FrameLayout(context) {

    init {
        val inflater = LayoutInflater.from(context)
        val layoutView = inflater.inflate(R.layout.view_map, null)
        val view = layoutView.mapFrameLayout

        val mapFragment = SupportMapFragment.newInstance()
        fragmentManager.beginTransaction().add(view.id, mapFragment).commit()
        mapFragment.getMapAsync {
            // nothing
        }

        this.addView(layoutView)
    }

}
```

# FrameLayoutを入れたFragmentを返す

ViewPagerの各ページのレイアウトにFrameLayoutを定義し、そこにSupportMapFragmentを追加する方法です。
このときfragmentManagerではなく、**childFragmentManager**を使います。

[MapPagerFragment](https://github.com/hitting1024/MapInPagerViewSample/blob/master/app/src/main/java/jp/hitting/mapinviewpagersample/MapPagerFragment.kt#L11)

```kotlin
class MapPagerFragment : Fragment() {

    override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        val view = inflater!!.inflate(R.layout.fragment_map_pager, container, false)
        val mapView = view.mapView
        val mapFragment = SupportMapFragment.newInstance()
        this.childFragmentManager.beginTransaction().add(mapView.id, mapFragment).commit()
        mapFragment.getMapAsync {
            // nothing
        }
        return view
    }

    // omitted

}
```


# 参考

- [How to add map fragment programmatically](https://stackoverflow.com/questions/29697884/how-to-add-map-fragment-programmatically)