Custom Annotation in Skobbler map - android

I am using Skobbler SDK VERSION 2.5.1. I found this. But, there are few method cannot be resolved.
SKAnnotation annotationDrawable = new SKAnnotation();
setHeight()
setWidth()
setDrawableResourceId()
I am using this for default SKAnnotationType.
private void addAnnotation(Place place) {
if (mapView != null) {
CustomSKAnnotation skAnnotation = new CustomSKAnnotation(new Random().nextInt(), place.getName());
skAnnotation.setAnnotationType(SKAnnotation.SK_ANNOTATION_TYPE_BLUE);
skAnnotation.setLocation(new SKCoordinate(place.getLongitude(), place.getLatitude()));
mapView.addAnnotation(skAnnotation, SKAnimationSettings.ANIMATION_PIN_DROP);
}
}
I want to add my custom image as a annotation icon.
What can be done to solve this problem?

// add an annotation with a view
SKAnnotation annotationFromView = new SKAnnotation(11);
annotationFromView.setLocation(new SKCoordinate(-122.423573, 37.761349));
annotationFromView.setMininumZoomLevel(5);
SKAnnotationView annotationView = new SKAnnotationView();
customView =(RelativeLayout) ((LayoutInflater)
getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(
R.layout.layout_custom_view, null, false);
//If width and height of the view are not power of 2
//the actual size of the image will be the next power of 2 of
//max(width,height).
annotationView.setView(customView);
annotationFromView.setAnnotationView(annotationView);
mapView.addAnnotation(annotationFromView, SKAnimationSettings.ANIMATION_NONE);
<—--- layout_custom_view.xml ---—>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/custom_layout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="#+id/customView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/icon_searchcenter_favorite" />
</RelativeLayout>

Related

Adding a custom view to a page not working in PDFTron.Android for Xamarin

I'm trying to use PDFTron for Xamarin Android.
I want to render and paint my custom annotations, without using their annotation system.
According to their documentation in https://www.pdftron.com/documentation/xamarin/guides/ui-customization/custom-view/android/ You can add a CustomRelativeLayout which doesn't work.
It basically renders nothing in top of the PDF
I hosted the whole solution in here http://s000.tinyupload.com/index.php?file_id=14574507524295393508 so it's easy to test and see if someone can see what's wrong.
Thanks!
UPDATE
Tried Shirley G suggestion. Modified the pdf_custom_layout to be added to:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="50dp"
android:layout_height="50dp">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Custom Layout Text View"
android:textSize="24dp"
android:elevation="2dp"/>
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/holo_red_dark" />
</LinearLayout>
and the code to:
[Activity(Label = "#string/app_name", Theme = "#style/AppTheme", MainLauncher = true)]
public class MainActivity : AppCompatActivity
{
private PDFViewCtrl _pdfControl;
private PDFDoc _doc;
protected override void OnCreate(Bundle savedInstanceState)
{
PDFNet.Initialize(this, Resource.Raw.pdfnet, "Insert commercial license key here after purchase");
base.OnCreate(savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.activity_main);
_pdfControl = FindViewById<PDFViewCtrl>(Resource.Id.pdfControl);
var assets = this.Assets;
using var sr = new StreamReader(assets.Open("dummy.pdf"));
_doc = new PDFDoc(sr.BaseStream);
_pdfControl.DocumentLoad += _pdfControl_DocumentLoad;
_pdfControl.SetDoc(_doc);
}
private void _pdfControl_DocumentLoad(object sender, System.EventArgs e)
{
var overlay = new CustomRelativeLayout(BaseContext);
var color = new Android.Graphics.Color(BaseContext.GetColor(Resource.Color.red));
overlay.SetBackgroundColor(color);
overlay.SetZoomWithParent(true);
LayoutInflater.Inflate(Resource.Layout.pdf_custom_layout, overlay);
_pdfControl.AddView(overlay);
}
But nothing happened, still no overlay shown.
UPDATE 2
I added the fixes and started working, however, when I add this code:
var overlay = new CustomRelativeLayout(BaseContext, _pdfControl, 50, 50, 1);
overlay.SetBackgroundColor(BaseContext.Resources.GetColor(Resource.Color.orange));
overlay.SetZoomWithParent(true);
_pdfControl.AddView(overlay);
overlay.LayoutParameters.Width = 300;
overlay.LayoutParameters.Height = 300;
_pdfControl.Invalidate();
overlay.RequestLayout();
I see a small rect of 50x50 at page position x=50 and y50. I specified the overlay to be 300 in width and it's not showing it.
If I add this, nothing is shown at all even the overlay should be of 300x300 at x=0, y =0.
var overlay = new CustomRelativeLayout(BaseContext, _pdfControl, 0, 0, 1);
The layout needs to be added on to the view hierarchy (i.e. PDFViewCtrl.AddView) which is not done in your project. You can find a working sample here:
https://github.com/PDFTron/pdftron-android-samples/tree/master/CustomUI
In particular, relevant code can be find here:
https://github.com/PDFTron/pdftron-android-samples/blob/master/CustomUI/app/src/main/java/com/pdftron/android/tutorial/customui/custom/CustomLinkClick.java
The sample adds the layout to page 3, since your pdf file only have 1 page, you will want to change that to page 1 in the XML layout. Do note that all posX and poxY are in page space, not screen space. Read more on the topic here:
https://www.pdftron.com/documentation/android/guides/basics/coordinates
With that in mind, running your project will see:
layout:
<pdftron.PDF.Tools.CustomRelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="50dp"
android:layout_height="50dp"
app:posX="50"
app:posY="50"
app:pageNum="1"
app:zoomWithParent="true">
<!--Child views under CustomRelativeLayout-->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Custom Layout Text View"
android:textSize="12sp"
android:elevation="2dp"/>
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/holo_red_dark" />
</pdftron.PDF.Tools.CustomRelativeLayout>
If you are adding the view programmatically, you will need to specify the location, or if you are putting it over an annotation, you can specify the annotation.
Typically looks like this:
CustomRelativeLayout overlay = new CustomRelativeLayout(context);
overlay.setBackgroundColor(context.getResources().getColor(R.color.orange));
overlay.setAnnot(pdfViewCtrl, annot, pageNum);
overlay.setZoomWithParent(true);
pdfViewCtrl.addView(overlay);

Get the position of each corner of a view, then add a view at the position

I am working on an android project where I have a custom view. When the custom view is clicked, I want a to put a view (a circle) at each corner of the view.
At the moment I'm just trying to get it work in the top left corner but it ends up in the middle.
Below is my click function for adding the view.
View view = LayoutInflater.from(getContext()).inflate(R.layout.view, this, false);
TextView textItem = view.findViewById(R.id.lblItemText);
textItem.setText("View: " + counter);
view.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
Anchor anchor1 = new Anchor(getContext());
anchor1.setLeft(v.getLeft());
anchor1.setTop(CustomView.this.getTop());
CustomView.this.addView(anchor1);
}
});
The custom view is hosted inside a relative layout. The custom view extends RelativeLayout and the anchor view which is supposed to go into the top left corner of the custom view extends button.
The anchor constructor contains the following:
public Anchor(Context context)
{
super(context);
this.setBackgroundResource(R.drawable.anchor);
this.setPadding(0,0,0,0);
this.setWidth(1);
this.setHeight(1);
}
For some reason the anchor is appearing in the middle instead of being on the corner as shown below
Below is kind of expecting.
UPDATE
After a couple of days made some progress and I do have it working, except its using hardcoded values to get it in the right position, which doesn't seem right. I'm guessing this will only work on the specific device I'm testing on, another device with another resolution will be positioned wrong.
Below is the code I have that hopefully shows what is I am trying to achieve along with a screenshot as to what I have now.
private void createAnchorPoints()
{
//Main View
ViewGroup mainView = activity.findViewById(android.R.id.content);
int[] viewToBeResizedLoc = new int[2];
viewToBeResized.getLocationOnScreen(viewToBeResizedLoc);
//Add top left anchor
Anchor topLeftAnchor = new Anchor(context, Anchor.ResizeMode.TOP_LEFT);
FrameLayout.LayoutParams topLeftParms = new FrameLayout.LayoutParams(150,150);
topLeftParms.leftMargin = viewToBeResizedLoc[0] - 50;
topLeftParms.topMargin = viewToBeResizedLoc[1] - viewToBeResized.getHeight() - 30;
topLeftAnchor.setLayoutParams(topLeftParms);
mainView.addView(topLeftAnchor);
//Add top right anchor
Anchor topRightAnchor = new Anchor(context, Anchor.ResizeMode.TOP_RIGHT);
FrameLayout.LayoutParams topRightParms = new FrameLayout.LayoutParams(150, 150);
topRightParms.leftMargin = topLeftParms.leftMargin + viewToBeResized.getWidth() - 40;
topRightParms.topMargin = topLeftParms.topMargin;
topRightAnchor.setLayoutParams(topRightParms);
mainView.addView(topRightAnchor);
//Add bottom left anchor
Anchor bottomLeftAnchor = new Anchor(context, Anchor.ResizeMode.BOTTOM_LEFT);
FrameLayout.LayoutParams bottomLeftParms = new FrameLayout.LayoutParams(150, 150);
bottomLeftParms.leftMargin = topLeftParms.leftMargin;
bottomLeftParms.topMargin = topLeftParms.topMargin + viewToBeResized.getHeight() - 40;
bottomLeftAnchor.setLayoutParams(bottomLeftParms);
mainView.addView(bottomLeftAnchor);
//Add bottom right anchor
Anchor bottomRightAnchor = new Anchor(context, Anchor.ResizeMode.BOTTOM_RIGHT);
FrameLayout.LayoutParams bottomRightParms = new FrameLayout.LayoutParams(150, 150);
bottomRightParms.leftMargin = topRightParms.leftMargin;
bottomRightParms.topMargin = bottomLeftParms.topMargin;
bottomRightAnchor.setLayoutParams(bottomRightParms);
mainView.addView(bottomRightAnchor);
}
Since the top-level layout is a RelativeLayout, you will need to use the view positioning that is available to RelativeLayout to achieve what you want. (See the documentation.)
Here is a mock-up of what you want to achieve in XML. This mock-up will demonstrate how we can approach the actual solution. I am using standard views, but it shouldn't matter. The technique will apply to your custom views. The image is from Android Studio's designer, so no code was used to create the image.
activity_main.xml
<RelativeLayout
android:id="#+id/relativeLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<RelativeLayout
android:id="#+id/customView"
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_centerInParent="true"
android:background="#android:color/holo_green_light" />
<ImageView
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_alignStart="#id/customView"
android:layout_alignTop="#id/customView"
android:src="#drawable/circle"
android:translationX="-10dp"
android:translationY="-10dp" />
<ImageView
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_alignEnd="#id/customView"
android:layout_alignTop="#id/customView"
android:src="#drawable/circle"
android:translationX="10dp"
android:translationY="-10dp" />
<ImageView
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_alignBottom="#id/customView"
android:layout_alignStart="#id/customView"
android:src="#drawable/circle"
android:translationX="-10dp"
android:translationY="10dp" />
<ImageView
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_alignBottom="#id/customView"
android:layout_alignEnd="#id/customView"
android:src="#drawable/circle"
android:translationX="10dp"
android:translationY="10dp" />
</RelativeLayout>
circle.xml
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<!-- fill color -->
<solid android:color="#android:color/holo_red_light" />
<size
android:width="20dp"
android:height="20dp" />
</shape>
The Actual Solution
Now that we have demonstrated that the mocked-up approach works, we now have to reproduce the effect in code. We will have to add the circle view and position it within the parent RelativeLayout using RelativeLayout view positioning and translations. The following code shows just the top left circle positioned, but the other circles will be positioned in a similar way.
activity_main.java
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Drawable circle = ContextCompat.getDrawable(this, R.drawable.circle);
ImageView imageView = new ImageView(this);
imageView.setImageDrawable(circle);
int circleSize = dpToPx(CIRCLE_SIZE_DP);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(circleSize, circleSize);
// Position top left circle within the custom view.
lp.addRule(RelativeLayout.ALIGN_START, R.id.customView);
lp.addRule(RelativeLayout.ALIGN_TOP, R.id.customView);
// Uncomment these 2 lines to position the top left circle with translation.
imageView.setTranslationX(-circleSize / 2);
imageView.setTranslationY(-circleSize / 2);
// Uncomment these 3 lines to position the top left circle with margins.
// View customView = findViewById(R.id.customView);
// lp.leftMargin = customView.getLeft() - circleSize / 2;
// lp.topMargin = customView.getTop() - circleSize / 2;
((RelativeLayout) findViewById(R.id.relativeLayout)).addView(imageView, lp);
}
private int dpToPx(int dp) {
return (int) (dp * getResources().getDisplayMetrics().density);
}
private static final int CIRCLE_SIZE_DP = 20;
}
The code above uses a shortened layout:
activity_main.xml
<RelativeLayout
android:id="#+id/relativeLayout"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<RelativeLayout
android:id="#+id/customView"
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_centerInParent="true"
android:background="#android:color/holo_green_light" />
</RelativeLayout>
It is also possible to produce the same positioning using margins. The code to use margins is commented out but will work. (I think that negative margins may also work, but I have read that they are not officially supported, so I try to avoid them.)

