继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

android 开发:仿照微信 发送本人位置(基于百度地图)(前篇)

慕码人3916992
关注TA
已关注
手记 102
粉丝 81
获赞 3602

首先先上一张开发效果图:
图片描述
效果是模仿微信的发送位置,项目的框架上采用mvp模式,并用了我自己写的一套lib,地址ndileber
首先界面上的开发,我简单粘贴代码(笑)

activity_location_baidu.xml

<?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"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@color/g_child_page_bg_color">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/app_bar_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay"
        app:elevation="0dp">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:titleTextAppearance="@style/Toolbar.TitleText">

            <include layout="@layout/nim_action_bar_right_clickable_tv" />
        </android.support.v7.widget.Toolbar>
    </android.support.design.widget.AppBarLayout>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/search_view"
        android:layout_above="@+id/search_list"
        >

        <com.baidu.mapapi.map.MapView
            android:id="@+id/bmapView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:clickable="true" />
        <LinearLayout
            android:id="@+id/location_info"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_above="@+id/location_pin"
            android:layout_centerHorizontal="true"
            android:background="@drawable/marker_info_bg"
            android:orientation="vertical"
            android:paddingLeft="8dp"
            android:paddingRight="8dp"
            android:visibility="gone">

            <TextView
                android:id="@+id/marker_address"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/location_map"
                android:textColor="@color/white"
                android:textSize="12sp" />
        </LinearLayout>

        <Button
            android:id="@+id/my_location"
            android:layout_width="@dimen/friend_map_btn_height"
            android:layout_height="@dimen/friend_map_btn_height"
            android:background="@drawable/btn_location_selector"
            android:layout_alignParentBottom="true"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true"
            android:layout_marginLeft="16dp"
            android:layout_marginStart="16dp"
            android:layout_marginBottom="17dp" />

        <ImageView
            android:id="@+id/location_pin"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@mipmap/pin"
            android:layout_centerVertical="true"
            android:layout_centerHorizontal="true" />
    </RelativeLayout>

    <!--<View-->
        <!--android:id="@+id/assist_my_location"-->
        <!--android:layout_width="match_parent"-->
        <!--android:layout_height="24dip"-->
        <!--android:layout_alignParentBottom="true" />-->

    <android.support.v7.widget.RecyclerView
        android:layout_width="match_parent"
        android:layout_height="230dp"
        android:id="@+id/search_list"

        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_alignParentBottom="true">

    </android.support.v7.widget.RecyclerView>

    <!--<EditText-->
        <!--android:layout_width="match_parent"-->
        <!--android:layout_height="wrap_content"-->
        <!--android:id="@+id/search_text"-->
        <!--android:layout_below="@+id/app_bar_layout"-->
        <!--android:imeOptions="actionSearch"-->
        <!--android:singleLine="true"-->
        <!--android:inputType="text"-->
        <!--android:layout_centerHorizontal="true" />-->

    <include
        android:id="@+id/search_view"
        layout="@layout/search_edittext"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/app_bar_layout"/>

</RelativeLayout>

cell的界面

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:padding="4dp"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="来广营"
        android:textColor="@color/black"
        android:textSize="@dimen/recy_kicatuib_item_title"
        android:id="@+id/location_name" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="北京市朝阳区"
        android:textSize="@dimen/recy_kicatuib_item_content"
        android:textColor="#595959"
        android:id="@+id/location_local" />
</LinearLayout>

当然很多资源文件我懒得剔除了,大家自己把资源那块全换为具体数值吧

LocationAdapter的代码,由于我写了两套,一套是百度地图的,一套是高德地图的,里面有切换方式,大家可以吧高德地图的那块去掉。

public class LocationAdapter extends RecyclerView.Adapter<LocationAdapter.LocationViewHolder>{

    List<PoiItem> poiItems = null;
    List<PoiInfo> poiInfos = null;

    LocationAmapActivity.LocationOnCreateItem locationOnCreateItem = null;
    LocationBaiduActivity.LocationOnCreateItem locationOnCreateItem2 = null;

    public LocationAdapter(List<PoiItem> poiItems,LocationAmapActivity.LocationOnCreateItem locationOnCreateItem){
        this.poiItems = poiItems;
        this.locationOnCreateItem = locationOnCreateItem;
    }

    public LocationAdapter(List<PoiInfo> poiInfos, LocationBaiduActivity.LocationOnCreateItem locationOnCreateItem){
        this.poiInfos = poiInfos;
        this.locationOnCreateItem2 = locationOnCreateItem;
    }

    public void refData(List<PoiItem> poiItems){
        this.poiItems = poiItems;
        notifyDataSetChanged();
    }

    public void refData2(List<PoiInfo> poiInfos){
        this.poiInfos = poiInfos;
        notifyDataSetChanged();
    }

