I am currently trying to build a yelp-like app as a personal project, and I plan to use the Google Maps API + Map Utils to help me, but I have two quick questions.
The first is why can't I change the background color of my custom marker? Every time I try, the background is still the default white.
Here is my code:
IconGenerator tc = new IconGenerator(this);
Bitmap bmp = tc.makeIcon("1");
tc.setColor(IconGenerator.STYLE_RED);
Marker marker = map.addMarker(new MarkerOptions()
.position(new LatLng(38.681512, -90.248927))
.title("San Francisco")
.icon(BitmapDescriptorFactory.fromBitmap(bmp)));
My next question is how can I not hard code the text inside the markers? What I'm trying to say is how can I program my app so that I don't have to hard code every marker because I don't want to have 100 different entries that all simply do the same thing, but just have different icon titles (i.e. numbers on the markers, like Yelp does in their app) and different slightly descriptions (also see Yelp).
The first is why can't I change the background color of my custom marker? Every time I try, the background is still the default white.
I see nothing in your code that sets the background. Hence, I would expect that your background will not change. A quick glance at the IconGenerator JavaDocs turns up a setBackground() method that may do what you need.
My next question is how can I not hard code the text inside the markers?
Well, the text has to come from somewhere. It is presumably the same "somewhere" that the locations are coming from. That could be a database, or a file, or the results of a Web service call, or whatever.
So, for example, if you are getting the data from a Web service, you would iterate over the Web service response (e.g., array of objects parsed from JSON) and call addMarker() for each. Do bear in mind, though, that addMarker() needs to be called on the main application thread, and doing 100 of those at one time may freeze your UI.
Regarding customization of info windows. You can look at the documentation here.
I went ahead and got a simple example working for this.
Code to set up the InfoWindowAdapter:
map.setInfoWindowAdapter(new GoogleMap.InfoWindowAdapter() {
#Override
public View getInfoWindow(Marker arg0) {
return null;
}
#Override
public View getInfoContents(Marker arg0) {
View v = getLayoutInflater().inflate(R.layout.customlayout, null);
TextView tLocation = (TextView) v.findViewById(R.id.location);
TextView tSnippet = (TextView) v.findViewById(R.id.population);
tLocation.setText(arg0.getTitle());
tSnippet.setText(arg0.getSnippet());
return v;
}
});
customlayout.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="20dp"
android:orientation="vertical"
android:background="#000000">
<TextView
android:id="#+id/location"
android:textColor="#D3649F"
android:textStyle="bold"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/population"
android:textColor="#D3649F"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
Result:
Related
Hi Am working on google maps. i have added location in a fragment now am trying to add StreetViewPanoramaView to the fragment . But am getting Oops! something went wrong error message as shown in 2nd image
this is my code
maps_activity.xml
<Button
android:id="#+id/button_streetview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Open StreetView"
/>
<androidx.fragment.app.FragmentContainerView
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="wrap_content"
tools:context=".MapsActivity" />
<com.google.android.gms.maps.StreetViewPanoramaView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/streetview"/>
This is my MapActivity.kt
button_streetview.setOnClickListener(View.OnClickListener {
var mStreetViewPanoramaView : StreetViewPanoramaView = findViewById(R.id.streetview)
mStreetViewPanoramaView.onCreate(savedInstanceState)
var streetViewPanorama: StreetViewPanoramaOptions = StreetViewPanoramaOptions()
streetViewPanorama.panningGesturesEnabled(false)
streetViewPanorama.position(address)
streetViewPanorama.userNavigationEnabled(false)
streetViewPanorama.zoomGesturesEnabled(true)
var streetViewPanoramaCamera : StreetViewPanoramaCamera = StreetViewPanoramaCamera(25F,30F,1F)
streetViewPanorama.panoramaCamera(streetViewPanoramaCamera)
mStreetViewPanoramaView = StreetViewPanoramaView(this,streetViewPanorama)
mStreetViewPanoramaView.getStreetViewPanoramaAsync(this)
})
i can successfully retrive latitude and longitude of a place by address and display it in infoWindow and add custom marker as shown in image.
But when i click openstreetview button error message is coming.
This is the StreetView
This is the logcat
As This Error message is showing Wrong API key but i have added correct Key as i can retrive and display a marker successfully. Can anyone please tell me where am doing wrong
It looks like you are getting the error described here:
If you receive an error such as Your card does not support automatic
recurring payments or General decline of the card, please select a
different form of payment.
You might encounter these errors if you are using a debit card that
requires two-factor authentication to complete an online transaction.
Two-factor authentication requires you to be in-session at the time of
the transaction. Cards that require you to be in-session are not
usable for subscriptions or similar recurring automatic transactions.
Your street view map should work without problem once you enable billing on your project. Hope this helps!
This is probably a basic procedure, and in fact I've been extensively searching for a suitable answer, but I haven't found anything usable or that actually works. Now, the case:
A Dialog window is placed inside a method:
public void method_with_Dialog_code() {
Dialog simpleDialog = new Dialog(this, R.style.FilterDialogTheme);
simpleDialog.setContentView(R.layout.dialog_xml_layout);
simpleDialog.setCancelable(true);
TextView insideTextView = (TextView) simpleDialog.findViewById( R.id.insidetextview );
insideTextView.setText("This text should change when the WiFi is offline");
simpleDialog.show();
}
The respective dialog_xml_layout.xml file is simply:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="#+id/insidetextview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" />
</LinearLayout>
If the device is for example disconnected from the Internet, it generates a message that should be shown in the insideTextView. But notice that simpleDialog and insideTextView are inside the method, so they are local objects, so the first issue is how to execute:
insideTextView.setText("This device is now offline");
from another part of the code, that is, outside of the method?
If I decide to make simpleDialog and insideTextView as Global variables, I can with no problem, from another part of the program, set the line:
insideTextView.setText("This device is now offline");
But the instruction doesn't work. The TextView is never updated with the new message.
So, any ideas? Maybe with TextView.addTextChangedListener, so insideTextView could be updated when the TextView.setText is executed externally?
Gracias.
make insideTextView a member variable of the class and use it later.
I am developing an Android offline mapping application using osmdroid and osm bonus pack and loading the tiles and data from external storage. Right now, as the data grows, markers are starting to get cramped together, I even have the situation of two places on the same building. I know this kind of issue has been asked a lot before, mine is about a simple temporal workaround I'm thinking of implementing. How about if two places are near enough(right in top of each other!) the standard info window pops up as a ListView with each row designed like the standard bubble(image, title, moreInfoButton).
My question is: some thoughts or advices on how to create the new bonuspack_bubble.xml layout file.
I don't know if this will help you.
I needed to create a CustomInfoBubble for my project. What I did was, to extend the InfoWindow default class, and pass to it my custom bubble layout. Something like this:
http://mobiledevstories.wordpress.com/2014/03/01/osmdroid-bonus-pack-markers-with-clickable-infowindows/
My Java class MapCustomInfoBubble looks like this:
public class MapCustomInfoBubble extends InfoWindow {
public MapCustomInfoBubble(MapView mapView) {
super(R.layout.map_infobubble_black, mapView);//my custom layout and my mapView
}
#Override
public void onClose() {
//by default, do nothing
}
#Override
public void onOpen(Object item) {
Marker marker = (Marker)item; //the marker on which you click to open the bubble
String title = marker.getTitle();
if (title == null)
title = "";
Button moreInfo = (Button)mView.findViewById(R.id.bubble_moreinfo);//the button that I have in my XML;
moreInfo.setText(title);
moreInfo.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
gotoMoreInfoWindow();//custom method; starts another activity
}
});
}
}
In my XML file, I have:
<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="#drawable/map_infobubble_black" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView android:id="#+id/bubble_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:maxEms="17"
android:layout_gravity="left"
android:layout_weight="1"
android:text="Title" />
<Button android:id="#+id/bubble_moreinfo"
android:background="#drawable/map_btn_moreinfo"
android:visibility="visible"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:layout_weight="0" />
</LinearLayout>
</LinearLayout>
Somewhere else in my code, I then use:
Marker wp = new Marker(mapView);
wp.setPosition(new GeoPoint(mylocation.getMyLocation()));
wp.setTitle(editTextName.getText().toString());
wp.setInfoWindow(new MapCustomInfoBubble(mapView));
mapView.getOverlays().add(wp);
mapView.invalidate();
In my code, I set the text on the button with the Marker's title.
The Marker is the item on which I click. If you want to put info about more markers in the same InfoWindow (inside a ListView), I think you would need to know in advance what the info will be.
I believe that, You can put whatever code you want inside onOpen(), however, I am not so sure if it's a good practice. You could try creating a custom Constructor and put your logic there. It should work.
You need to pass the Resource Id (layout) and mapView to the super constructor, so it returns a valid mView object.
I have read a number of tutorials on this topic but not able to make it working. Can anyone please help me with the following
a) A home screen widget which has a button, Imageview and a TextView
b) The textview updates periodically via a service
c) On Click of the button the Image Changes.
Can anyone please help with a sample code or point to codes which do this functionality
check out this book, it explains very clear how to make a widget "silent mode toggle"
http://iit.qau.edu.pk/books/Android.Application.Development.for.For.Dummies.pdf
a) In your xml, the following will be the code.
<Button
android:id="#+id/b"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/go" />
<ImageView
android:id="#+id/iv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/image" />
<TextView
android:id="#+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#string/welcome" />
Of course, you need to arrange them according to your fancy.
b) Updating the text view is no big deal. Getting the text from the source is what is important. If it is from a web page, you could refer to usage of JSON. If it is from a database, then try SQLite. It all depends on your necessity.
Lets assume that you get your text. Your code for updation will be:
TextView t =(TextView) findViewById(R.id.tv);
t.setText(your_string);
To do it periodically you can use a parallel threading concept such as a runnable.
c) Set up an on Click Listener for this purpose.
Button b1;
b1 = (Button) findViewById(R.id.b);
b1.setOnClickListener(button_func);
This comes in your onCreate method.
View.OnClickListener button_func = new View.OnClickListener() {
#Override
public void onClick(View arg0) {
image = (ImageView) findViewById(R.id.iv);
iv.setImageResource(R.id.new_image);
}
};
Hope that you find this useful
What I would like to accomplish is to, at runtime, place a button in the middle of the screen, as the very top layer, overlaying anything below it. (It's not big, so it will not completely cover the screen, just whatever happens to be below it.)
I looked at creating a custom dialog, however that blocks all other user input. I want all of the views below this new button to act normally and respond to the user, but I just want to add (and later remove) the button above everything.
Hopefully that makes sense. I'm just wondering what might be the best approach to look into?
Use a FrameLayout, with the button as it's 2nd child. Set it to GONE when you don't want it visible.
I had to overlay a simple layout programmatically on top of any visible activity. Normal activity layout xmls don't know anything about the overlay. Layout had one textview component but could have any structure you see fit. This is my overlay layout.
res/layout/identity.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/identitylayout"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_centerInParent="true" >
<TextView
android:id="#+id/identityview"
android:padding="5dp"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:textColor="#FFFFFF" android:background="#FF6600"
android:textSize="30dp"
/>
</RelativeLayout>
Overlay is shown on top of the existing content, after timeout is deleted from the screen. Application calls this function to display overlay.
private void showIdentity(String tag, long duration) {
// default text with ${xx} placeholder variables
String desc = getString(R.string.identity);
desc = desc.replace("${id}", reqId!=null ? reqId : "RequestId not found" );
desc = desc.replace("${tag}", tag!=null ? tag : "" );
desc = desc.trim();
// get parent and overlay layouts, use inflator to parse
// layout.xml to view component. Reuse existing instance if one is found.
ViewGroup parent = (ViewGroup)findViewById(R.id.mainlayout);
View identity = findViewById(R.id.identitylayout);
if (identity==null) {
LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
identity = inflater.inflate(R.layout.identity, parent, false);
parent.addView(identity);
}
TextView text = (TextView)identity.findViewById(R.id.identityview);
text.setText(desc);
identity.bringToFront();
// use timer to hide after timeout, make sure there's only
// one instance in a message queue.
Runnable identityTask = new Runnable(){
#Override public void run() {
View identity = findViewById(R.id.identitylayout);
if (identity!=null)
((ViewGroup)identity.getParent()).removeView(identity);
}
};
messageHandler.removeCallbacksAndMessages("identitytask");
messageHandler.postAtTime(identityTask, "identitytask", SystemClock.uptimeMillis()+duration);
}
Timer messageHandler is member of main Activity instance (private Handler messageHandler) where I put all scheduled tasks. I am using Android 4.1 device lower than that I don't know what happens.