Skobbler annotation with button

I am creating a Skobbler Annotation as follows:
markerCoords = mapView.pointToCoordinate(skScreenPoint); //gives us the coordinate
SKAnnotation annotation = new SKAnnotation(11);
SKAnnotationView view = new SKAnnotationView();
View v = getLayoutInflater().inflate(R.layout.annotation_marker, null, false);
v.findViewById(R.id.btn_destination).setOnClickListener(destListener);
v.findViewById(R.id.btn_origin).setOnClickListener(originListener);
view.setView(v);
annotation.setAnnotationView(view);
annotation.setLocation(mapView.pointToCoordinate(skScreenPoint));
annotation.setMininumZoomLevel(1);
mapView.addAnnotation(annotation, SKAnimationSettings.ANIMATION_POP_OUT);
The view R.layout.annotation_marker contains a couple of buttons, but I can't tap/click them. My click goes through the annotation and hits the map instead (I've detected it). I've tried using requestFocus() on the view when I inflate it, but that has no effect. I also have android:clickable='true' in the xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="200dp"
android:layout_height="110dp"
android:layout_gravity="center_horizontal">
<Button
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Origin"
android:id="#+id/btn_origin"
android:layout_gravity="right"
android:focusable="true"
android:clickable="true"/>
<Button
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true"
android:text="Destination"
android:id="#+id/btn_destination" />
</LinearLayout>
How do I get the click event to hit the buttons instead of the underlying map?
Since the onClick event doesn’t happen, the solution in order to enable events on different views situated on map is incorporating them in different annotations using annotationViews and the execute actions on the onAnnotationSelected callback(so there should be one view per annotation).
In order to make an event trigger in a natural manner a corresponding offset must be set to the annotation so as the onAnnotationSelected callback to be triggered when the actual view is clicked, not the extension of the annotation.
#Override
public void onSurfaceCreated(SKMapViewHolder mapHolder) {
….
SKAnnotation annotation = new SKAnnotation(137);
SKAnnotationView annotationView = new SKAnnotationView();
View v = getLayoutInflater().inflate(R.layout.bug_2_btn_layout,null,false);
annotationView.setView(v);
annotation.setAnnotationView(annotationView);
annotation.setLocation(new SKCoordinate(52.520008,13.404954));
annotation.setMininumZoomLevel(1);
double viewToLayoutRatio = getResources().getDimension(R.dimen.originBtn_width)/getResources().getDimension(R.dimen.annotationLayout_width);
annotation.setOffset(new SKScreenPoint((float) (annotation.getOffset().getX()-(viewToLayoutRatio*getResources().getDimension(R.dimen.originBtn_width))), (float) (annotation.getOffset().getY()+(viewToLayoutRatio/3)*getResources().getDimension(R.dimen.originBtn_width))));
mapView.addAnnotation(annotation, SKAnimationSettings.ANIMATION_POP_OUT);
…
}
#Override
public void onAnnotationSelected(final SKAnnotation annotation) {
switch (annotation.getUniqueID()) {
…
case 137:
Toast.makeText(getApplicationContext(),"Annotation was clicked",Toast.LENGTH_SHORT);
View v = getLayoutInflater().inflate(R.layout.bug_2_btn_layout,null,false);
originClicked(v);
break;
}
}

