How to Customise AutoCompleteTextView in Xamarin Forms - xamarin

I am trying to Customise the look of AutoCompleteTextView i need a rounded Entry
till now i have tried this
[assembly: ExportRenderer(typeof(AutoCompleteViewv3),
typeof(AutoCompleteViewRendererv3))]
namespace PredictiveList.Droid
{
public class AutoCompleteViewRendererv3 : ViewRenderer<AutoCompleteViewv3,
AutoCompleteTextView>
{
static string[] COUNTRIES = new string[] {
"Afghanistan", "Albania", "Algeria", "American Samoa", "Andorra",
"Angola", "Anguilla", "Antarctica", "Antigua and Barbuda", };
public AutoCompleteViewRendererv3(Android.Content.Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<AutoCompleteViewv3> e)
{
base.OnElementChanged(e);
if (e.OldElement != null || this.Element == null)
return;
// var textInputLayout = (TextInputLayout)LayoutInflater.From(Context).Inflate(Resource.Layout.TextInputLayout, null);
var autoComplete = new AutoCompleteTextView(Context);
autoComplete.SetBackgroundResource(Resource.Drawable.rounded_cornersrev);
//var autoCompleteTextView = (AutoCompleteTextView)LayoutInflater.From(Context).Inflate(Resource.Layout.TextInputLayout, null);
//var txtSearch = (AutoCompleteTextView)FindViewById(Resource.Id.autocomplete_country);
// TextView name = (TextView)Android.Views.View.FindViewById(Resource.Id.txt_searchhh);
AutoCompleteTextView textView = new AutoCompleteTextView(Context);
textView = FindViewById<AutoCompleteTextView>(Resource.Id.autocomplete_country);
var adapter = new ArrayAdapter<String>(Context, Resource.Layout.list_item, COUNTRIES);
autoComplete.Adapter = adapter;
SetNativeControl(autoComplete);
}
// Use the control here.
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (this.Element == null || this.Control == null)
return;
// variable this.Control is the AutoCompleteTextView, so you an manipulate it.
}
}
}
i am trying to implement this in Xamarin Forms if someone have some other idea please do suggest
also please help me how can i remove understroke of entry

