Can I add Custom Control as Marker to OSMBONUSPACK?
I create some Buttons and image in Android xml file Named MyMarkerItem.xml
I would like something like MyMarker.setDesign(R.layout.MyMarkerItem);
Thanks
OK, I understand that you want the marker icon itself to be not a simple bitmap, but a layout.
What you can do is to use the marker infowindow "instead" of the marker icon.
First of all, create a new class CustomInfoWindow which inherits from MarkerInfoWindow - the default InfoWindow for Markers, and uses your own layout:
public class CustomInfoWindow extends MarkerInfoWindow {
public CustomInfoWindow(MapView mapView) {
super(my_own_layout, mapView);
}
}
CustomInfoWindow myCustomInfoWindow = new CustomInfoWindow(mapView);
Then, just after creating your Marker, do that:
Set a marker icon as a 1x1 pixel size bitmap, fully transparent: setIcon(mySmall_InvisibleIcon)
Set the marker infowindow to your own: setInfoWindow(myCustomInfoWindow)
Set the infowindow "anchor" to the most appropriate and natural position, depending on the "look" of your layout: setInfoWindowAnchor(ANCHOR_CENTER, ANCHOR_CENTER) maybe?
Force the opening of the infowindow: showInfoWindow()
All these steps are fairly simple.
But then, I guess you expect some behaviour to happen when the user will click on your layout buttons.
So, inside your CustomInfoWindow code, you will certainly have to do some work => follow this tutorial.
Markers in Osmdroid arent actually android views and therefore it's not possible to add other components into them. They are basically just an image.
Simple and suggested solution
You can add your components to a MarkerInfoWindow which is displayed after a click, though.
marker.setInfoWindow(new MarkerInfoWindow(R.layout.MyMarkerItem, mapView));
Possible "real" soluiton
If you really need such behaviour - meaning you really need multiple buttons displayed on a map as a "marker" and give the user the opportunity to click on them - it should be possible to create your own implementation of a Marker-like class. In other words, you would have to implement your own subclass of OverlayWithIW or Overlay and override (mainly) the draw method (which should draw your buttons to a canvas) and the onSingleTapConfirmed method, where you would need to detect properly on which button user clicked and call the related action. Try to go through source of the Marker class, it's a good example.
But keep in mind: this is an advanced task. Everything related to drawing on canvas can lead to performance issues if it's not done properly. There will be edge cases you'll have to cover. There may be other problems you'll need to solve and debug. I would not suggest such a solution to a beginner.
It's August 2021 and I wanted to add an arbitrary layout as my marker item. Much as the OP is asking for here.
I tried the Simple and suggested solution of https://stackoverflow.com/a/53003664/866333:
marker.setInfoWindow(new MarkerInfoWindow(R.layout.MyMarkerItem, mapView));
I get a runtime exception when I click it:
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference.
I refine my layout down to a single TextView widget for arguments sake and the error persists.
I give up on that answer and attempt the accepted one: https://stackoverflow.com/a/53216542/866333
public class CustomInfoWindow extends MarkerInfoWindow {
public CustomInfoWindow(MapView mapView) {
super(my_own_layout, mapView);
}
}
CustomInfoWindow myCustomInfoWindow = new CustomInfoWindow(mapView);
Using the same my_own_layout as before, let's call it R.layout.my_info_window
I get the same error:
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
I dug into the AS-reverse engineered (thanks AS) source code to discover the reason for this error is that the layout being passed to the MarkerInfoWindow super class constructor has particular id requirements.
We must have these ids in our layout: bubble_title, bubble_description, bubble_subdescription, bubble_image
Here is a minimal working example:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/bubble_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
tools:layout_editor_absoluteX="153dp"
tools:layout_editor_absoluteY="20dp" />
<TextView
android:id="#+id/bubble_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
tools:layout_editor_absoluteX="153dp"
tools:layout_editor_absoluteY="39dp" />
<TextView
android:id="#+id/bubble_subdescription"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
tools:layout_editor_absoluteX="153dp"
tools:layout_editor_absoluteY="58dp" />
<ImageView
android:id="#+id/bubble_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:srcCompat="#drawable/marker_cluster"
tools:layout_editor_absoluteX="145dp"
tools:layout_editor_absoluteY="76dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
That works great!
I can even attempt to customise by appending another widget:
<TextView
android:id="#+id/anothertexttestview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="look ma!"
tools:layout_editor_absoluteX="153dp"
tools:layout_editor_absoluteY="125dp" />
The absoluteY is ignored and superimposed on the only text I set programmatically, the title. IOW, the widget isn't purely declarative xml. I'm afraid ConstraintLayout is after my time as a front end engineer so I'll leave it to the reader to experiment from here.
Related
I want to write new UI class which contain Check box and Label. At the moment there is existing UI class with same elements but their element descriptions are different. But data model for both UIs are going to be same.
So is it good practice to keep separate UI classes (by duplicating GridBagConstraints and other stuffs) for each or move common code in to abstract layer and derive description of the UI elements in the implementation level?
There are some other things that you can try, so you can avoid duplicating UI code, I'll give you 2 examples:
You can use the tag to bring the UI code inside another layout file and show it in you current layout, at the end you will be able to call it directly from your current Activity or Fragment in the same way you do with the other elements at the root of your Fragment or Activity class.
Re-using layouts
First layout file named: include_example_layout.xml
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<TextView
android:id="#+id/textView_includeExampleLayout_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<CheckBox
android:id="#+id/checkBox_includeExampleLayout_valid"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</merge>
Second layout file named: activity_main.xml
<LinearLayout>
<include layout="#layout/toolbar_search_algolia"/>
</LinearLayout>
And from the MainActivity file you will be able to call the ids of this file include_example_layout as if they were declared directly in your activity_main file, so you will be able to reuse it.
The second one is creating a View element, this has an added advantage to the first method but is a little more complex, the thing is that you will be able to move some UI logic to the class of the new View element, for example if you want to disable the checkbox when something is happening with the information you can move thtat logic to the new view class.
Custom View
I'll no write a complete tutorial about this because it is a extense topic but I'll left some examples in other places that will help you understand the most basic concepts, there are two way in wich you can build CustomViews the first one is extending the View class that will force you to create it from scratch, but you can also extend other Views like a LinearLayout and this will help you to get started with the concept of a CustomView (is not recommended in every case, it can slow down your UI if you don't use it wisely)
Example extending LinearLayout
Example extending View
My first question was to click through layout. I solved it out.
Now my question is how to set button's position at desired location?
My application's minimum api level is 8 (I can't set getX() or getLeft())
Test XML code:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" >
<Button android:id="#+id/buttonx" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="X" />
</LinearLayout>
Acitivty code:
import android.app.*;
import android.os.*;
import android.view.*;
import android.widget.*;
public class Test extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED); getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD); getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL); requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.test);
Button xclose = (Button) findViewById(R.id.buttonx);
xclose.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
finish();
}
});
}
}
any way to change button's position dynamically or programatically?
If you need to align the views in Linear Layout Please read about gravity and layout_gravity properties.
You have another layout like Relative layout. It will give you more properties for view alignment.ex:layout_alignLeft,layout_alignParentLeft etc...
Study about it and use it however you want....Thanks...
You can always use NineOldAndroids by Jake Wharton to use setX() and setY() (and many other properties).
This library ports back the Honeycomb-Animation Framework to api level 1!
If that doesn't work, you could create your own ViewGroup and measure/layout the children yourself. More information here.
EDIT: Also, View.getLeft()/getTop()/... is available since api level 1. See here
Hope this helps!
You can use padding or margin in code for example
xclose.setPadding(left, top, right, bottom);
At the time of onclick u try this
I don't know where do you want to locate your button, but you should look into FrameLayout (which will let you put the button anywhere in your layout).
Using Android, you usually have three layout options as detailed in the Layouts | Android Developers notes. The Linear Layout gives you the option to declare elements and chain them either horizontally or vertically. The Relative Layout, which is what I believe you need, allows you to freely define the position of an element relative to another element, and the Web View is usually used to show web related content.
As I said, I believe the Relative Layout is what you are looking for. Have a look at this example which neatly outlines how to use the different alignment options to place elements. You will not there are two major categories. The first lets you align your element with a parent element which is handy if you want to move elements left, right, top, bottom, or centre. The second lets you define the alignment in regard to elements on the same level by specifying that your element be, for example, android:layout_toLeftOf or android:layout_below. You can combine all of these to get the desired result.
I am well aware that there are many options to achieve the result but I found this to be quite simple and usually sufficient to achieve visually attractive layouts.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/blur2"
android:orientation="horizontal"
tools:context=".MainActivity" >
<Button android:id="#+id/buttonx" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="X" />
</RelativeLayout>
Make sure it's relative, not Linearlayout, because on relative it would allow you to move buttons easily.
I want to have a "comments" button on my Android e-reader app that displays the number of comments currently posted inside the icon... so basically I want a comment bubble with a number inside it.
I could have multiple drawables, each being the bubble with a different number inside of it, and use a switch statement to choose which one to load each time based on the int number_of_comments field of the element being displayed. This approach seems a little wasteful though, and in any case I have a feeling there's a more elegant way to do it.
Any ideas?
You can do better. You can have a textview on top of the image view and keep updating its value everytime a new comment is added. You can define the overlap in xml like below and adjust your code logic accordingly to increase the comment count. For now I have just set up a dummy text Hello to show on top of the ImageView. You can add your comment count using the TextView's setText method.
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/relativelayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<ImageView
android:id="#+id/myImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/myImageSouce" />
<TextView
android:id="#+id/myImageViewText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/myImageView"
android:layout_alignTop="#+id/myImageView"
android:layout_alignRight="#+id/myImageView"
android:layout_alignBottom="#+id/myImageView"
android:layout_margin="1dp"
android:gravity="center"
android:text="Hello"
android:textColor="#000000" />
</RelativeLayout>
Hope this helps...
check out this 3rd party created widget
Android ViewBadger
You can use it to create the little number bubbles that you are looking for I think. This gives you the benefit of not having modify your layouts so much to achieve what you are trying to get.
Here is the sample code to apply a "badge"
View target = findViewById(R.id.target_view);
BadgeView badge = new BadgeView(this, target);
badge.setText("1");
badge.show();
I have an issue with a virtual keyboard.
This Soft Keyboard Covers Data Fields - and can't See what's going on.
I want to use this soft keypad and at the same time it should not become a problem to use data fields.
So how can I manage the data fields in such cases?
Encase the layout that you already have set up within a ScrollView. This will allow the content to scroll when the software keyboard shows. Keep in mind a ScrollView has to be formatted as such.
<Scrollview android:layout_width="fill_parent"
android:layout_height="wrap_content">
<LinearLayout android:layout_width="fill_parent"
android:layout_height="wrap_content">
<!-- Your content -->
</LinearLayout>
</ScrollView>
You may also consider setting the following attribute on your Activity in the Android Manifest to further specify the behavior.
From here (http://developer.android.com/guide/topics/manifest/activity-element.html):
android:windowSoftInputMode=["stateUnspecified",
"stateUnchanged", "stateHidden",
"stateAlwaysHidden", "stateVisible",
"stateAlwaysVisible", "adjustUnspecified",
"adjustResize", "adjustPan"]
I find that adjustResize works better for applications contained in ScrollViews in my particular case.
I want to customize my ExpandableList. My issue is that I need a button and expandable list on single activity. Can I achieve that? I have seen all the examples but all extends ExpandableListActivity not the Activity in which I can put all the widgets in one activity.
Any help would be appreciated.
According to the documentation this task should not be too hard.
the first thing that you will have to do is create a new xml file to hold your custom layout. The file should be saved in your res/layout folder and be named something like "my_custom_expandable_list_view_layout.xml", it should look something like this:
<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ExpandableListView android:id="#id/android:list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"/>
<Button android:id="#id/my_button_id"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Click Me"/>
</LinearLayout>
The import part of that layout file is that you include an "ExpandableListView" and give it the id of "android"list".
The next thing that you will need to do is let your activity know that you are using a custom layout by calling setContentView() in your activities onCreate(). The call should look something like this
setContentView(R.layout.my_custom_expandable_list_view_layout);
At this point you should be able to run you program and see a large button at the bottom of the screen. In order to do something with this button you will need to access it via a call to findViewById() in your Activity like this
Button myButton = (Button)findViewById(R.id.my_button_id);
Once you have that myButton object you can add a click listener or whatever else you would like to do. You can pretty much add anything else you want by just adding new things to the layout file.