-
-
Save Lingviston/1d97660f7a5888ca0f76 to your computer and use it in GitHub Desktop.
public class MainActivity extends AppCompatActivity implements SlidingUpPanelLayout.PanelSlideListener{ | |
private SupportMapFragment mMapFragment; | |
private SlidingUpPanelLayout mSlidingUpPanelLayout; | |
@Override | |
protected void onCreate(@Nullable Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
setContentView(R.layout.activity_main); | |
mSlidingUpPanelLayout = (SlidingUpPanelLayout) findViewById(R.id.slidingUpLayout); | |
mSlidingUpPanelLayout.setPanelSlideListener(this); | |
mMapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map); | |
mMapFragment.getMapAsync(new OnMapReadyCallback() { | |
@Override | |
public void onMapReady(GoogleMap googleMap) { | |
LatLng latLng = new LatLng(53.9, 27.5666667); | |
CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(latLng, 17); | |
MarkerOptions options = new MarkerOptions().position(latLng); | |
googleMap.addMarker(options); | |
googleMap.moveCamera(cameraUpdate); | |
} | |
}); | |
} | |
@Override | |
public void onPanelSlide(View panel, final float slideOffset) { | |
final int panelHeight = findViewById(R.id.panel).getHeight(); | |
final int visiblePanelHeight = mSlidingUpPanelLayout.getPanelHeight(); | |
mMapFragment.getMapAsync(new OnMapReadyCallback() { | |
@Override | |
public void onMapReady(GoogleMap googleMap) { | |
CameraPosition cameraPosition = googleMap.getCameraPosition(); | |
CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); | |
googleMap.setPadding(0,0,0, (int) (visiblePanelHeight + (panelHeight - visiblePanelHeight) * slideOffset)); | |
googleMap.moveCamera(cameraUpdate); | |
} | |
}); | |
} | |
@Override | |
public void onPanelCollapsed(View panel) { | |
} | |
@Override | |
public void onPanelExpanded(View panel) { | |
} | |
@Override | |
public void onPanelAnchored(View panel) { | |
} | |
@Override | |
public void onPanelHidden(View panel) { | |
} | |
} |
<?xml version="1.0" encoding="utf-8"?> | |
<com.sothree.slidinguppanel.SlidingUpPanelLayout | |
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:id="@+id/slidingUpLayout" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
android:gravity="bottom" | |
app:umanoOverlay="true" | |
app:umanoPanelHeight="40dp" | |
app:umanoShadowHeight="0dp" | |
app:umanoFadeColor="@android:color/transparent"> | |
<fragment | |
android:id="@+id/map" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
android:name="com.google.android.gms.maps.SupportMapFragment" | |
tools:context=".MapsActivity"/> | |
<TextView | |
android:id="@+id/panel" | |
android:layout_width="match_parent" | |
android:layout_height="400dp" | |
android:text="Drag me" | |
android:background="@android:color/white" | |
android:gravity="center_horizontal|top"/> | |
</com.sothree.slidinguppanel.SlidingUpPanelLayout> |
Give this id to the root view of UI part which slides over the map. I suppose in your case it's "dragView".
public class MainActivity extends FragmentActivity implements LocationListener {
private static final String LIST_FRAGMENT_TAG = "list_fragment";
private static final String TAG = "DemoActivity";
GoogleMap googleMap;
double currentLat , currentLon;
LocationManager locationManager;
Location mlocation;
double latitude;
double longitude;
LatLng latLng,points;
Boolean flag = false;
String mLastUpdateTime;
CameraPosition INIT;
private SlidingUpPanelLayout mLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (!isGooglePlayServiceAvailable()) {
finish();
}
final SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
googleMap = mapFragment.getMap();
googleMap.setMyLocationEnabled(true);
googleMap.getUiSettings().setCompassEnabled(false);
LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
Criteria criteria = new Criteria();
String bestProvider = locationManager.getBestProvider(criteria, true);
mlocation = locationManager.getLastKnownLocation(bestProvider);
if (mlocation != null) {
onLocationChanged(mlocation);
}
locationManager.requestLocationUpdates(bestProvider, 20000, 0, this);
/*SlidingPanelUpLayout*/
mLayout = (SlidingUpPanelLayout) findViewById(R.id.sliding_layout);
// mLayout.setAnchorPoint(0.3f);
mLayout.setPanelState(SlidingUpPanelLayout.PanelState.HIDDEN);
// mLayout.setParallaxOffset(10);
mLayout.setPanelSlideListener(new SlidingUpPanelLayout.PanelSlideListener() {
@Override
public void onPanelSlide(View panel, final float slideOffset) {
Log.i(TAG, "onPanelSlide, offset " + slideOffset);
googleMap.getUiSettings().setAllGesturesEnabled(true);
final int panelHeight = findViewById(R.id.dragView).getHeight();
final int visiblePanelHeight = mLayout.getPanelHeight();
mapFragment.getMapAsync(new OnMapReadyCallback() {
@Override
public void onMapReady(GoogleMap googleMap) {
CameraPosition cameraPosition = googleMap.getCameraPosition();
CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition);
googleMap.setPadding(5,10,10, (int) (visiblePanelHeight + (panelHeight - visiblePanelHeight)*slideOffset));
googleMap.moveCamera(cameraUpdate);
}
});
}
@Override
public void onPanelExpanded(View panel) {
Log.i(TAG, "onPanelExpanded");
googleMap.getUiSettings().setAllGesturesEnabled(false);
}
@Override
public void onPanelCollapsed(View panel) {
flag=true;
Log.i(TAG, "onPanelCollapsed");
googleMap.getUiSettings().setAllGesturesEnabled(false);
}
@Override
public void onPanelAnchored(View panel) {
Log.i(TAG, "onPanelAnchored");
}
@Override
public void onPanelHidden(View panel) {
flag=false;
Log.i(TAG, "onPanelHidden");
}
});
}
public Boolean isGooglePlayServiceAvailable() {
int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (ConnectionResult.SUCCESS == status) {
return true;
} else {
GooglePlayServicesUtil.getErrorDialog(status, this, 0).show();
return false;
}
}
@Override
public void onLocationChanged(Location location) {
mlocation = location;
latitude = location.getLatitude();
longitude = location.getLongitude();
latLng = new LatLng(latitude, longitude);
long atTime = mlocation.getTime();
mLastUpdateTime = DateFormat.getTimeInstance().format(new Date(atTime));
MarkerOptions options = new MarkerOptions();
options.position(latLng).icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_ORANGE));
googleMap.addMarker(options.title(getAdress()));
googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
INIT =
new CameraPosition.Builder()
.target(latLng)
.zoom(17.5F)
.bearing(300F) // orientation
.tilt(50F) // viewing angle
.build();
googleMap.moveCamera(CameraUpdateFactory.newCameraPosition(INIT));
googleMap.getUiSettings().setCompassEnabled(false);
/** Marker Click *//
googleMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
@Override
public boolean onMarkerClick(Marker marker) {
Log.i("Marker","Click");
points = new LatLng(marker.getPosition().latitude,marker.getPosition().longitude);
if(flag==false){
if(mLayout!=null){
Log.i("Marker", "collapsed");
// mLayout.setAnchorPoint(0.5f);
// mLayout.setPanelState(SlidingUpPanelLayout.PanelState.ANCHORED);
mLayout.setPanelState(SlidingUpPanelLayout.PanelState.COLLAPSED);
animateLatLngZoom(points, 0, -10, 10);
}}else{
Log.i("Marker","Hidden");
// mLayout.setAnchorPoint(0.3f);
// mLayout.setPanelState(SlidingUpPanelLayout.PanelState.COLLAPSED);
mLayout.setPanelState(SlidingUpPanelLayout.PanelState.HIDDEN);
}
// toggleList();
return true;
}
});
private void animateLatLngZoom(LatLng latlng, int reqZoom, int offsetX, int offsetY) {
/*calculate the offset's center in the required zoom from original's offset, and then animate the map's camera.
For this, first move the map's camera to the desired zoom, calculate the offset for that zoom level, and then restore
the original zoom.After calculating the new center we can make the animation with CameraUpdateFactory.newLatLngZoom.*/
// Save current zoom
// float originalZoom = googleMap.getCameraPosition().zoom;
// Move temporarily camera zoom
// googleMap.moveCamera(CameraUpdateFactory.zoomTo(reqZoom));
Point pointInScreen = googleMap.getProjection().toScreenLocation(latlng);
Point newPoint = new Point();
newPoint.x = pointInScreen.x + offsetX;
newPoint.y = pointInScreen.y + offsetY;
LatLng newCenterLatLng = googleMap.getProjection().fromScreenLocation(newPoint);
// Restore original zoom
// googleMap.moveCamera(CameraUpdateFactory.zoomTo(originalZoom));
// Animate a camera with new latlng center and required zoom.
// googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(newCenterLatLng, reqZoom));
googleMap.animateCamera(CameraUpdateFactory.newLatLng(newCenterLatLng));
}
}
main_activity.xml
<com.sothree.slidinguppanel.SlidingUpPanelLayout
xmlns:sothree="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/sliding_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="bottom"
sothree:umanoShadowHeight="0dp"
sothree:umanoPanelHeight="300dp"
sothree:umanoOverlay="true"
sothree:umanoFadeColor="@android:color/transparent"
sothree:umanoDragView="@+id/dragView">
<fragment
android:id="@+id/map"
android:windowSoftInputMode="adjustResize"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.SupportMapFragment"/>
<include layout="@layout/sliding_fragment_layout"
android:background="#ffffff"
android:clickable="true"
android:focusable="false"
android:id="@+id/dragView"/>
</com.sothree.slidinguppanel.SlidingUpPanelLayout>
sliding_fragment_layout
<?xml version="1.0" encoding="utf-8"?>
<TableLayout
android:id="@+id/verified"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="60dp"
android:clickable="true"
android:focusable="false"
android:paddingLeft="10dp"
android:background="#FFFF"
android:paddingRight="10dp"
android:paddingTop="10dp"
xmlns:android="http://schemas.android.com/apk/res/android">
<!--android:descendantFocusability="beforeDescendants"-->
<!--android:focusableInTouchMode="true"-->
<TextView
android:id="@+id/panel"
android:layout_width="match_parent"
android:layout_height="400dp"
android:text="Drag me"
android:background="@android:color/white"
android:gravity="center_horizontal|top"/>
</TableLayout>
Just watched your video. Padding setted correctly. You can see it by Google mark being moved on top of the panel. So it looks like the problem is in animation of zoom to the marker on marker tap. Like I said during animation CURRENT map center stays untouched and in your case marker is not in center of the map when tap performed. What you can do is:
- On tap save the marker position in the local variable.
- In onPanelSlide callback move camera not to the current map center like I did but to the position you saved.
Okay two things : firstly , i think i passed the correct padding and even after removing animation it works with same issue . And Secondly , If applying an answer gives me more issue then why would i apply it . Hence , it is in scope .
okay i try the above solution . And see if it resolving my issue . Anyways thanx alot again
Your original question was about map shaking. The problem was in that you don't understand how Android lays out views. It is solved by my answer as you confirmed. Problem with marker positioning is out of the scope cause it has nothing to do with map shaking.
In fact your current problem is in camera positioning on tap/slide up. It can be easily solved by you otherwise another question should be asked.
Let me know if suggested solution helps you.
hey , thanks this worked . But can i ask you something that might be out of scope . When i am clicking on panel its Expanded and clicking again panel it going on panel height instead i want it to go Hidden . Can i do it ?
Well , yes suggestion worked . And marked tick on stack as well . 👍
And while using answer i learnt many things . Really . this not only resolved my issue but help exploring and learning stuff .
Yes. By default tapping on dragview again sets state to COLLAPSED and it's ok in your case. You incorrectly understand the meaning of app:umanoPanelHeight attribute. It's height of the visible part in collapsed state. So you have to set it to 0dp and probably set TableLayout's height to 300 dp.
Or probably you can simply set state to HIDDEN on second tap but my opinion is that the first solution is more correct.
I understood the meaning . But its really like troubling me with one another issue . Setting an panelHeight = 0 will raise a problem : on clicking marker no panel will show up . 2 . On making table layout to 300 dp : It will show panel on launch of app instead clicking marker and come up .
:( So thats the issue . Should i change in slidingUpPanel file instead changing to this ?
Actually slidingUpPanel is collapsed on start. You defenitly do something wrong.
I have done exactly what u said . I mean just changes in xml 's . Ahha.... mine is Hidden on start might be thats why . As i want it changed to collapsed on marker click only
hey , it worked as per my need but just a query : In the xml , you have given @+id/panel to textView . But like in my activity xml its include an another xml (pasted in Question both the activity.xml and included xml i.e. sliding_fragment_layout ) , so who would i define id @+id/panel in my sliding_fragment_layout . So . it calculate panel height in onPanelSlide method and also work as drag_view