Have a try this way:
AutoCompleteTextView textView = new AutoCompleteTextView(textView =FindViewById<AutoCompleteTextView>(Resource.Id.autocomplete_country);
textView.Background = null; // Set background be null

Related

Adding questions and answers to Pin Xamarin.forms

Is there any way to make a popup with a few questions + a few answers to choose from after pressing the added pin on the map?
How to do that? What I mean most is how to combine the popup with the pin (in xamarin.forms)
I apologize for my weak language
My pin code for adding pins:
private async void OnButton(object sender, EventArgs e)
{
Pin pin = new Pin
{
Label = "Nazwa",
Address = "adres",
Type = PinType.SavedPin,
Position = new Position(Convert.ToDouble(szerokosc.Text), Convert.ToDouble(dlugosc.Text))
};
positions.Add(new Position(Convert.ToDouble(szerokosc.Text), Convert.ToDouble(dlugosc.Text)));
Polyline polyline = new Polyline
{
StrokeColor = Color.Blue,
StrokeWidth = 6
};
foreach (Position pos in positions)
{
polyline.Geopath.Add(pos);
}
maps.Pins.Add(pin);
maps.MapElements.Add(polyline);
var json = JsonConvert.SerializeObject(new { X = pin.Position.Latitude, Y = pin.Position.Longitude });
var content = new StringContent(json, Encoding.UTF8, "application/json");
HttpClient client = new HttpClient();
var result = await client.PostAsync("URL", content);
if (result.StatusCode == HttpStatusCode.Created)
{
await DisplayAlert("Komunikat", "Dodanie puntku przebiegło pomyślnie", "Anuluj");
}
}
You could use CustomRenderer to define your Map,and create a custom info window base on your needs.For example,use a listview to display your questions and answers.
You could refer to custom map pin and custom info window
Update (i could only give you some snippets,you should fill your content and layout base on your needs):
[assembly: ExportRenderer(typeof(CustomMap), typeof(CustomMapRenderer))]
namespace CustomRenderer.Droid
{
public class CustomMapRenderer : MapRenderer, GoogleMap.IInfoWindowAdapter
{
List<CustomPin> customPins;
public CustomMapRenderer(Context context) : base(context)
{
}
protected override void OnElementChanged(Xamarin.Forms.Platform.Android.ElementChangedEventArgs<Map> e)
{
base.OnElementChanged(e);
if (e.OldElement != null)
{
NativeMap.InfoWindowClick -= OnInfoWindowClick;
}
if (e.NewElement != null)
{
var formsMap = (CustomMap)e.NewElement;
customPins = formsMap.CustomPins;
}
}
protected override void OnMapReady(GoogleMap map)
{
base.OnMapReady(map);
NativeMap.InfoWindowClick += OnInfoWindowClick;
NativeMap.SetInfoWindowAdapter(this);
}
protected override MarkerOptions CreateMarker(Pin pin)
{
var marker = new MarkerOptions();
marker.SetPosition(new LatLng(pin.Position.Latitude, pin.Position.Longitude));
marker.SetTitle(pin.Label);
marker.SetSnippet(pin.Address);
marker.SetIcon(BitmapDescriptorFactory.FromResource(Resource.Drawable.pin));
return marker;
}
void OnInfoWindowClick(object sender, GoogleMap.InfoWindowClickEventArgs e)
{
var customPin = GetCustomPin(e.Marker);
if (customPin == null)
{
throw new Exception("Custom pin not found");
}
if (!string.IsNullOrWhiteSpace(customPin.Url))
{
var url = Android.Net.Uri.Parse(customPin.Url);
var intent = new Intent(Intent.ActionView, url);
intent.AddFlags(ActivityFlags.NewTask);
Android.App.Application.Context.StartActivity(intent);
}
}
// you could custom your view with a listview here,fill the answers and question
public Android.Views.View GetInfoContents(Marker marker)
{
var inflater = Android.App.Application.Context.GetSystemService(Context.LayoutInflaterService) as Android.Views.LayoutInflater;
if (inflater != null)
{
Android.Views.View view;
var customPin = GetCustomPin(marker);
if (customPin == null)
{
throw new Exception("Custom pin not found");
}
//inflate your custom layout
if (customPin.Name.Equals("Xamarin"))
{
view = inflater.Inflate(Resource.Layout.XamarinMapInfoWindow, null);
}
else
{
view = inflater.Inflate(Resource.Layout.MapInfoWindow, null);
}
var infoTitle = view.FindViewById<TextView>(Resource.Id.InfoWindowTitle);
var infoSubtitle = view.FindViewById<TextView>(Resource.Id.InfoWindowSubtitle);
if (infoTitle != null)
{
infoTitle.Text = marker.Title;
}
if (infoSubtitle != null)
{
infoSubtitle.Text = marker.Snippet;
}
return view;
}
return null;
}
public Android.Views.View GetInfoWindow(Marker marker)
{
return null;
}
CustomPin GetCustomPin(Marker annotation)
{
var position = new Position(annotation.Position.Latitude, annotation.Position.Longitude);
foreach (var pin in customPins)
{
if (pin.Position == position)
{
return pin;
}
}
return null;
}
}
}

How to Use AutoCompleteTextView With Xamarin Forms

I am trying to Implement AutocompleteTextview in xamarin forms,
till now i have achieved the customisation and look which i need to for my Auto Complete Bar,
but the thing where i am stuck is filling of data to Dataadapter from Shared Library also i am not getting what text is selected inside the Entry bar, so could anyone help me how can i bind my list from pcl to native and also i need two way data to Text Property
here is the code which i had implemented till now
my common class
public class AutoCompleteViewv3 : View
{
public AutoCompleteViewv3()
{
}
}
My Android Implementation
[assembly: ExportRenderer(typeof(AutoSuggestBox),
typeof(AutoCompleteViewRendererv3))]
namespace PredictiveList.Droid
{
public class AutoCompleteViewRendererv3 :
ViewRenderer<AutoCompleteViewv3,
AutoCompleteTextView>
{
static string[] COUNTRIES = new string[] {
"Afghanistan", "Albania", "Algeria", "American Samoa", "Andorra",
"Angola", "Anguilla", "Antarctica", "Antigua and Barbuda", };
public AutoCompleteViewRendererv3(Android.Content.Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<AutoCompleteViewv3> e)
{
base.OnElementChanged(e);
if (e.OldElement != null || this.Element == null)
return;
AutoCompleteTextView textView = (AutoCompleteTextView)LayoutInflater.From(Context).Inflate(Resource.Layout.TextEditorLayouts, null);
var adapter = new ArrayAdapter<String>(Context,
Resource.Layout.list_item, COUNTRIES);
textView.Adapter = adapter;
SetNativeControl(textView);
}
// Use the control here.
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (this.Element == null || this.Control == null)
return;
// variable this.Control is the AutoCompleteTextView, so you an manipulate it.
}
}
}
For Ios i am still trying to implemented
please check Code here for Auto complete

