New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spec: Visual #4435

Open
davidortinau opened this Issue Nov 15, 2018 · 4 comments

Comments

@davidortinau
Contributor

davidortinau commented Nov 15, 2018

Rationale

Customers desire to more easily create Xamarin.Forms applications that look mostly or exactly the same by default on iOS and Android. In examining the style of design that is most typically implemented, Material design is the most beneficial starting point.

Developers should be able to express their design for this starting point at the top level of their Xamarin.Forms application, and have that preference reflected throughout.

Developers should be able to also control this preference at the ContentPage and control levell.

In the future, additional Visual styles may be supported, such as Cupertino, Fluent, or any other design styling that someone would wish to implement themselves.

Goals

  • Visually identical rendering
    • Not to be confused with “pixel perfect”. Visually identical means the naked eye can’t tell the difference at a glance.
  • High performance
    • Switching
    • Rendering
    • Inflation
  • Dynamic switching between visuals
  • Target controls
    • ActivityIndicator
    • Button
    • DatePicker
    • Entry
    • Editor
    • ListView
      • Done with just some default property setting really
    • Picker
    • ProgressBar
    • SearchBar
    • Slider
    • Stepper
    • Switch
    • TimePicker
      Stretch Goals
  • User control of rendering
    • In renderer
    • In cross-platform code
  • Support of Material-only properties
    • Elevation in particular would be neat

Button

Icon

  • On Android the Icon will now be placed directly to the left/right of the text
  • More Icon configuration properties (bounds, aspect, or implicit sizing)
class Button
{
     public Color ImageTint {get; set;}
     public Size ImageSize {get; set;}
     public ImageSizing ImageSizing {get; set;}
     public Aspect ImageAspect {get; set;}
}

public enum ImageSizing
{
      Default,
      MatchTextHeight, //this will maintain image ratio
      MatchSizeToTextHeight //this will make a square out of all images
}

Limitations

  • The controls remain native controls, and as such there will naturally still be differences in areas such as fonts, shadows, elevation, and colors (consider how iOS does alpha blending on the navigation bar for example, resulting in visual color differences compared to Android).
  • Not all controls have a material implementation or style.

Implementation

Branch working from

public class VisualElement
{
  
  [TypeConverter] //used for css
  public IVisual Visual { get; set; } //BP
}

public interface IVisual {}

namespace Xamarin.Forms
{
	public static class Visual
	{
		public static IVisual MatchParent { get; } = new MatchParentVisual();
		public static IVisual Default { get; } = new DefaultVisual();
		public static IVisual Material { get; } = new MaterialVisual();

		public sealed class MaterialVisual : IVisual { }
		public sealed class DefaultVisual : IVisual { }
		public sealed class MatchParentVisual : IVisual { }
	}

	public interface IVisual { }
}

namespace Xamarin.Forms
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	public abstract class HandlerAttribute : Attribute
	{
		protected HandlerAttribute(Type handler, Type target, Type[] supportedVisuals = null)
		{
			SupportedVisuals = supportedVisuals ?? new[] { typeof(Visual.DefaultVisual) };
			TargetType = target;
			HandlerType = handler;
		}

		internal Type[] SupportedVisuals { get; private set; }
		internal Type HandlerType { get; private set; }

		internal Type TargetType { get; private set; }

		public virtual bool ShouldRegister()
		{
			return true;
		}
	}
}

Example Renderer

[assembly: ExportRenderer(typeof(Entry), typeof(MaterialTextViewRenderer), new[] { typeof(Visual.MateralVisual) })]
namespace Xamarin.Forms.ControlGallery.Android
{
	public class MaterialEntryRenderer : ViewRenderer<Xamarin.Forms.Controls.App.MaterialTextView, global::Android.Support.Design.Widget.TextInputLayout>
	{
	}
}

Example CSS


* {
  visual: material;
}

Button {
  visual: fluent;
}

.normal {
  visual: normal;
}

At Renderer selection time the Visual property of the View is inspected and included in the renderer selection process. When the Visual changes the Renderer is recreated from scratch along with any children. The SupportsVisualTypes property on the renderer is tested

IVisual is nothing more than a marker interface used at renderer selection time. For something like a skia backend you would then use an attached property to attach the drawing to the visual. This API gives us maximum flexibility.

Implementation Notes

Currently just creating new renderers for material components

  • If a single renderer contains a reference to both the material text box and the normal one then the material one can't be linked out
  • When implementing the MaterialEntryRenderer on iOS the placeholder code will break it so for now I feel it's just easier to develop as it's own thing while it's being spiked and once it's in a happy place merging behavior can make sense

iOS

https://www.nuget.org/packages/Xamarin.iOS.MaterialComponents/

Android

  • Will take a hard dependency on the v28 of the support libraries as these contain all the Material theme's and components
  • Currently it will be required to set your theme to Material in order to get the Material Components https://github.com/material-components/material-components-android/blob/master/docs/getting-started.md
  • Support libraries v28 are still a bit quirky. I had to enable multi dex for the project to compile and currently some interfaces dealing with tabs are broken so those had to be commented out
@AmrAlSayed0

This comment has been minimized.

AmrAlSayed0 commented Nov 15, 2018

So is this somehow supposed to be complementary to Shell/Material Shell spec?

@andersondamasio

This comment has been minimized.

andersondamasio commented Nov 16, 2018

should this launch come only in 2019?

@davidortinau

This comment has been minimized.

Contributor

davidortinau commented Nov 16, 2018

@AmrAlSayed0 it is how we will support things like MaterialShell, yes. This works independent of Shell.

@andersondamasio we will have a preview available in a few weeks. When I get to my desk I will share some screenshots of the progress to see what everyone thinks.

@kingces95 kingces95 removed this from New in Triage Nov 16, 2018

@PureWeen

This comment has been minimized.

Contributor

PureWeen commented Nov 21, 2018

Added Button Icon APIs. Comments are welcome

@rmarinho rmarinho closed this in 94e6621 Nov 23, 2018

@rmarinho rmarinho added this to Done in Enhancements via automation Nov 23, 2018

@PureWeen PureWeen reopened this Nov 27, 2018

@PureWeen PureWeen moved this from Done to In Progress in Enhancements Nov 27, 2018

@samhouts samhouts added this to In progress in Sprint 145 Nov 30, 2018

@samhouts samhouts added the a/visual label Dec 4, 2018

@samhouts samhouts added this to To do in Sprint 146 via automation Dec 15, 2018

@samhouts samhouts moved this from To do to In progress in Sprint 146 Dec 15, 2018

@samhouts samhouts added this to In progress in Sprint 147 Jan 9, 2019

@samhouts samhouts added this to the 4.0.0 milestone Jan 10, 2019

@samhouts samhouts added this to In Progress in vNext (Target 3.5.0) Jan 11, 2019

@samhouts samhouts moved this from In progress to Done in Sprint 147 Jan 11, 2019

@samhouts samhouts moved this from In Progress to Done in vNext (Target 3.5.0) Jan 11, 2019

@samhouts samhouts removed this from Done in vNext (Target 3.5.0) Jan 11, 2019

@samhouts samhouts removed this from In Progress in Enhancements Jan 11, 2019

@samhouts samhouts added this to In Progress in vNext (Target 3.5.0) Jan 11, 2019

@samhouts samhouts moved this from In Progress to Done in vNext (Target 3.5.0) Jan 14, 2019

@samhouts samhouts removed this from Done in vNext (Target 3.5.0) Jan 14, 2019

@samhouts samhouts added this to In Progress in vNext (Target 3.5.0) Jan 15, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment