How to Implement draggable map like uber android, Update with change location -


how implement draggable map uber? using google maps v2. got solution referring this post , sharing complete solution here

updated latest code included change location autocomplete

complete project can found here

logic simple need framelayout , add map , marker layout inside framelayout make maker layout gravity center , latitude , longitude of centre point of map on camera change refer this answer here code create activity_maps.xml

<relativelayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/white" android:orientation="vertical">  <linearlayout     android:id="@+id/container_toolbar"     android:layout_width="match_parent"     android:layout_height="wrap_content"     android:orientation="vertical">      <include         android:id="@+id/toolbar"         layout="@layout/toolbar" />      <linearlayout         android:layout_width="match_parent"         android:layout_height="wrap_content"         android:layout_marginleft="5dp"         android:layout_marginright="5dp"         android:layout_margintop="5dp"         android:orientation="vertical">          <textview android:gravity="center_vertical"             android:id="@+id/locality"             android:layout_width="match_parent"             android:layout_height="wrap_content"             android:drawableleft="@drawable/ic_btn_current_location"             android:drawablepadding="@dimen/list_row_padding"             android:ellipsize="end"             android:padding="10dp"             android:singleline="true"             android:text="click change location"             android:textsize="@dimen/font_22" />          <edittext             android:id="@+id/address"             android:layout_width="match_parent"             android:layout_height="wrap_content"             android:layout_margintop="5dp"             android:ellipsize="end"             android:enabled="false"             android:hint="address"             android:singleline="true" />     </linearlayout> </linearlayout> <framelayout     android:layout_width="match_parent"     android:layout_height="match_parent"     android:layout_below="@+id/container_toolbar">      <fragment         xmlns:tools="http://schemas.android.com/tools"         android:id="@+id/map"         android:name="com.google.android.gms.maps.supportmapfragment"         android:layout_width="match_parent"         android:layout_height="match_parent"         tools:context="com.sample.sishin.maplocation.mapsactivity" />     <linearlayout         android:id="@+id/locationmarker"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:layout_gravity="center"         android:layout_marginbottom="30dp"         android:gravity="center"         android:orientation="vertical" >          <textview             android:id="@+id/locationmarkertext"             android:layout_width="wrap_content"             android:layout_height="wrap_content"             android:background="@drawable/rounded_corner_map"             android:gravity="center"             android:minwidth="250dp"             android:paddingleft="2dp"             android:paddingright="2dp"             android:text=" set location "             android:textcolor="@android:color/white" />          <imageview             android:id="@+id/imagemarker"             android:layout_width="wrap_content"             android:layout_height="wrap_content"             android:src="@drawable/add_marker" />     </linearlayout>    </framelayout> 

create textview backgound xml here rounded_corner_map.xml

<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" >      <solid android:color="#000000" />      <stroke         android:width="2dp"         android:color="#ffffff" />      <padding         android:bottom="8dp"         android:left="1dp"         android:right="1dp"         android:top="8dp" />      <corners         android:bottomleftradius="15dp"         android:bottomrightradius="15dp"         android:topleftradius="15dp"         android:toprightradius="15dp" />  </shape> 

