Change Switch Color in Xamarin.Forms? - xamarin.android

I want to change the color of switch in android and created custom renderer just like as one of the post from stack overflow:
Below is the code
public class CustomSwitchRenderer : SwitchRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Switch> e)
{
base.OnElementChanged(e);
if (Control != null)
{
Control.TextOn = "Yes";
Control.TextOff = "No";
Android.Graphics.Color colorOn = Android.Graphics.Color.Rgb(239, 201, 6);
Android.Graphics.Color colorOff = Android.Graphics.Color.LightGray;
Android.Graphics.Color colorDisabled = Android.Graphics.Color.Gray;
Android.Graphics.Color textColor = Android.Graphics.Color.Black;
Control.SetTextColor (ColorStateList.ValueOf (textColor));
Control.SetTextColor (textColor);
StateListDrawable drawable = new StateListDrawable();
drawable.AddState(new int[] { Android.Resource.Attribute.StateChecked }, new ColorDrawable(colorOn));
drawable.AddState(new int[] { -Android.Resource.Attribute.StateEnabled }, new ColorDrawable(colorDisabled));
drawable.AddState(new int[] { }, new ColorDrawable(colorOff));
Control.ThumbDrawable = drawable;
}
}
}
This code isn't working for me ? Do i need to add some items in drawable folder as well ?

With Forms 2.1, there are now effects which can remove the need for a custom renderer in situations where only minor visual changes are being made. See the linked guide for getting started on using them.

You can create your own control in your UI project:
public class MySwitch : Switch
{
}
After that change your forms where you used Switch control to MySwitch control.
And then you need to tell Xamarin.Forms infrastructure that you are providing renderer for MySwitch control.
In your *.Droid project add following attribute at assembly level (above your namespace declaration or in AssemblyInfo.cs file)
[assembly: ExportRenderer(typeof(MySwitch), typeof(CustomSwitchRenderer))]

For Android you can change the propery "colorAccent" on your "styles.xml" file
<item name="colorAccent">#008000</item>

Related

MvvmCross Android Dialog bind programmatically

I want to use the Android.Dialog (Cross.UI) in my MvvmCross project. My first approach was to use AutoViews. As this feature is still fairly young, the alternative was to implement the dialog in touch and Droid platforms.
For now i'm just doing this for Droid and I need to programmatically bind the properties of the ViewModel to the elements of the Dialog.
My View and ViewModel code is the following:
View
public class DialogConfigurationView : MvxBindingDialogActivityView<DialogConfigurationViewModel>
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
DroidResources.Initialise(typeof(Resource.Layout));
Root = new RootElement()
{
new Section("Private Configuration")
{
new EntryElement("Name:"),
new EntryElement("Description:"),
new BooleanElement("Active?")
}
};
}
}
ViewModel
public class DialogConfigurationViewModel : MvxViewModel
{
public ConfigurationSet Configuration
{
get { return _configuration; }
set
{
if (_configuration != value)
{
_configuration = value;
RaisePropertyChanged(() => Configuration);
}
}
}
private ConfigurationSet _configuration;
}
My goal is to have a twoway bind the EntryElement("Name:") with the property ViewModel.Configuration.Name.
Can anyone help me with this? Can this be done?
I don't know if there are any monodroid.dialog mvvmcross samples floating around which don't use autoviews!
However.... the basic syntac for binding should be the same as MonoTouch.Dialog - e.g. something like:
new Section("Contact Info")
{
new StringElement("ID", ViewModel.Customer.ID ?? string.Empty),
new EntryElement("Name", "Name").Bind(this, "{'Value':{'Path':'Customer.Name'}}"),
new EntryElement("Website", "Website").Bind(this, "{'Value':{'Path':'Customer.Website'}}"),
new EntryElement("Primary Phone", "Phone").Bind(this, "{'Value':{'Path':'Customer.PrimaryPhone'}}"),
},
new Section("Primary Address")
{
new EntryElement("Address").Bind(this, "{'Value':{'Path':'Customer.PrimaryAddress.Street1'}}"),
new EntryElement("Address2").Bind(this, "{'Value':{'Path':'Customer.PrimaryAddress.Street2'}}"),
new EntryElement("City").Bind(this, "{'Value':{'Path':'Customer.PrimaryAddress.City'}}"),
new EntryElement("State").Bind(this, "{'Value':{'Path':'Customer.PrimaryAddress.State'}}"),
new EntryElement("Zip").Bind(this, "{'Value':{'Path':'Customer.PrimaryAddress.Zip'}}"),
},
from https://github.com/slodge/MvvmCross/blob/vnext/Sample%20-%20CustomerManagement/CustomerManagement/CustomerManagement.Touch/Views/BaseCustomerEditView.cs
Note that in MvvmCross bindings for MonoTouch and MonoDroid, the default binding for things like text edit boxes is generally TwoWay by default.
If you do get a sample running, then please feel free to post it to a gist or to a repo - or to blog about it - looks like we could do with some samples to work from!

