How to add clear button in CustomDatePicker control (.NET MAUI)? - android

I have started learning .NET MAUI technology. And I have noticed that DatePicker control does not have support for null/empty value.
So, I have created custom control using bindable property. Here is my code:
CustomDatePickerControl.cs
using System;
using System.Globalization;
​
namespace TestApp.Controls
{
public class CustomDatePicker : DatePicker
{
public string _format = null;
public static readonly BindableProperty CustomDateProperty =
BindableProperty.Create(nameof(CustomDate), typeof(DateTime?),
typeof(CustomDatePicker), DateTime.Now,
BindingMode.TwoWay, propertyChanged: OnDateChanged);
​
public DateTime? CustomDate
{
get { return (DateTime?)GetValue(CustomDateProperty); }
set { SetValue(CustomDateProperty, value); }
}
​
static void OnDateChanged(BindableObject bindable, object oldValue, object newValue)
{
var control = (CustomDatePicker)bindable;
var dateFormate = CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern;
if (control.CustomDate.HasValue)
{
if (control._format != null)
{
control.Format = control._format;
}
else
{
control.Format = dateFormate;
}
control.Date = control.CustomDate.Value;
control.Opacity = 1;
}
else
{
control._format = dateFormate;
​
//Added character in quotes to escape it, otherwise it will not get display properly.
control.Format = string.Format("Selec't' 'Date'");
control.Opacity = 0.3;
}
}
​
protected override void OnPropertyChanged(string propertyName = null)
{
base.OnPropertyChanged(propertyName);
​
if (propertyName == "Date")
{
CustomDate = Date;
}
}
}
}
Use in MainPage.xaml page
<control:CustomDatePicker x:Name="datePicker" />
MainPage.xaml.cs
{
InitializeComponent();
datePicker.CustomDate = null;
}
It does work fine in both Android and iOS. Now, I want to add clear action button to my CustomDatePicker control so that if user want to clear selected date they can.
Does anyone know how I can achieve it in MAUI? I do not know much about Xamarin.Forms or MAUI as I'm new to it. If someone can help me on this it will be really helpful.
Expected Output:

Related

SwiftUI ObservableObject + #Published equivalent in flutter

I developed an iOS app in SwiftUI, and now need to port it to Android, and decided to try Flutter. After overcoming super verbose and/or ugly nested widgets, I got stuck on state management. In SwiftUI:
class MySharedObj : ObservableObject {
#Published var someVar = 0
}
Now I can simply drop "#ObservedObject var obj:MySharedObj" in ANY views, and whenever the someVar is changed anywhere, all views "observing" this object are updated automatically. Is there something equivalent in Flutter? Currently I manage a list of "listeners" manually as follows:
class ObservableObject {
List<State> _listeners = [];
ObservableObject subscribe(State state) { _listeners.add(state); return(this); }
ObservableObject unsubscribe(State state) { _listeners.remove(state); return(this); }
ObservableObject notify() { _listeners.forEach((l) => l.setState((){})); return(this); }
}
class MySharedObj : ObservableObject {
int _someVar = 0;
int get someVar => _someVar;
void set someVar(int v) { _someVar = v; notify(); }
}
class SomeView1State extends State<SomeView1> {
#override initState(){widget.obj.subscribe(this);super.initState();}
#override dispose(){widget.obj.unsubscribe(this);super.dispose();}
}
...
This sort of works, but it's ugly and again verbose (it seems to be Android's theme).
I think you want to look at the provider package. There's a great discussion of it here.

How do I get a reference to ActionBarDrawerToggle?