How to center text on android IconGenerator

I'm developing an app using lots of markers placed on the map, and I'm using a custom ClusterRenderer to show them.
Problem is that I can't draw the cluster's size in the center of the custom marker icon, please see attached screenshot.
I've tried adding contentPadding to the IconGenerator, but still no luck, because of the changing number of digits shown. Could you please help me center the text on the generated icon?
Code:
IconGenerator clusterIconGenerator = new IconGenerator(context);
clusterIcon = context.getResources().getDrawable(R.drawable.map_cluster);
clusterIconGenerator.setBackground(clusterIcon);
#Override
protected void onBeforeClusterRendered(Cluster<MyType> cluster, MarkerOptions markerOptions) {
Bitmap clusterIcon = clusterIconGenerator.makeIcon(String.valueOf(cluster.getSize()));
markerOptions.icon(BitmapDescriptorFactory.fromBitmap(clusterIcon));
}
UPDATE
starting Apr 1, 2016 a prefix has been added to the Resources of the library
so the id="text" has been changed to "amu_text".
As stated in the library documentation :
setContentView public void setContentView(View contentView) Sets the child view for the icon. If the view contains a
TextView with the id "amu_text", operations such as
setTextAppearance(Context, int) and makeIcon(String) will operate
upon that TextView .
#Override
protected void onBeforeClusterRendered(Cluster<Dashboard_Marker> cluster, MarkerOptions markerOptions) {
IconGenerator TextMarkerGen = new IconGenerator(context);
Drawable marker;
int ClusterSize = cluster.getSize();
marker = context.getResources().getDrawable(R.drawable.cluster_red);
TextMarkerGen.setBackground(marker);
LayoutInflater myInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View activityView = myInflater.inflate(R.layout.cluster_view, null, false);
TextMarkerGen.setContentView(activityView);
TextMarkerGen.makeIcon(String.valueOf(cluster.getSize()));
BitmapDescriptor icon = BitmapDescriptorFactory.fromBitmap(TextMarkerGen.makeIcon());
markerOptions.icon(icon);
}
with the layout cluster_view as :
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:layout_centerInParent="true"
android:layout_centerVertical="true"
android:weightSum="1">
<TextView
android:layout_width="61dp"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Medium Text"
android:textColor="#000000"
android:id="#+id/amu_text"
android:layout_marginTop="13dp"
android:gravity="center" />
</LinearLayout>
note :: the layout must contain one text view with an id = "amu_text" in order for the icon generator to accept it , manipulate all the positioning you want in the layout .

