高德地图 Android 模仿微信选择地址

先上图:


Screenshot_20180709-164828.jpg
Screenshot_20180709-164840.jpg

移动地图的视角下面的列表的数据可以自动改变,在顶部进行搜索会出现第二张图的列表。

代码是 Kotlin 写的,如果没学过的话读起来可能会有点麻烦……

第一个 Activity 的代码

class ShareLocationActivity : BaseActivity() {
    override fun getLayoutRes(): Int = R.layout.activity_share_location

    override fun initClick() {
        restoreLocationButton.onClick {
            restoreLocation()
        }
        shareLocationSearchButton.onClick {
            searchPoi()
        }
    }

    private fun searchPoi() {
        var input = shareLocationEdit.text.toString()
        if (input.isEmpty()) {
            toast("请输入要搜索的内容")
            return
        }
        launchActivity<PoiSearchResultListActivity> {
            putExtra("keyword", input)
        }
    }

    private var amapLocalUtils: AMapLocationUtils? = null
    private fun restoreLocation() {
        amapLocalUtils?.getLonLat(applicationContext) {
            setCameraToCurrent(it.latitude, it.longitude)
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        initHead()
        initMap(savedInstanceState)
        // 定位
        initPOI()
        initMapCameraChangeListen()
        initEvent()
        initSearch()
        initStateLayout()
    }

    private fun initStateLayout() {
        shareLocationStateLayout.setErrorAndEmptyAction {
            initPOI()
        }
    }

    private fun initSearch() {
        shareLocationEdit.setOnEditorActionListener { _, actionId, event ->
            if (actionId == EditorInfo.IME_ACTION_SEND
                    || actionId == EditorInfo.IME_ACTION_DONE
                    || (event != null && KeyEvent.KEYCODE_ENTER == event.keyCode &&
                            KeyEvent.ACTION_DOWN == event.action)) {
                searchPoi()
                true
            }
            false
        }
    }

    private fun initEvent() {
        Bus.observe<FinishShareLocationEvent>()
                .subscribe {
                    if (!isFinishing) {
                        finish()
                        Logcat.d("finish", "")
                    }
                }
                .registerInBus(this)
    }


    private fun initMapCameraChangeListen() {
        getMap().setOnCameraChangeListener(object : AMap.OnCameraChangeListener {
            override fun onCameraChangeFinish(position: CameraPosition) {
                var target = position.target
                decodePosition(target.latitude, target.longitude)
                doPoiSearch(target.latitude, target.longitude)
            }

            override fun onCameraChange(position: CameraPosition?) {
            }

        })
    }

    private fun decodePosition(latitude: Double, longitude: Double) {
        var search = GeocodeSearch(this)
        search.setOnGeocodeSearchListener(object : GeocodeSearch.OnGeocodeSearchListener {
            override fun onRegeocodeSearched(result: RegeocodeResult, code: Int) {
                if (code != 200) {
                    shareLocationCityNameText.text = result.regeocodeAddress.city
                    cityCode = result.regeocodeAddress.cityCode
                }
            }

            override fun onGeocodeSearched(result: GeocodeResult, code: Int) {

            }

        })
        var query = RegeocodeQuery(LatLonPoint(latitude, longitude), 200f, GeocodeSearch.AMAP)
        search.getFromLocationAsyn(query)
    }

    private var cityCode: String = ""
    private fun initPOI() {
        shareLocationStateLayout.showProgressView()
        amapLocalUtils = AMapLocationUtils().get()
        amapLocalUtils?.getLonLat(this) { location ->
            cityCode = location.cityCode
            doPoiSearch(location.latitude, location.longitude)
            shareLocationCityNameText.text = location.city
        }
    }

    private fun doPoiSearch(latitude: Double, longitude: Double) {
        var query = PoiSearch.Query("", "地名地址信息", cityCode)
        query.pageSize = 20
        var poiSearch = PoiSearch(this, query)
        poiSearch.bound = PoiSearch.SearchBound(LatLonPoint(latitude, longitude), 500000000)
        poiSearch.setOnPoiSearchListener(object : PoiSearch.OnPoiSearchListener {
            override fun onPoiItemSearched(item: PoiItem, code: Int) {

            }

            override fun onPoiSearched(result: PoiResult, code: Int) {
                if (result.pois.isEmpty()) {
                    toast("附近没有标志性建筑")
                }
                Logcat.d(result.toString())
                initListView(result.pois)
                shareLocationStateLayout.showContentView()
            }

        })
        poiSearch.searchPOIAsyn()
    }

    private fun initListView(pois: ArrayList<PoiItem>) {
        var adapter = ShareLocationAdapter(this, pois)
        shareLocationListView.adapter = adapter
        shareLocationListView.onItemClick { _, _, i, _ ->
            var poi = pois[i]
            Bus.send(ShareLocationEvent(poi.title, poi.latLonPoint.latitude, poi.latLonPoint.longitude))
            finish()
            Logcat.d("finish", "")
        }
    }


    private fun setCameraToCurrent(latitude: Double, longitude: Double) {
        var map = getMap()
        map.animateCamera(CameraUpdateFactory
                .newLatLngZoom(LatLng(latitude, longitude), 15f))
    }

    private fun getMap() = shareLocationMapView.map

    private fun initMap(savedInstanceState: Bundle?) {
        shareLocationMapView.onCreate(savedInstanceState)
        var map = shareLocationMapView.map
        initMyLocationDot(map)
    }

    private fun initMyLocationDot(map: AMap) {
        map.isMyLocationEnabled = true
        var locationStyle = MyLocationStyle()
        locationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATE)
        locationStyle.interval(2000)
        locationStyle.showMyLocation(true)
        map.setMyLocationStyle(locationStyle)
    }