Custom Renderer for Picker in Xamarin.Forms

I want to customize my picker. I created a custom renderer for my picker but I dont know how the customization settings. How can I change the font style and size of the item? and How can I remove the two lines?
public class CustomPickerRenderer : PickerRenderer
{
public CustomPickerRenderer(Context context) : base(context)
{
AutoPackage = false;
}
protected override void OnElementChanged(ElementChangedEventArgs<Picker> e)
{
base.OnElementChanged(e);
if (e.OldElement == null)
{
Control.Background = null;
var layoutParams = new MarginLayoutParams(Control.LayoutParameters);
layoutParams.SetMargins(0, 0, 0, 0);
Control.LayoutParameters = layoutParams;
Control.SetPadding(0, 0, 0, 0);
SetPadding(0, 0, 0, 0);
}
}
}
If you want to set the fontSize of the text , you first need to customize a subclass extends from NumberPicker and overwrite the method AddView.
public class TextColorNumberPicker: NumberPicker
{
public TextColorNumberPicker(Context context) : base(context)
{
}
public override void AddView(View child, int index, ViewGroup.LayoutParams #params)
{
base.AddView(child, index, #params);
UpdateView(child);
}
public void UpdateView(View view)
{
if ( view is EditText ) {
//set the font of text
((EditText)view).TextSize = 8;
}
}
}
If you want to remove the lines,you should rewrite the NumberPicker
in Android Custom Renderer
public class MyAndroidPicker:PickerRenderer
{
IElementController ElementController => Element as IElementController;
public MyAndroidPicker()
{
}
private AlertDialog _dialog;
protected override void OnElementChanged(ElementChangedEventArgs<Picker> e)
{
base.OnElementChanged(e);
if (e.NewElement == null || e.OldElement != null)
return;
Control.Click += Control_Click;
}
protected override void Dispose(bool disposing)
{
Control.Click -= Control_Click;
base.Dispose(disposing);
}
private void SetPickerDividerColor(TextColorNumberPicker picker)
{
Field[] fields = picker.Class.GetDeclaredFields();
foreach (Field pf in fields)
{
if(pf.Name.Equals("mSelectionDivider"))
{
pf.Accessible = true;
// set the color as transparent
pf.Set(picker, new ColorDrawable(this.Resources.GetColor(Android.Resource.Color.Transparent)));
}
}
}
private void Control_Click(object sender, EventArgs e)
{
Picker model = Element;
var picker = new TextColorNumberPicker(Context);
if (model.Items != null && model.Items.Any())
{
picker.MaxValue = model.Items.Count - 1;
picker.MinValue = 0;
picker.SetBackgroundColor(Android.Graphics.Color.Yellow);
picker.SetDisplayedValues(model.Items.ToArray());
//call the method after you setting DisplayedValues
SetPickerDividerColor(picker);
picker.WrapSelectorWheel = false;
picker.Value = model.SelectedIndex;
}
var layout = new LinearLayout(Context) { Orientation = Orientation.Vertical };
layout.AddView(picker);
ElementController.SetValueFromRenderer(VisualElement.IsFocusedProperty, true);
var builder = new AlertDialog.Builder(Context);
builder.SetView(layout);
builder.SetTitle(model.Title ?? "");
builder.SetNegativeButton("Cancel ", (s, a) =>
{
ElementController.SetValueFromRenderer(VisualElement.IsFocusedProperty, false);
// It is possible for the Content of the Page to be changed when Focus is changed.
// In this case, we'll lose our Control.
Control?.ClearFocus();
_dialog = null;
});
builder.SetPositiveButton("Ok ", (s, a) =>
{
ElementController.SetValueFromRenderer(Picker.SelectedIndexProperty, picker.Value);
// It is possible for the Content of the Page to be changed on SelectedIndexChanged.
// In this case, the Element & Control will no longer exist.
if (Element != null)
{
if (model.Items.Count > 0 && Element.SelectedIndex >= 0)
Control.Text = model.Items[Element.SelectedIndex];
ElementController.SetValueFromRenderer(VisualElement.IsFocusedProperty, false);
// It is also possible for the Content of the Page to be changed when Focus is changed.
// In this case, we'll lose our Control.
Control?.ClearFocus();
}
_dialog = null;
});
_dialog = builder.Create();
_dialog.DismissEvent += (ssender, args) =>
{
ElementController?.SetValueFromRenderer(VisualElement.IsFocusedProperty, false);
};
_dialog.Show();
}
}
I also used this CustomRenderer which was posted before only instead of overriding it you can change the properties like this.
private void Control_Click(object sender, EventArgs e)
{
Picker model = Element;
var picker = new MyNumberPicker(Context);
if (model.Items != null && model.Items.Any())
{
// set style here
picker.MaxValue = model.Items.Count - 1;
picker.MinValue = 0;
picker.SetBackgroundColor(Android.Graphics.Color.Transparent);
picker.SetDisplayedValues(model.Items.ToArray());
//call the method after you setting DisplayedValues
SetPickerDividerColor(picker);
picker.WrapSelectorWheel = false;
picker.Value = model.SelectedIndex;
// change Text Size and Divider
picker.TextSize = 30;
picker.SelectionDividerHeight = 1;
}

How to change Picker Border color in xamarin forms

My borderless custom renderer for picker
public class BorderlessPickerRenderer : PickerRenderer
{
public static void Init() { }
protected override void OnElementChanged(ElementChangedEventArgs<Picker> e)
{
base.OnElementChanged(e);
if (e.OldElement == null)
{
Control.Background = null;
}
}
}
It will change the picker list text color as white. please see the screenshot
If you check the source code of PickerRenderer, you will find that the Dialog is totally generated in the code behind.
So here to set a Transparent(border-less) background, we can re-write the Click event of this control, for example:
public class BorderlessPickerRenderer : Xamarin.Forms.Platform.Android.PickerRenderer
{
private IElementController ElementController => Element as IElementController;
private AlertDialog _dialog;
protected override void OnElementChanged(ElementChangedEventArgs<Picker> e)
{
base.OnElementChanged(e);
if (e.NewElement == null || e.OldElement != null)
return;
Control.Click += Control_Click;
}
protected override void Dispose(bool disposing)
{
Control.Click -= Control_Click;
base.Dispose(disposing);
}
private void Control_Click(object sender, EventArgs e)
{
Picker model = Element;
var picker = new NumberPicker(Context);
if (model.Items != null && model.Items.Any())
{
picker.MaxValue = model.Items.Count - 1;
picker.MinValue = 0;
picker.SetDisplayedValues(model.Items.ToArray());
picker.WrapSelectorWheel = false;
picker.DescendantFocusability = DescendantFocusability.BlockDescendants;
picker.Value = model.SelectedIndex;
}
var layout = new LinearLayout(Context) { Orientation = Orientation.Vertical };
layout.AddView(picker);
ElementController.SetValueFromRenderer(VisualElement.IsFocusedPropertyKey, true);
var builder = new AlertDialog.Builder(Context);
builder.SetView(layout);
builder.SetTitle(model.Title ?? "");
builder.SetNegativeButton(global::Android.Resource.String.Cancel, (s, a) =>
{
ElementController.SetValueFromRenderer(VisualElement.IsFocusedPropertyKey, false);
// It is possible for the Content of the Page to be changed when Focus is changed.
// In this case, we'll lose our Control.
Control?.ClearFocus();
_dialog = null;
});
builder.SetPositiveButton(global::Android.Resource.String.Ok, (s, a) =>
{
ElementController.SetValueFromRenderer(Picker.SelectedIndexProperty, picker.Value);
// It is possible for the Content of the Page to be changed on SelectedIndexChanged.
// In this case, the Element & Control will no longer exist.
if (Element != null)
{
if (model.Items.Count > 0 && Element.SelectedIndex >= 0)
Control.Text = model.Items[Element.SelectedIndex];
ElementController.SetValueFromRenderer(VisualElement.IsFocusedPropertyKey, false);
// It is also possible for the Content of the Page to be changed when Focus is changed.
// In this case, we'll lose our Control.
Control?.ClearFocus();
}
_dialog = null;
});
_dialog = builder.Create();
_dialog.DismissEvent += (ssender, args) =>
{
ElementController?.SetValueFromRenderer(VisualElement.IsFocusedPropertyKey, false);
};
_dialog.Show();
_dialog.Window.SetBackgroundDrawable(new ColorDrawable(Android.Graphics.Color.Transparent));
}
}
Rendering image of this custom picker:
The font color and button's style can be modified as you need since you created this dialog by yourself. And the style of the dialog also depends on the style of your app.

Why is my Event not firing in Xamarin UWP Map CustomRenderer?

I am trying to write a custom renderer for a Xamarin Map on UWP and a collection change event in the PCL is not triggering the appropriate event in the UWP custom renderer. It works just fine on iOS and Android.
With the following code the event ItemsCollectionChanged never gets called in the CustomMapRenderer even through the OnItemsSourcePropertyChanged is being called every 5 seconds.
public class CustomMap : Map
{
#region << Events >>
public event EventHandler ItemsCollectionChanged;
#endregion
private static void OnItemsSourcePropertyChanged(BindableObject bindable, object oldValue, object newValue)
{
var map = bindable as CustomMap;
if (map == null)
return;
map.ItemsSource.CollectionChanged += (s, e) =>
{
SetPin(bindable);
if (map.ItemsCollectionChanged != null)
{
map.ItemsCollectionChanged(bindable, new EventArgs());
}
};
}
}
[assembly: ExportRenderer(typeof(CustomMap), typeof(CustomMapRenderer))]
Namespace MyNamespace.Renderers
{
public class CustomMapRenderer : MapRenderer
{
MapControl _nativeMap;
protected override void OnElementChanged(ElementChangedEventArgs<Map> e)
{
base.OnElementChanged(e);
if (e.OldElement != null)
{
_nativeMap.MapElementClick -= OnMapElementClick;
_nativeMap.Children.Clear();
_nativeMap = null;
}
if (e.NewElement != null)
{
var formsMap = (CustomMap)e.NewElement;
formsMap.ItemsCollectionChanged += ItemsCollectionChanged;
_pinClickedCommand = formsMap.PinClickedCommand;
_routeCoordinates = formsMap.ItemsSource;
_nativeMap = Control as MapControl;
_nativeMap.Children.Clear();
_nativeMap.MapElementClick += OnMapElementClick;
var snPosition = new BasicGeoposition { Latitude = 45, Longitude = -88 };
Geopoint snPoint = new Geopoint(snPosition);
var mapIcon = new MapIcon();
if (mapIcon != null)
{
_nativeMap.MapElements.Remove(mapIcon);
}
mapIcon.CollisionBehaviorDesired = MapElementCollisionBehavior.RemainVisible;
mapIcon.Location = snPoint;
mapIcon.NormalizedAnchorPoint = new Windows.Foundation.Point(0.5, 1.0);
_nativeMap.MapElements.Add(mapIcon);
_nativeMap.Center = snPoint;
}
}
void ItemsCollectionChanged(object sender, EventArgs e)
{
;
}
}
}
I used a singleton to get the observable collection that I needed

Resources