    @Override
    public LocationViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.recy_location_item, parent, false);
        return new LocationViewHolder(view);
    }

    @Override
    public void onBindViewHolder(final LocationViewHolder holder, int position) {
        if(App.MAP_TYPE == App.MAP_BAIDU){
            holder.poiInfo = poiInfos.get(position);
            holder.location_name.setText(holder.poiInfo.name);
            holder.location_local.setText(holder.poiInfo.address);
            if(locationOnCreateItem2!=null){
                holder.mView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        locationOnCreateItem2.onItemClick(holder.poiInfo);
                    }
                });
            }
        }else{
            holder.poiItem = poiItems.get(position);
            holder.location_name.setText(holder.poiItem.getTitle());
            holder.location_local.setText(holder.poiItem.getSnippet());
            Logger.d(holder.poiItem.getCityName()+holder.poiItem.getProvinceName()+holder.poiItem.getSnippet()+holder.poiItem.getWebsite());
            if(locationOnCreateItem!=null){
                holder.mView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        locationOnCreateItem.onItemClick(holder.poiItem);
                    }
                });
            }
        }

    }

    @Override
    public int getItemCount() {
        if(App.MAP_TYPE == App.MAP_BAIDU){
            if(poiInfos==null){
                return 0;
            }else{
                return poiInfos.size();
            }
        }else{
            if(poiItems==null){
                return 0;
            }else{
                return poiItems.size();
            }
        }
    }

    public class LocationViewHolder extends RecyclerView.ViewHolder{
        private final View mView;
        private PoiItem poiItem;
        private PoiInfo poiInfo;
        private final TextView location_name;
        private final TextView location_local;

        public LocationViewHolder(View itemView) {
            super(itemView);
            mView = itemView;
            location_name = (TextView) itemView.findViewById(R.id.location_name);
            location_local = (TextView) itemView.findViewById(R.id.location_local);

        }
    }

}

建立接口的连接器:Contract
LocationBaiduContract.java

public interface LocationBaiduContract extends BaseContract{

    public interface View extends BaseView<Presenter>{
        void setAddress(String address);
        void refData(List<PoiInfo> poiInfoList);
        void sendButtonStatus(int status);
        void pinInfoPanelStatus(int status);
        MapView getMapView();
        void keybordState(boolean show);
        void searchText(String text);
        void setPinInfoText(String text);
        String getSearchText();
        void deleteVisibility(int visiblility);
    }

    public interface Presenter extends BasePresenter,NimLocationManager.NimLocationListener,
            android.view.View.OnClickListener,BaiduMap.OnMapStatusChangeListener,OnGetGeoCoderResultListener,OnGetPoiSearchResultListener,BDLocationListener,LocationBaiduActivity.LocationOnCreateItem,TextWatcher,TextView.OnEditorActionListener {
        void initMap();
    }

}

建立presenter,来操作业务,里面大部分代码都是百度地图开发的代码,基本不解释了
LocationBaiduPresenter.java

public class LocationBaiduPresenter implements LocationBaiduContract.Presenter{

    LocationBaiduContract.View view;

    public LocationBaiduPresenter(LocationBaiduContract.View view){
        this.view = Check.checkNotNull(view, "view cannot be null!");
        this.view.setPresenter(this);
    }

    @Override
    public void start() {

    }

    @Override
    public void onDestroy() {
        // 退出时销毁定位
        mLocClient.stop();
        // 关闭定位图层
        mBaiduMap.setMyLocationEnabled(false);
        mSearch.destroy();
    }

    private double latitude; // 经度
    private double longitude; // 维度
    private boolean isChick = false;
    private String addressInfo; // 对应的地址信息

    @Override
    public void onGetReverseGeoCodeResult(ReverseGeoCodeResult result) {
        if (result == null  result.error != SearchResult.ERRORNO.NO_ERROR) {
            view.toast( "未找到结果", Toast.LENGTH_LONG);
            return;
        }

        if (result.error == SearchResult.ERRORNO.NO_ERROR) {
            if(!isChick){
                view.setAddress(result.getAddress());
                latitude = result.getLocation().latitude;
                longitude = result.getLocation().longitude;
                addressInfo =  result.getAddress();
            }
            isChick = false;
            List<PoiInfo> poiInfoList = result.getPoiList();
            view.refData(poiInfoList);
            return;
        }
    }

    @Override
    public void onGetPoiResult(PoiResult result) {
        if (result == null  result.error == SearchResult.ERRORNO.RESULT_NOT_FOUND) {
            view.toast( "未找到结果", Toast.LENGTH_LONG);
            return;
        }
        if (result.error == SearchResult.ERRORNO.NO_ERROR) {
            view.refData(result.getAllPoi());
            return;
        }
    }

    @Override
    public void onGetGeoCodeResult(GeoCodeResult geoCodeResult) {
    }

    @Override
    public void onGetPoiDetailResult(PoiDetailResult poiDetailResult) {

    }

    @Override
    public void onGetPoiIndoorResult(PoiIndoorResult poiIndoorResult) {

    }

    @Override
    public void onLocationChanged(NimLocation location) {

    }

    private boolean isButtonLoc = false;

