What is an Alternative to the UIPickerView from IOS in android? - java

I am trying to reproduce the IOS UIPickerView functionality but in android.
In IOS you can set this UIPickerView as an input type of the keyboard. I need this same type of interaction but in android.
UPDATE:
When I say input type I mean the UIPickerView simply replaces the keyboard view. So if a textfield were clicked the UIPickerView would open instead of the Keyboard. Hope that clears stuff up!

not sure exactly what you mean by
as an inputtype of the keyboard
but the android equivalent to that image would be the TimePickerDialog
Update
If you want that picker type of UI you have 3 options for pickers, the TimePicker, DatePicker or the NumberPicker obviously the first 2 are out so you are left with the NumberPicker with the number picker you can populate it with the numbers you want (inches) and then another for feet
I suggest you take a quicl look at the Pickers article
https://developer.android.com/guide/topics/ui/controls/pickers.html

I would suggest making a layout with multiple pickers, that way you can have as many as you need and initialise them with any values you require.
The below layout will give you two spinners side by side similar to the iOS UIPickerView.
I've posted a link to my github repo at the bottom with a simple example showing how to use 3 spinners, one for minutes, hours and days that should help you (Or anyone else coming from iOS with the same question) can use as a base to get started.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent"
android:id="#+id/multispinner">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp"
android:paddingLeft="10dp"
android:paddingRight="10dp">
<Spinner
android:id="#+id/spinner1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginLeft="5dp"/>
<Spinner
android:id="#+id/spinner2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginLeft="5dp" />
</LinearLayout>
</LinearLayout>
My simple multiple picker example