and here activity class mainactivity.java

    package com.sample.sishin.maplocation;      import android.manifest;     import android.app.alertdialog;     import android.content.context;     import android.content.dialoginterface;     import android.content.intent;     import android.content.pm.packagemanager;     import android.location.location;     import android.os.handler;     import android.os.resultreceiver;     import android.provider.settings;     import android.support.v4.app.activitycompat;     import android.os.bundle;      import android.support.v7.app.appcompatactivity;     import android.support.v7.widget.toolbar;     import android.util.log;     import android.view.view;     import android.widget.edittext;     import android.widget.textview;     import android.widget.toast;      import com.google.android.gms.common.connectionresult;     import com.google.android.gms.common.googleapiavailability;     import com.google.android.gms.common.googleplayservicesnotavailableexception;     import com.google.android.gms.common.googleplayservicesrepairableexception;     import com.google.android.gms.common.googleplayservicesutil;     import com.google.android.gms.common.api.googleapiclient;     import com.google.android.gms.common.api.status;     import com.google.android.gms.location.locationrequest;     import com.google.android.gms.location.locationservices;     import com.google.android.gms.location.places.place;     import com.google.android.gms.location.places.ui.placeautocomplete;     import com.google.android.gms.maps.cameraupdatefactory;     import com.google.android.gms.maps.googlemap;     import com.google.android.gms.maps.onmapreadycallback;     import com.google.android.gms.maps.supportmapfragment;     import com.google.android.gms.maps.model.cameraposition;     import com.google.android.gms.maps.model.latlng;      public class mapsactivity extends appcompatactivity implements onmapreadycallback, googleapiclient.connectioncallbacks, googleapiclient.onconnectionfailedlistener, com.google.android.gms.location.locationlistener {     private googlemap mmap;     private googleapiclient mgoogleapiclient;     private final static int play_services_resolution_request = 9000;     private static string tag = "map location";     context mcontext;     textview mlocationmarkertext;     private latlng mcenterlatlong;       /**      * receiver registered activity response fetchaddressintentservice.      */     private addressresultreceiver mresultreceiver;     /**      * formatted location address.      */     protected string maddressoutput;     protected string mareaoutput;     protected string mcityoutput;     protected string mstateoutput;     edittext mlocationaddress;     textview mlocationtext;     private static final int request_code_autocomplete = 1;     toolbar mtoolbar;       @override     protected void oncreate(bundle savedinstancestate) {         super.oncreate(savedinstancestate);         setcontentview(r.layout.activity_maps);         mcontext = this;         // obtain supportmapfragment , notified when map ready used.         supportmapfragment mapfragment = (supportmapfragment) getsupportfragmentmanager()                 .findfragmentbyid(r.id.map);          mlocationmarkertext = (textview) findviewbyid(r.id.locationmarkertext);         mlocationaddress = (edittext) findviewbyid(r.id.address);         mlocationtext = (textview) findviewbyid(r.id.locality);         mtoolbar = (toolbar) findviewbyid(r.id.toolbar);         setsupportactionbar(mtoolbar);         getsupportactionbar().setdisplayshowhomeenabled(true);          getsupportactionbar().settitle(getresources().getstring(r.string.app_name));           mlocationtext.setonclicklistener(new view.onclicklistener() {             @override             public void onclick(view view) {                  openautocompleteactivity();              }           });         mapfragment.getmapasync(this);         mresultreceiver = new addressresultreceiver(new handler());          if (checkplayservices()) {             // if check succeeds, proceed normal processing.             // otherwise, prompt user valid play services apk.             if (!apputils.islocationenabled(mcontext)) {                 // notify user                 alertdialog.builder dialog = new alertdialog.builder(mcontext);                 dialog.setmessage("location not enabled!");                 dialog.setpositivebutton("open location settings", new dialoginterface.onclicklistener() {                     @override                     public void onclick(dialoginterface paramdialoginterface, int paramint) {                         intent myintent = new intent(settings.action_location_source_settings);                         startactivity(myintent);                     }                 });                 dialog.setnegativebutton("cancel", new dialoginterface.onclicklistener() {                      @override                     public void onclick(dialoginterface paramdialoginterface, int paramint) {                         // todo auto-generated method stub                      }                 });                 dialog.show();             }             buildgoogleapiclient();         } else {             toast.maketext(mcontext, "location not supported in device", toast.length_short).show();         }      }       /**      * manipulates map once available.      * callback triggered when map ready used.      * can add markers or lines, add listeners or move camera. in case,      * add marker near sydney, australia.      * if google play services not installed on device, user prompted install      * inside supportmapfragment. method triggered once user has      * installed google play services , returned app.      */     @override     public void onmapready(googlemap googlemap) {         log.d(tag, "onmapready");         mmap = googlemap;          mmap.setoncamerachangelistener(new googlemap.oncamerachangelistener() {             @override             public void oncamerachange(cameraposition cameraposition) {                 log.d("camera postion change" + "", cameraposition + "");                 mcenterlatlong = cameraposition.target;                   mmap.clear();                  try {                      location mlocation = new location("");                     mlocation.setlatitude(mcenterlatlong.latitude);                     mlocation.setlongitude(mcenterlatlong.longitude);                      startintentservice(mlocation);                     mlocationmarkertext.settext("lat : " + mcenterlatlong.latitude + "," + "long : " + mcenterlatlong.longitude);                  } catch (exception e) {                     e.printstacktrace();                 }             }         });         if (activitycompat.checkselfpermission(this, manifest.permission.access_fine_location) != packagemanager.permission_granted && activitycompat.checkselfpermission(this, manifest.permission.access_coarse_location) != packagemanager.permission_granted) {             // todo: consider calling             //    activitycompat#requestpermissions             // here request missing permissions, , overriding             //   public void onrequestpermissionsresult(int requestcode, string[] permissions,             //                                          int[] grantresults)             // handle case user grants permission. see documentation             // activitycompat#requestpermissions more details.             return;         } //        mmap.setmylocationenabled(true); //        mmap.getuisettings().setmylocationbuttonenabled(true); // //        // add marker in sydney , move camera //        latlng sydney = new latlng(-34, 151); //        mmap.addmarker(new markeroptions().position(sydney).title("marker in sydney")); //        mmap.movecamera(cameraupdatefactory.newlatlng(sydney));     }      @override     public void onconnected(bundle bundle) {         if (activitycompat.checkselfpermission(this, manifest.permission.access_fine_location) != packagemanager.permission_granted && activitycompat.checkselfpermission(this, manifest.permission.access_coarse_location) != packagemanager.permission_granted) {             // todo: consider calling             //    activitycompat#requestpermissions             // here request missing permissions, , overriding             //   public void onrequestpermissionsresult(int requestcode, string[] permissions,             //                                          int[] grantresults)             // handle case user grants permission. see documentation             // activitycompat#requestpermissions more details.             return;         }         location mlastlocation = locationservices.fusedlocationapi.getlastlocation(                 mgoogleapiclient);         if (mlastlocation != null) {             changemap(mlastlocation);             log.d(tag, "on connected");          } else             try {                 locationservices.fusedlocationapi.removelocationupdates(                         mgoogleapiclient, this);              } catch (exception e) {                 e.printstacktrace();             }         try {             locationrequest mlocationrequest = new locationrequest();             mlocationrequest.setinterval(10000);             mlocationrequest.setfastestinterval(5000);             mlocationrequest.setpriority(locationrequest.priority_high_accuracy);             locationservices.fusedlocationapi.requestlocationupdates(                     mgoogleapiclient, mlocationrequest, this);          } catch (exception e) {             e.printstacktrace();         }      }      @override     public void onconnectionsuspended(int i) {         log.i(tag, "connection suspended");         mgoogleapiclient.connect();     }      @override     public void onlocationchanged(location location) {         try {             if (location != null)                 changemap(location);             locationservices.fusedlocationapi.removelocationupdates(                     mgoogleapiclient, this);          } catch (exception e) {             e.printstacktrace();         }     }      @override     public void onconnectionfailed(connectionresult connectionresult) {      }       protected synchronized void buildgoogleapiclient() {         mgoogleapiclient = new googleapiclient.builder(this)                 .addconnectioncallbacks(this)                 .addonconnectionfailedlistener(this)                 .addapi(locationservices.api)                 .build();     }      @override     protected void onstart() {         super.onstart();         try {             mgoogleapiclient.connect();          } catch (exception e) {             e.printstacktrace();         }     }      @override     protected void onstop() {         super.onstop();         try {          } catch (runtimeexception e) {             e.printstacktrace();         }         if (mgoogleapiclient != null && mgoogleapiclient.isconnected()) {             mgoogleapiclient.disconnect();         }     }      private boolean checkplayservices() {         int resultcode = googleplayservicesutil.isgoogleplayservicesavailable(this);         if (resultcode != connectionresult.success) {             if (googleplayservicesutil.isuserrecoverableerror(resultcode)) {                 googleplayservicesutil.geterrordialog(resultcode, this,                         play_services_resolution_request).show();             } else {                 //finish();             }             return false;         }         return true;     }      private void changemap(location location) {          log.d(tag, "reaching map" + mmap);           if (activitycompat.checkselfpermission(this, manifest.permission.access_fine_location) != packagemanager.permission_granted && activitycompat.checkselfpermission(this, manifest.permission.access_coarse_location) != packagemanager.permission_granted) {             // todo: consider calling             //    activitycompat#requestpermissions             // here request missing permissions, , overriding             //   public void onrequestpermissionsresult(int requestcode, string[] permissions,             //                                          int[] grantresults)             // handle case user grants permission. see documentation             // activitycompat#requestpermissions more details.             return;         }          // check if map created or not         if (mmap != null) {             mmap.getuisettings().setzoomcontrolsenabled(false);             latlng latlong;               latlong = new latlng(location.getlatitude(), location.getlongitude());              cameraposition cameraposition = new cameraposition.builder()                     .target(latlong).zoom(19f).tilt(70).build();              mmap.setmylocationenabled(true);             mmap.getuisettings().setmylocationbuttonenabled(true);             mmap.animatecamera(cameraupdatefactory                     .newcameraposition(cameraposition));              mlocationmarkertext.settext("lat : " + location.getlatitude() + "," + "long : " + location.getlongitude());             startintentservice(location);           } else {             toast.maketext(getapplicationcontext(),                     "sorry! unable create maps", toast.length_short)                     .show();         }      }       /**      * receiver data sent fetchaddressintentservice.      */     class addressresultreceiver extends resultreceiver {         public addressresultreceiver(handler handler) {             super(handler);         }          /**          * receives data sent fetchaddressintentservice , updates ui in mainactivity.          */         @override         protected void onreceiveresult(int resultcode, bundle resultdata) {              // display address string or error message sent intent service.             maddressoutput = resultdata.getstring(apputils.locationconstants.result_data_key);              mareaoutput = resultdata.getstring(apputils.locationconstants.location_data_area);              mcityoutput = resultdata.getstring(apputils.locationconstants.location_data_city);             mstateoutput = resultdata.getstring(apputils.locationconstants.location_data_street);              displayaddressoutput();              // show toast message if address found.             if (resultcode == apputils.locationconstants.success_result) {                 //  showtoast(getstring(r.string.address_found));               }           }      }      /**      * updates address in ui.      */     protected void displayaddressoutput() {         //  mlocationaddresstextview.settext(maddressoutput);         try {             if (mareaoutput != null)                // mlocationtext.settext(mareaoutput+ "");              mlocationaddress.settext(maddressoutput);             //mlocationtext.settext(mareaoutput);         } catch (exception e) {             e.printstacktrace();         }     }      /**      * creates intent, adds location data extra, , starts intent service      * fetching address.      */     protected void startintentservice(location mlocation) {         // create intent passing intent service responsible fetching address.         intent intent = new intent(this, fetchaddressintentservice.class);          // pass result receiver service.         intent.putextra(apputils.locationconstants.receiver, mresultreceiver);          // pass location data service.         intent.putextra(apputils.locationconstants.location_data_extra, mlocation);          // start service. if service isn't running, instantiated , started         // (creating process if needed); if running remains running.         // service kills automatically once intents processed.         startservice(intent);     }       private void openautocompleteactivity() {         try {             // autocomplete activity requires google play services available. intent             // builder checks , throws exception if not case.             intent intent = new placeautocomplete.intentbuilder(placeautocomplete.mode_fullscreen)                     .build(this);             startactivityforresult(intent, request_code_autocomplete);         } catch (googleplayservicesrepairableexception e) {             // indicates google play services either not installed or not date. prompt             // user correct issue.             googleapiavailability.getinstance().geterrordialog(this, e.getconnectionstatuscode(),                     0 /* requestcode */).show();         } catch (googleplayservicesnotavailableexception e) {             // indicates google play services not available , problem not             // resolvable.             string message = "google play services not available: " +                     googleapiavailability.getinstance().geterrorstring(e.errorcode);              toast.maketext(mcontext, message, toast.length_short).show();         }     }      /**      * called after autocomplete activity has finished return result.      */     @override     public void onactivityresult(int requestcode, int resultcode, intent data) {         super.onactivityresult(requestcode, resultcode, data);          // check result autocomplete widget.         if (requestcode == request_code_autocomplete) {             if (resultcode == result_ok) {                 // user's selected place intent.                 place place = placeautocomplete.getplace(mcontext, data);                  // todo call location based filter                   latlng latlong;                   latlong = place.getlatlng();                  //mlocationtext.settext(place.getname() + "");                  cameraposition cameraposition = new cameraposition.builder()                         .target(latlong).zoom(19f).tilt(70).build();                  if (activitycompat.checkselfpermission(this, manifest.permission.access_fine_location) != packagemanager.permission_granted && activitycompat.checkselfpermission(this, manifest.permission.access_coarse_location) != packagemanager.permission_granted) {                     // todo: consider calling                     //    activitycompat#requestpermissions                     // here request missing permissions, , overriding                     //   public void onrequestpermissionsresult(int requestcode, string[] permissions,                     //                                          int[] grantresults)                     // handle case user grants permission. see documentation                     // activitycompat#requestpermissions more details.                     return;                 }                 mmap.setmylocationenabled(true);                 mmap.animatecamera(cameraupdatefactory                         .newcameraposition(cameraposition));               }           } else if (resultcode == placeautocomplete.result_error) {             status status = placeautocomplete.getstatus(mcontext, data);         } else if (resultcode == result_canceled) {             // indicates activity closed before selection made. example if             // user pressed button.         }     }       } 

and manifest file is

    <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android"     package="com.sample.sishin.maplocation">      <!--          access_coarse/fine_location permissions not required use          google maps android api v2, must specify either coarse or fine          location permissions 'mylocation' functionality.      -->     <uses-permission android:name="android.permission.access_fine_location" />     <uses-permission android:name="android.permission.access_coarse_location" />     <application         android:allowbackup="true"         android:icon="@mipmap/ic_launcher"         android:label="@string/app_name"         android:supportsrtl="true"         android:theme="@style/apptheme">          <!--              api key google maps-based apis defined string resource.              (see file "res/values/google_maps_api.xml").              note api key linked encryption key used sign apk.              need different api key each encryption key, including release key used              sign apk publishing.              can define keys debug , release targets in src/debug/ , src/release/.          -->           <meta-data             android:name="com.google.android.geo.api_key"             android:value="your key here" />          <activity             android:name="com.sample.sishin.maplocation.mapsactivity"             android:label="@string/title_activity_maps">             <intent-filter>                 <action android:name="android.intent.action.main" />                  <category android:name="android.intent.category.launcher" />             </intent-filter>         </activity>         <service             android:name="com.sample.sishin.maplocation.fetchaddressintentservice"             android:exported="false" />      </application>  </manifest> 

enter image description here


Comments

Popular posts from this blog

java - Plugin org.apache.maven.plugins:maven-install-plugin:2.4 or one of its dependencies could not be resolved -

Round ImageView Android -

How can I utilize Yahoo Weather API in android -