I have a Xamarin Forms application that I am porting from a FormsActivity to an AppCompatActivity. For functional requirements, the hamburger icon should always show, which I have done by using
NavigationPage.SetHasBackButton(nextPage, false);
But this does not work with AppCompat and the issue report has sat unaddressed for over a year, so I'm trying to get around the issue with a custom renderer. I can successfully create the icon and display it, but tapping on it does not display the correct behavior. I'm thinking what I need to do is set the DrawerIndicatorEnabled to true and call SyncState, but I need a reference to the ActionBarDrawerToggle to do that and I haven't figured out how to get it.
Edit: This is the bug report with screen shots:
https://github.com/xamarin/Xamarin.Forms/issues/2577
Here is the custom NavigationPageRenderer:
[assembly: ExportRenderer(typeof(CustomNavigationPage), typeof(CustomNavigationPageRenderer))]
namespace HeaderTest.Droid
{
public class CustomNavigationPageRenderer : NavigationPageRenderer // APPCOMP
{
public CustomNavigationPageRenderer(Context context) : base(context)
{
}
protected override Task<bool> OnPushAsync(Page view, bool animated)
{
var retVal = base.OnPushAsync(view, false);
var context = (Activity)Context;
var toolbar = context.FindViewById<AToolbar>(Resource.Id.toolbar);
if (toolbar != null)
{
var icon = new DrawerArrowDrawable(context)
{
SpinEnabled = false,
};
toolbar.NavigationIcon = icon;
}
return retVal;
}
}
}

Android Header? How to create enums visible in whole project?