You can use a number picker, if you're looking for a similar feel. Just make sure to add a personalized style as theme (or else it will take your app theme as default) and add a formatter to the number picker. You'll run into some trouble on the first render (it won't show the first value until you scroll), just use the solution provided here:
Android NumberPicker with Formatter doesn't format on first rendering
You can also put it into a cardview like in the image, it looks tidy enough.
formatted number picker screenshot
Ps.: Actually you can modify several fields, but you have to acces the class fields/methods. To do so, do as this exmaple code.
public void setNumberPickerDivider (NumberPicker picker) {
Field[] fields = NumberPicker.class.getDeclaredFields();
for(Field f:fields){
if(f.getName().equals("mSelectionDividerHeight")){
f.setAccessible(true);
try {
f.set(picker,1);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
break;
}
}
}

Related

Add Custom Control as Marker OSMDROID BONUS PACK

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.

Set Keyboard for Action in Android

I am new to Android development and need some pointers around the input. I am familiar with the use of Android and I would like to know how to complete general actions around the keyboard.
I know how to set it to things such as phone, email, decimal, and so on.
But how do you change it to move to the next field or fire an action?
Thank you for your insights.
You need to add this attribute in editext xml android:imeOptions="actionDone"
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:imeOptions="actionDone"
android:inputType="text"/>

Android Vertical Switch Widget

Using android, I'd like to get a vertical switch widget implementation in place. As far as I can tell, it looks like switches only have a horizontal orientation. I'd like to have something like the following:
After looking through the threads here and searching google, I have yet to find something that can give me this. Everything I search for gives me the horizontal implementation only.
so I can generate your typical horizontal switch
<Switch
android:id="#+id/switch_button"
android:layout_width="130dp"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/label"
android:layout_gravity="center"
android:switchMinWidth="130dp"
android:thumb="#drawable/switch_selector"
android:track="#drawable/track_selector" >
</Switch>
but there doesn't seem to be a good way to set the orientation. I know that the question is a bit high level. Is there some attribute that is immediately available that will allow me to have a vertical switch? Or will I have to create a custom switch and possibly modify the onDraw method so that it is flipped vertically? Any help is appreciated. Thanks.
Try android:rotation="90" like this:
<Switch
android:id="#+id/switch_button"
android:layout_width="130dp"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/label"
android:layout_gravity="center"
android:switchMinWidth="130dp"
android:thumb="#drawable/switch_selector"
android:track="#drawable/track_selector"
android:rotation="90">
</Switch>
There is no quick attribute for vertical orientation.. Sorry :)
First you can look at the code of the switch and see if you can copy and manipulate it.
Second you can just implement your on. Have a layout with a button inside it. use onTouchListener to slide it from side to side. No need to use "onDraw".
Try toggle button witch graphics and use pictures like this You included in Your post. Here is example of such toggle buttons: Toggle button using two image on different state

android:gravity="right" not working on all devices for Arabic and other RTL languages

I've got an Arabic Android application, and here is the XML code:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#drawable/greygradientbackground">
<ImageView android:id="#+id/logo"
android:layout_width="150dp"
android:layout_height="fill_parent"
android:scaleType="centerCrop"
android:layout_margin="5dp"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true" />
<TextView android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
android:textColor="#000000"
android:layout_gravity="center_vertical|right"
android:gravity="right"
android:layout_toLeftOf="#id/logo"/>
</RelativeLayout>
The problem is that android:gravity works on some Android models and on others don't.
To be more specific, I've tested the app on many 2.3.3 android devices and the Arabic text is aligned right. However on other 2.3.3 devices the Arabic text is aligned left (which is wrong).
When I changed android:gravity="right" to android:gravity="left" the problem shifted from the second group of devices to the first.
So my question is how can I solve this issue especially that as far as I know there aren't a way to localize layouts based on a device model number.
Thanks in advance for any guidance because am totally lost. :(
UPDATE:
I searched about "How to align Arabic correctly on all Android versions?" but found nothing working on all my testing devices. Any suggestions please? I am sure there is a best practice approach for aligning Arabic text on Android.
UPDATE 2:
I tried to use a WebView instead of a TextView to align Arabic correctly using CSS styles. However, the Arabic text is showing in the WebView as strange characters.
Here is the Code:
mWebView.loadData("<html dir=\"rtl\">الأسم<body></body></html>", "text/html", "UTF-8");
The strange thing is that Arabic websites text is displayed correctly. So, what's the problem? :(
This is an expected behaviour. You may not use gravity="right", but gravity="end" instead, the same idea you apply to gravity="left" which you may use gravity="start", as well as layout_marginStart instead of layout_marginLeft
This way, Android will put the text to the "start" orientation, depending on the location. (for us, americans, we start to write from the left and we end on the right, but arabians start from the right and end on the left).
You can get the layout/text directions with the method getLayoutDirectionFromLocale(null), this will return View.LAYOUT_DIRECTION_LTR (left-to-right) or View.LAYOUT_DIRECTION_RTL (right-to-left, like arabic).
More info you can check here
change your textveiw in the layout to this....
<TextView android:id="#+id/title"
change your layout_width to "fill_parent"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="16sp"
android:textColor="#000000"
android:layout_gravity="center_vertical|right"
android:gravity="right"
android:layout_toLeftOf="#id/logo"
/>
You can change the thing in another way also....You can make changes in the activity class..as follows...let your TextView with id title is mapped in the activity class with a TextView object named "tv" the you can make it right aligned by writing this.
tv.setGravity(Gravity.RIGHT);
but in both the cases the width layout width should be "fill_parent"..
If you do not do this and keep it "wrap_content" then there is no space for the text to move... all the alignments (center,left,right...)remain the same.....
If both of these donot work out... then I would prefer you to use table layout and keep the text view in it....
try putting your textview inside a separate LinearLayout ,and set that layouts properties likethis:
android:layout_gravity="center_vertical" and android:orientation="vertical"
android:gravity="right"
note: dont specify layout_gravity of the textview.
hope this helps! it worked fine for me.
also you can try the solution provided here: Android Arabic text aligment
Another solution to achieve such behavior:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layoutDirection="ltr"
android:layout_weight="1"
android:gravity="end"
android:padding="16dp"
android:text="#string/locale_switch_btn" />
</LinearLayout>
Note that, for correct gravity="end" alignment, in rtl locales you should set property:
android:layoutDirection="ltr"

How to create a Layout were I can place anything where I want?

I'm designing an app with many images, buttons and textViews strewn across the screen. At the moment I am using the relative layout as it seemed the most flexible of the lot. However were I place my elements and their size is still restricted to being aligned with other elements. Even worse if an element changes size any elements aligned to it will also change size.
There must be a simple solution to this! Apple's nib files perform this so easily with an effortless drag and drop to any location; yet android appears to be stuck with restrictive table/linear/relative/grid layouts.
If possible can the solution be performed via eclipse. If not please guide me to the relevant documentation to learn to create my own layouts via xml, create a huge grid layout or whatever horrors await me :)
Thanks
I think what you want is something like an absolute layout tho these were deprecated a while ago, Im pretty sure you can still do this via a Relative layout, you don't necessarily need to align the via with another view, I guess you could just do something like this:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="70dp"
android:layout_marginTop="82dp"
android:src="#drawable/ic_launcher" />
<ImageView
android:id="#+id/imageView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_marginBottom="172dp"
android:layout_marginRight="84dp"
android:src="#drawable/ic_launcher" />
</RelativeLayout>
all I'm doing here is aligning it with the side of the parent and having a margin between it
You can do what you ask with a Frame Layout and setting the position of each object. But do so at your own risk. The reason Apple nib files let you arbitrarily place objects is taht the aspect ratio of all their devices is the same. So your layouts just scale up and down evenly.
Android is a more diverse ecosystem, and you should try to embrace layouts that adapt to different screen sizes and orientations.
Take a look at Android custom layout and Android - How to draw a letter at a specific point?
Are you planning to only use the app on a single android device model? If yes, check AbsoluteLayout's Alternatives. (FrameLayout or RelativeLayout)
It's not a good idea to put "Anything Anywhere you want" since Android devices have a lot of different screen sizes and properties. The only option would be to define your own custom layout.
I actually really like the way Android tries to make your layout compatible with as much devices as it can using alignment and structured layout views.
The reason it's simple for Apple is that you're only targeting iPhone, which has a fixed screen properties accross all devices.
Hope it helps. Good luck.

Categories

Resources