    private fun initHead() {
        setToolbarTitle("新增地址")
        setToolbarLeftButtonVisiable(true)
    }

    override fun onDestroy() {
        super.onDestroy()
        amapLocalUtils?.unRegister()
    }
}

布局

<?xml version="1.0" encoding="utf-8"?>
<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="cn.qingyangkeji.qingyang.activity.ShareLocationActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:orientation="vertical"
        android:layout_height="match_parent">

        <include layout="@layout/layout_head"></include>

        <com.lufficc.stateLayout.StateLayout
            android:layout_width="match_parent"
            android:id="@+id/shareLocationStateLayout"
            android:layout_height="match_parent">
            <LinearLayout
                android:layout_width="match_parent"
                android:orientation="vertical"
                android:layout_height="match_parent">

                <LinearLayout
                    android:layout_width="match_parent"
                    android:background="@color/white"
                    android:orientation="horizontal"
                    android:gravity="center_vertical"
                    android:layout_height="73px">

                    <TextView
                        android:id="@+id/shareLocationCityNameText"
                        android:layout_width="wrap_content"
                        android:drawableLeft="@drawable/location_icon"
                        android:drawablePadding="15px"
                        android:text=""
                        android:layout_marginLeft="29px"
                        android:textColor="#2D2D2D"
                        android:textSize="30px"
                        android:layout_height="wrap_content" />

                    <ImageView
                        android:layout_width="18px"
                        android:src="@drawable/location_bottom_arrow"
                        android:layout_marginLeft="8px"
                        android:layout_height="12px" />

                    <EditText
                        android:maxLines="1"
                        android:singleLine="true"
                        android:layout_width="0dp"
                        android:layout_weight="1"
                        android:background="@null"
                        android:hint="查找周边学校 / 大厦 / 小区"
                        android:textColorHint="#999999"
                        android:textSize="26px"
                        android:imeOptions="actionDone"
                        android:id="@+id/shareLocationEdit"
                        android:layout_marginLeft="96px"
                        android:layout_height="wrap_content" />

                    <TextView
                        android:paddingRight="20px"
                        android:paddingLeft="20px"
                        android:textColor="#2D2D2D"
                        android:id="@+id/shareLocationSearchButton"
                        android:layout_width="wrap_content"
                        android:text="搜索"
                        android:layout_height="wrap_content" />

                </LinearLayout>

                <RelativeLayout
                    android:layout_width="match_parent"
                    android:layout_height="647px">

                    <com.amap.api.maps2d.MapView
                        android:layout_width="match_parent"
                        android:id="@+id/shareLocationMapView"
                        android:layout_height="647px"></com.amap.api.maps2d.MapView>

                    <ImageView
                        android:layout_width="70px"
                        android:src="@drawable/restore_location_icon"
                        android:layout_alignParentBottom="true"
                        android:layout_alignParentLeft="true"
                        android:layout_marginLeft="15px"
                        android:id="@+id/restoreLocationButton"
                        android:layout_marginBottom="50px"
                        android:layout_height="70px" />

                    <ImageView
                        android:layout_width="48px"
                        android:id="@+id/shareLocationCenterIcon"
                        android:src="@drawable/location_center_icon"
                        android:layout_centerInParent="true"
                        android:layout_height="62px" />

                </RelativeLayout>

                <ListView
                    android:layout_width="match_parent"
                    android:id="@+id/shareLocationListView"
                    android:layout_height="match_parent"></ListView>


            </LinearLayout>

        </com.lufficc.stateLayout.StateLayout>



    </LinearLayout>