    LocationClient mLocClient;

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.my_location:
                isButtonLoc = true;
                mLocClient.start();
                break;
            case R.id.action_bar_right_clickable_textview:
                sendLocation();
                ((Activity)(view.getContext())).finish();
                break;
            case R.id.dileber_search_editext_delete:
                view.searchText("");
                break;
            case R.id.dileber_search_editext_button:
                search(view.getSearchText());
                break;
        }
    }
    PoiSearch mPoiSearch;

    private void search(String message){
        mPoiSearch.searchNearby(new PoiNearbySearchOption().keyword(message).location(new LatLng(latitude,longitude)).radius(500).pageNum(1));
        view.keybordState(false);
        view.searchText("");
    }

    @Override
    public void initMap() {
        mBaiduMap = view.getMapView().getMap();
        // 开启定位图层
        mBaiduMap.setMyLocationEnabled(true);
        // 定位初始化
        mLocClient = new LocationClient(view.getContext());
        mLocClient.registerLocationListener(this);
        LocationClientOption option = new LocationClientOption();
        option.setOpenGps(true); // 打开gps
        option.setCoorType("bd09ll"); // 设置坐标类型
        option.setScanSpan(1000);
        mLocClient.setLocOption(option);
        mLocClient.start();
        mBaiduMap.setOnMapStatusChangeListener(this);
        mSearch = GeoCoder.newInstance();
        mSearch.setOnGetGeoCodeResultListener(this);
        mPoiSearch = PoiSearch.newInstance();
        mPoiSearch.setOnGetPoiSearchResultListener(this);
    }

    private static LocationProvider.Callback mCallback;
    public static void start(Context context, LocationProvider.Callback callback) {
        mCallback = callback;
        context.startActivity(new Intent(context, LocationBaiduActivity.class));
    }
    private void sendLocation() {
        addressInfo = TextUtils.isEmpty(addressInfo) ? MainApplication.getAppContext().getString(R.string.location_address_unkown) : addressInfo;
        if (mCallback != null) {
            mCallback.onSuccess(longitude, latitude, addressInfo);
        }
    }

    /**
     * 手势操作地图,设置地图状态等操作导致地图状态开始改变。
     * @param mapStatus 地图状态改变开始时的地图状态
     */
    @Override
    public void onMapStatusChangeStart(MapStatus mapStatus) {

    }
    /**
     * 地图状态变化中
     * @param mapStatus 当前地图状态
     */
    @Override
    public void onMapStatusChange(MapStatus mapStatus) {

    }
    /**
     * 地图状态改变结束
     * @param mapStatus 地图状态改变结束后的地图状态
     */
    @Override
    public void onMapStatusChangeFinish(MapStatus mapStatus) {

        LatLng ll=mapStatus.target;
        Logger.d("map change sts ch fs:"+ll.latitude+","+ll.longitude+"");
        searchNearBy(ll);
    }

    GeoCoder mSearch;

    public void searchNearBy(LatLng latLng){
        mSearch.reverseGeoCode(new ReverseGeoCodeOption()
                .location(latLng));
    }
    boolean isFirstLoc = true; // 是否首次定位
    BaiduMap mBaiduMap;

    @Override
    public void onReceiveLocation(BDLocation location) {
        // map view 销毁后不在处理新接收的位置
        if (location == null  view.getMapView() == null) {
            return;
        }
        view.sendButtonStatus(View.VISIBLE);
        view.pinInfoPanelStatus(View.VISIBLE);
        MyLocationData locData = new MyLocationData.Builder()
                .accuracy(location.getRadius())
                // 此处设置开发者获取到的方向信息,顺时针0-360
                .direction(100).latitude(location.getLatitude())
                .longitude(location.getLongitude()).build();
        mBaiduMap.setMyLocationData(locData);
        if (isFirstLocisButtonLoc) {
            isFirstLoc = false;
            isButtonLoc = false;
            LatLng ll = new LatLng(location.getLatitude(),
                    location.getLongitude());
            MapStatus.Builder builder = new MapStatus.Builder();
            builder.target(ll).zoom(18.0f);
            mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()));
            searchNearBy(ll);
        }
        mLocClient.stop();
    }

    @Override
    public void onItemClick(PoiInfo poiInfo) {
        view.setPinInfoText(poiInfo.name);
        MapStatus.Builder builder = new MapStatus.Builder();
        builder.target(poiInfo.location).zoom(18.0f);
        mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()));
        latitude = poiInfo.location.latitude;
        longitude = poiInfo.location.longitude;
        addressInfo = poiInfo.name;
        isChick = true;
    }

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {

    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {

    }

    @Override
    public void afterTextChanged(Editable s) {
        int size = view.getSearchText().length();
        if(size>0){
            view.deleteVisibility(View.VISIBLE);
        }else{
            view.deleteVisibility(View.GONE);
        }
    }

    @Override
    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
        if (actionId == EditorInfo.IME_ACTION_SEARCH) {
            search(view.getSearchText());
        }
        return false;
    }
}
打开App,阅读手记
3人推荐
发表评论
随时随地看视频慕课网APP

热门评论

有demo吗 求demo

                 赞自己

查看全部评论