I'm looking for a way to create a "header" or something like that to specify some variables like:
enum Misc
{
double EFFECT_DAMAGE = Math.pow(2,0);
double EFFECT_ABSORB = Math.pow(2,1);
double EFFECT_HEAL = Math.pow(2,2);
int SPELL_FIREBALL = 51673;
}
And in every .java file I want to be able to write:
double effect = 1;
if (effect == EFFECT)
{
...some code...
}
Is there a nice way to do this?
I'm creating a mini game for now and want to have all the files nice and tidy to manage my project in the future easier once it gets bigger.
Thx in advance.
public enum Misc
{
EFFECT_DAMAGE(0), // 2^0
EFFECT_ABSORB(1), // 2^1
FIREBALL(245151);
private double value;
private Misc(double d){
value = d;
}
public String toString(){
return String.valueOf(value);
}
}
Access like this:
System.out.println("Fireball damage:" + Misc.FIREBALL);
You cannot assign values this way to a enum in java.
Instead you should use a public class with public static final variables to make them constants.
public class Misc {
public static final double EFFECT_DAMAGE = Math.pow(2,0);
public static final double EFFECT_ABSORB = Math.pow(2,1);
public static final double EFFECT_HEAL = Math.pow(2,2);
public static final int SPELL_FIREBALL = 51673;
}
So you can use in your code like
if (effect == Misc.EFFECT_DAMAGE )
{
...some code...
}
If you want use only the field without the class name first you should import the class as static:
import static test.Misc.*;
....
if (effect == EFFECT_DAMAGE ) {

C# call other class variable but return null (Unity3D)

I'm using Unity Augmented Reality. Why does my application return a null value if I call a public value of an other class?
These are my classes:
using UnityEngine;
using System.Collections;
public class GUIControlScript : MonoBehaviour {
public GUISkin MenuSkin;
public Texture BoxBackground;
public DefaultTrackableEventHandler DTEH;
public string ttx;
void OnGUI(){
Screen.orientation = ScreenOrientation.Landscape;
GUI.skin = MenuSkin;
GUI.Box(new Rect(0, 0, Screen.width, 600), BoxBackground);
GUI.BeginGroup(new Rect(Screen.width / 2 - 150, Screen.height / 2 - 150, 300, 300));
try
{
GUI.Button(new Rect(0, 0, 500, 500), ttx);
}
catch(System.Exception e)
{
}
GUI.EndGroup();
}
void Update()
{
ttx = DTEH.TrackableText; //This is the problem!
}
This is the class where I'm calling the variable
using UnityEngine;
public class DefaultTrackableEventHandler : MonoBehaviour,
ITrackableEventHandler
{
#region PRIVATE_MEMBER_VARIABLES
private TrackableBehaviour mTrackableBehaviour;
public string TrackableText = "";
#endregion // PRIVATE_MEMBER_VARIABLES
#region UNTIY_MONOBEHAVIOUR_METHODS
void Start()
{
mTrackableBehaviour = GetComponent<TrackableBehaviour>();
if (mTrackableBehaviour)
{
mTrackableBehaviour.RegisterTrackableEventHandler(this);
}
OnTrackingLost();
}
#endregion // UNTIY_MONOBEHAVIOUR_METHODS
#region PUBLIC_METHODS
// Implementation of the ITrackableEventHandler function called when the
// tracking state changes.
public void OnTrackableStateChanged(
TrackableBehaviour.Status previousStatus,
TrackableBehaviour.Status newStatus)
{
if (newStatus == TrackableBehaviour.Status.DETECTED ||
newStatus == TrackableBehaviour.Status.TRACKED)
{
OnTrackingFound();
}
else
{
OnTrackingLost();
}
}
#endregion // PUBLIC_METHODS
#region PRIVATE_METHODS
private void OnTrackingFound()
{
Renderer[] rendererComponents = GetComponentsInChildren<Renderer>();
// Enable rendering:
foreach (Renderer component in rendererComponents) {
component.enabled = true;
}
if (mTrackableBehaviour.TrackableName.Equals("farmasi"))
{
TrackableText = "farmasi";
}
Debug.Log("Trackable " + mTrackableBehaviour.TrackableName + " found");
}
private void OnTrackingLost()
{
Renderer[] rendererComponents = GetComponentsInChildren<Renderer>();
// Disable rendering:
foreach (Renderer component in rendererComponents) {
component.enabled = false;
}
Debug.Log("Trackable " + mTrackableBehaviour.TrackableName + " lost");
}
#endregion // PRIVATE_METHODS
Using the discussion in the comments, we managed to narrow it down to see what is null exactly. You call public DefaultTrackableEventHandler DTEH;, but you never initiate it. Try adding another function in your GUIControlScript-class like this:
void Start()
{
DTEH = new DefaultTrackableEventHandler();
}
That way, you didn't only give DTEH a type, but you initialized it as well.
Since you have DefaultTrackableEventHandler extending MonoBehaviour, it needs to be attached to a GameObject in order for it to initialize. You can do this in one of two ways:
In the inspector viewing the GameObject that GUIControlScript is attached to: add the Script manually to the GameObject by clicking Add Component, choosing Scripts (or wherever your scripts are located), and clicking on DefaultTrackableEventHandler. In the code, you can then access the DefaultTrackableEventHandler script by calling GetComponent:
public class GUIControlScript : MonoBehaviour {
private DefaultTrackableEventHandler dteh;
void Start() {
dteh = GetComponent<DefaultTrackableEventHandler>();
}
}
In the GUIControlScript script, call AddComponent to programmatically add the DefaultTrackableEventHandler script to the GameObject:
public class GUIControlScript : MonoBehaviour {
private DefaultTrackableEventHandler dteh;
void Start() {
dteh = gameObject.AddComponent<DefaultTrackableEventHandler>();
}
}
You do not always have to manually add the Component to the GameObject itself. Typically if you don't have any public variables that you want to change directly in the Inspector, then you can just programmatically add the Component.

Android - Create an Array of Variable Object Types

How do I create an array of different types? If each class is an extension of the _object class, can I just make an _object array and add the extensions to it?
Example:
class _object {
int type = 1;
public _object() {
type = 2;
}
public doSomething() {
}
}
class tree extends _object {
public tree() {
}
}
class apple extends _object {
public apple() {
}
}
public tree aTree = new tree();
public apple anApple = new apple();
public _object[] objects = new _object[] { aTree, anApple };
The example in your question works. This is known as polymorphism.
http://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html
http://en.wikipedia.org/wiki/Polymorphism_in_object-oriented_programming
After setting up the above code in android as a project and debugging it, it in fact does work, so long as you only call methods of the base object.

Categories

Resources