How to create view's actions listener for MvxItemTemplate

I have a view which contains an MvxListView and a form. I can hide the softkeyboard using the following code in my view's code (as this is pure view concerns)
var editText = FindViewById<EditText>(Resource.Id.newCheckbookName);
editText.EditorAction += (object sender, TextView.EditorActionEventArgs e) =>
{
if (e.ActionId == ImeAction.Done)
{
InputMethodManager inputMgr = GetSystemService(InputMethodService) as InputMethodManager;
inputMgr.HideSoftInputFromWindow(CurrentFocus.WindowToken, 0);
}
return;
};
In my item template I have an other text editor and would like to have the same behavior. But where can I add my code as I don't have any view code for the MwxItemTemplate ?
I think the easy way to do this is to use a custom 'View' within the listitem.
Note: that 'View' here refers to Android Views - not Model-View-ViewModel views - sorry for the naming confusion!
Creating custom views is easy to do...
Just create a custom View - e.g.
namespace Angevelle.App1.UI.Droid.Controls
{
public class MyText : EditText
{
public MyText(Context context, IAttributeSet attrs)
: base(context, attrs)
{
this.EditorAction += OnEditorAction;
}
private void OnEditorAction(object sender, EditorActionEventArgs editorActionEventArgs)
{
if (editorActionEventArgs.ActionId == ImeAction.Done)
{
// this code not tested - but something like this should work
var imm = (InputMethodManager)Context.GetSystemService(Context.InputMethodService);
imm.HideSoftInputFromWindow(WindowToken, 0);
}
}
}
}
Then you can use that View in your AXML just as you do Android or Mvx views:
<angevelle.app1.ui.droid.controls.MyText
android:layout_height=....
/>
If you are finding angevelle.app1.ui.droid.controls too verbose, then you could shorten this using an abbreviation in setup.cs:
protected override IDictionary<string, string> ViewNamespaceAbbreviations
{
get
{
var abbreviations = base.ViewNamespaceAbbreviations;
abbreviations["Abv"] = "angevelle.app1.ui.droid.controls";
return abbreviations;
}
}
then you can just use:
<Abv.MyText
android:layout_height=....
/>
An alternative approach might be to somehow customise the list...
If you ever do need to completely customise a listview and its adapter, then this can be easily done using the same type of technique - inherit from MvxBindableListView in your UI project:
public class MyListView : MvxBindableListView
{
public MyListView(Context context, IAttributeSet attrs);
: base(context, attrs, new MyListAdapter(context))
{
}
}
where MyListAdapter overrides the view creation:
public class MyListAdapter : MvxBindableListAdapter
{
public MyListAdapter(Context context)
: base(context)
{
}
// put your custom Adapter code here... e.g.:
protected override MvxBindableListItemView CreateBindableView(object source, int templateId)
{
return new MySpecialListItemView(_context, _bindingActivity, templateId, source);
}
}
where MySpecialListItemView inherits from MvxBindableListItemView but adds your own custom features.
Using this approach your list would then change from:
<Mvx.MvxBindableListView
....
/>
to:
<Abv.MyListView
....
/>
For more examples of custom views, take a look around GitHub - e.g. at some of the Calendar, ColorPicker, ActionBar projects in https://github.com/Cheesebaron
Don't expect your custom controls to render in the xamarin designer (well, not yet...)
Two final notes...
To reuse code... you might want to put that HideSoftInputFromWindow functionality in an extension method somehow so that you can just call anyEditText.HideOnDone()
Be careful when using the Monodroid/monotouch events on Views/UIViews - these events tend to use the native delegates/listeners - and so sometimes you can find that attaching something to subscribe to one event can unattach something else! Generally you are OK as long as you don't mix and match the C# event subscriptions at the same time as the native listener/delegate handlers.

how to use binding from a grid to an HTML template?