Monodroid add map preview

I am trying to add google map v2 in a fragment in a preview style but I am not sure how to fit the map with the desired zoom inside the view. When I try to add the the map in a full fragment it works correctly. I am using a framelayout and loading the map like this
void InitMapFragment()
{
GoogleMapOptions mapOptions = new GoogleMapOptions()
.InvokeMapType(GoogleMap.MapTypeNormal)
.InvokeZoomControlsEnabled(true)
.InvokeCompassEnabled(true);
m_mapFragment = SupportMapFragment.NewInstance(mapOptions);
Activity.SupportFragmentManager.BeginTransaction().Replace(Resource.Id.mapLayout, m_mapFragment, "map").Commit();
}
Any ideas on how to add in a small prview format as in Sunrise app?
And here is the sample of how my layout file looks
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="#style/RegularMatchLayout"
android:orientation="vertical"
android:background="#e5e5e5">
<FrameLayout
android:id="#+id/mapLayout"
android:layout_width="300dp"
android:layout_height="300dp" />
</LinearLayout>
I have made similar thing like this:
For layout I used fragment and not frame layout but it's the same more or less.
<fragment
android:id="#+id/map"
class="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="208dp" />
Then I used this code to find the map and setup appropriate zoom level:
_map = ((SupportMapFragment)SupportFragmentManager.FindFragmentById(Resource.Id.map)).Map;
_map.UiSettings.ZoomControlsEnabled = false;
_map.UiSettings.ScrollGesturesEnabled = false;
_map.UiSettings.RotateGesturesEnabled = false;
_map.UiSettings.ZoomGesturesEnabled = false;
_map.UiSettings.TiltGesturesEnabled = false;
var location = new LatLng(_item.Latitude, _item.Longitude);
_map.MoveCamera(CameraUpdateFactory.NewLatLngZoom(location, 16));
var markerOptions = new MarkerOptions();
markerOptions.SetPosition(location);
markerOptions.InvokeIcon(BitmapDescriptorFactory.FromResource(Resource.Drawable.ic_map_marker));
_map.AddMarker(markerOptions);

Categories

Resources