</RelativeLayout>

第二个 Activity 的代码

class PoiSearchResultListActivity : BaseActivity() {
    override fun getLayoutRes(): Int = R.layout.activity_poi_search_result_list

    override fun initClick() {

    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        initHead()
        initData()
    }

    private fun initData() {
        showDialog()
        var keyword = intent.getStringExtra("keyword")
        AMapLocationUtils().getLonLat(this) {
            location ->
            doSearchPoiByKeyword(location, keyword)
        }
    }

    private fun doSearchPoiByKeyword(location: AMapLocation, keyword: String) {
        var query = PoiSearch.Query(keyword, "", location.cityCode)
        query.pageSize = 50
        var poiSearch = PoiSearch(this, query)
        poiSearch.bound = PoiSearch.SearchBound(LatLonPoint(location.latitude, location.longitude), 5000000)
        poiSearch.setOnPoiSearchListener(object : PoiSearch.OnPoiSearchListener {
            override fun onPoiItemSearched(item: PoiItem, code: Int) {

            }

            override fun onPoiSearched(result: PoiResult, code: Int) {
                if (result.pois.isEmpty()) {
                    toast("附近没有标志性建筑")
                }
                dismissDialog()
                initListView(result.pois)
                dismissDialog()
            }

        })
        poiSearch.searchPOIAsyn()
    }

    private fun initListView(pois: ArrayList<PoiItem>) {
        poiSearchResultListView.adapter = ShareLocationAdapter(this, pois)
        poiSearchResultListView.onItemClick{
            _, _: View, i: Int, _: Long ->
            var poi = pois[i]
            Bus.send(ShareLocationEvent(poi.title, poi.latLonPoint.latitude, poi.latLonPoint.longitude))
            finish()
            Logcat.d("finish", "")
            Bus.send(FinishShareLocationEvent())
        }
    }

    private fun initHead() {
        setToolbarTitle("选择地址")
        setToolbarLeftButtonVisiable(true)
    }
}

布局

<?xml version="1.0" encoding="utf-8"?>
<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="cn.qingyangkeji.qingyang.activity.PoiSearchResultListActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:orientation="vertical"
        android:layout_height="match_parent">

        <include layout="@layout/layout_head"></include>

        <ListView
            android:layout_width="match_parent"
            android:id="@+id/poiSearchResultListView"
            android:layout_height="match_parent"></ListView>

    </LinearLayout>

</RelativeLayout>

代码和公司项目的耦合太多,不好分享出整个项目源码出来。有问题再问我。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,417评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,921评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,850评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,945评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,069评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,188评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,239评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,994评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,409评论 1 304
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,735评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,898评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,578评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,205评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,916评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,156评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,722评论 2 363
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,781评论 2 351

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,907评论 25 707
  • Google在今年的IO大会上宣布,将Android开发的官方语言更换为Kotlin,作为跟着Google玩儿An...
    蓝灰_q阅读 76,818评论 31 489
  • 1、通过CocoaPods安装项目名称项目信息 AFNetworking网络请求组件 FMDB本地数据库组件 SD...
    阳明先生_X自主阅读 15,975评论 3 119
  • 溢思得瑞集团成立于2013年,它是一个非常年轻而且充满活力的企业。我加入溢思得瑞集团已经2年不到的时间,在大公司里...
    亮晶昌阅读 502评论 1 1
  • 月光之下 旧事纷繁雨落 积水成渊 花好花坠 玉润玉碎 唯有月圆如新 荣烟好 岁漫长 源安稳
    积水空庭阅读 273评论 0 0