is it possible to use GXT's binding mechanism to bind a Grid to an Html (or other Widget implementation for that matter)?
it seems from the examples that it's only applicable for forms (FormBinding), while my purpose is to have a Template updating a widgets inner element, driven by the grid's SelectionChangedEvents sending the models for that template.
Binding grids and generic components directly is apparently not possible at the current version of GXT, anyhow this is an alternative solution offered as a workaround:
I just made use of the examples Grid Binding and Templates to support your requirement. Here is the modified code
#Override
protected void onRender(Element parent, int index) {
super.onRender(parent, index);
setStyleAttribute("margin", "10px");
ContentPanel cp = new ContentPanel();
cp.setHeading("Form Bindings");
cp.setFrame(true);
cp.setSize(800, 400);
cp.setLayout(new RowLayout(Orientation.HORIZONTAL));
final LayoutContainer panel = new LayoutContainer(new FlowLayout());
Grid<Stock> grid = createGrid();
grid.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
final Template template = new Template(getTemplate());
grid.getSelectionModel().addListener(Events.SelectionChange, new Listener<SelectionChangedEvent<Stock>>() {
public void handleEvent(SelectionChangedEvent<Stock> be) {
if (be.getSelection().size() > 0) {
template.overwrite(panel.getElement(), Util.getJsObject(be.getSelectedItem()));
} else {
panel.removeAll();
}
}
});
cp.add(grid, new RowData(.6, 1));
cp.add(panel, new RowData(.4, 1));
add(cp);
}
private native String getTemplate() /*-{
var html = [ '<p>Name: {name}</p>', '<p>Symbol: {symbol}</p>',
'<p>Last: {last}</p>', '<p>Last Updated: {date}</p>', ];
return html.join("");
}-*/;
Add these modifications to the Grid Binding example. Hope this helps.
Thanks,
Ganesh

instantiate a MenuItem

I have the following problem with a blackberry demo class:
MenuItem locatorItem = new MenuItem(new StringProvider("Location Search"), 0x230020, 0);
locatorItem.setCommand(new Command(new CommandHandler()
(...)
I am using Eclipse and a BlackBerry simulator to get this demo running and I get the 'Cannot instantiate the type MenuItem' error. I don't know why and there's no suggestion to solve it.
I imported 'net.rim.device.api.ui.MenuItem;'.
I think you're using the wrong type of MenuItem. net.rim.device.api.ui.MenuItem you are using is specific to the Blackberry.
If this is a J2ME Application/Midlet, just create a javax.microedition.lcdui.Command. They are turned into menu items on the blackberry.
If you're also usingnet.rim.device.api.ui.Screen or any other net.rim classes in the application, this is the way menu items are usually created:
function doSomething() {
// Your Code Here
}
// In the function building your screen
MenuItem somethingMi = new MenuItem() {
private MenuItem() { super("Do Something",100001, 5); }
public void run() { doSomething() };
}
addMenuItem(somethingMI);

adding custom property to webpart with a custom toolpart

I'm trying to add a custom property to my webpart as below:
[Personalizable(PersonalizationScope.Shared)]
[WebBrowsable(true)]
[System.ComponentModel.Category("Settings")]
[WebDisplayName("RSS List Path")]
[WebDescription("")]
public string RSSListURL
{
get
{
if (_myListURL == null)
{
_myListURL = "http://server2003dev/dev/";
}
return _myListURL;
}
set { _myListURL = value; }
}
But within the webpart I am also overriding the GetToolParts() method as below with my own custom toolpart:
public override ToolPart[] GetToolParts()
{
return new ToolPart[] { new RSSCountrySettings(), new WebPartToolPart() };
}
I need to display my custom toolpart (RSSCountrySettings) and my custom propery (RSS List Path) under the catergory Settings.
Any ideas how I do this, I able to only get one but not both to display...?
You are not using the base class's toolparts. Try this instead:
public override ToolPart[] GetToolParts()
{
var result = new List<ToolPart>() ;
var toolparts = base.GetToolParts();
result.AddRange(toolparts.ToList());
result.Add(new WebPartToolPart());
return result.ToArray();
}
The reason you need to do this is that the base class generates a toolpart for your custom property. However, you do not allow it to add that toolpart to the toolpart collection. So, you must get the base class's toolparts as a collection, then add yours in there as well. That's the danger in overriding an existing method. Check this link out for more info
You have to add CustomPropertyToolPart to toolParts list. Like this:
public override Microsoft.SharePoint.WebPartPages.ToolPart[] GetToolParts()
{
List<ToolPart> list = new List<ToolPart>();
list.AddRange(base.GetToolParts());
// adds custom controls
result.Add(new WebPartToolPart());
// adds default controls for properties marked with [WebBrowsable(true)]
list.Add(new CustomPropertyToolPart());
return list.ToArray();
}

Resources