Last active
August 29, 2015 14:14
-
-
Save kjeremy/5b76cb2eb82ff6caa046 to your computer and use it in GitHub Desktop.
AppCompat-v22 Tinting for MvvmCross
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <summary> | |
/// Tint-aware version of MvxSpinner so that it's styled properly | |
/// with AppCompat V21 | |
/// </summary> | |
public class MvxAppCompatSpinner : MvxSpinner, ITintableBackgroundView | |
{ | |
private static readonly int[] TintAttrs = | |
{ | |
Android.Resource.Attribute.Background, | |
Android.Resource.Attribute.PopupBackground | |
}; | |
private TintInfo _backgroundTint; | |
public MvxAppCompatSpinner(Context context) | |
: this(context, null) {} | |
public MvxAppCompatSpinner(Context context, IAttributeSet attributes) | |
: base(context, attributes) | |
{ | |
if (TintManager.ShouldBeUsed) | |
{ | |
TintTypedArray a = TintTypedArray.ObtainStyledAttributes(context, attributes, | |
TintAttrs, Android.Resource.Attribute.SpinnerStyle, 0); | |
if (a.HasValue(0)) | |
{ | |
ColorStateList tint = a.TintManager.GetTintList(a.GetResourceId(0, -1)); | |
if (tint != null) | |
{ | |
SupportBackgroundTintList = tint; | |
} | |
} | |
if (a.HasValue(1)) | |
{ | |
Drawable popupBackground = a.GetDrawable(1); | |
if ((int)Build.VERSION.SdkInt >= 16) | |
{ | |
SetPopupBackgroundDrawable(popupBackground); | |
} | |
else if ((int)Build.VERSION.SdkInt >= 11) | |
{ | |
SetPopupBackgroundDrawableV11(this, popupBackground); | |
} | |
} | |
a.Recycle(); | |
} | |
} | |
[TargetApi(Value = (int)BuildVersionCodes.Honeycomb)] | |
private static void SetPopupBackgroundDrawableV11(Spinner view, Drawable background) | |
{ | |
try | |
{ | |
Field popupField = Class.FromType(typeof(Spinner)).GetDeclaredField("mPopup"); | |
popupField.Accessible = true; | |
Object popup = popupField.Get(view); | |
if (popup is ListPopupWindow) | |
{ | |
((ListPopupWindow)popup).SetBackgroundDrawable(background); | |
} | |
} | |
catch (NoSuchFieldException e) | |
{ | |
e.PrintStackTrace(); | |
} | |
catch (IllegalAccessException e) | |
{ | |
e.PrintStackTrace(); | |
} | |
} | |
public ColorStateList SupportBackgroundTintList | |
{ | |
get { return _backgroundTint != null ? _backgroundTint.MTintList : null; } | |
set | |
{ | |
if (_backgroundTint == null) | |
{ | |
_backgroundTint = new TintInfo(); | |
} | |
_backgroundTint.MTintList = value; | |
_backgroundTint.MHasTintList = true; | |
ApplySupportBackgroundTint(); | |
} | |
} | |
public PorterDuff.Mode SupportBackgroundTintMode | |
{ | |
get { return _backgroundTint != null ? _backgroundTint.MTintMode : null; } | |
set | |
{ | |
if (_backgroundTint == null) | |
{ | |
_backgroundTint = new TintInfo(); | |
} | |
_backgroundTint.MTintMode = value; | |
_backgroundTint.MHasTintMode = true; | |
ApplySupportBackgroundTint(); | |
} | |
} | |
protected override void DrawableStateChanged() | |
{ | |
base.DrawableStateChanged(); | |
ApplySupportBackgroundTint(); | |
} | |
private void ApplySupportBackgroundTint() | |
{ | |
if (Background != null && _backgroundTint != null) | |
TintManager.TintViewBackground(this, _backgroundTint); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Setup : MvxAndroidSetup | |
{ | |
public Setup(Context applicationContext) : base(applicationContext) | |
{ | |
} | |
protected override IMvxApplication CreateApp() | |
{ | |
return new App(); | |
} | |
protected override IMvxTrace CreateDebugTrace() | |
{ | |
return new DebugTrace(); | |
} | |
protected override IList<Assembly> AndroidViewAssemblies | |
{ | |
get | |
{ | |
var toReturn = base.AndroidViewAssemblies; | |
// Add assemblies with other views we use. When the XML is inflated | |
// MvvmCross knows about the types and won't compain about them. This | |
// speeds up inflation noticeably. | |
toReturn.Add(typeof(DrawerLayout).Assembly); | |
toReturn.Add(typeof(SwitchCompat).Assembly); | |
return toReturn; | |
} | |
} | |
public class AppCompatViewFactory : MvxAndroidViewFactory | |
{ | |
public override View CreateView(View parent, string name, Context context, IAttributeSet attrs) | |
{ | |
if (Build.VERSION.SdkInt < BuildVersionCodes.Lollipop) | |
{ | |
// If we're running pre-L, we need to 'inject' our tint aware Views in place of the | |
// standard framework versions | |
switch (name) | |
{ | |
case "EditText": | |
return new AppCompatEditText(context, attrs); | |
case "MvxSpinner": // Use our own tint-aware version of MvxSpinner | |
return new MvxAppCompatSpinner(context, attrs); | |
case "Spinner": | |
return new AppCompatSpinner(context, attrs); | |
case "CheckBox": | |
return new AppCompatCheckBox(context, attrs); | |
case "RadioButton": | |
return new AppCompatRadioButton(context, attrs); | |
case "CheckedTextView": | |
return new AppCompatCheckedTextView(context, attrs); | |
case "AutoCompleteTextView": | |
return new AppCompatAutoCompleteTextView(context, attrs); | |
case "MultiAutoCompleteTextView": | |
return new AppCompatMultiAutoCompleteTextView(context, attrs); | |
case "RatingBar": | |
return new AppCompatRatingBar(context, attrs); | |
case "Button": | |
return new AppCompatButton(context, attrs); | |
} | |
} | |
return base.CreateView(parent, name, context, attrs); | |
} | |
} | |
public class BindingBuilder : MvxAndroidBindingBuilder | |
{ | |
protected override IMvxAndroidViewFactory CreateAndroidViewFactory() | |
{ | |
return new AppCompatViewFactory(); | |
} | |
} | |
protected override MvxAndroidBindingBuilder CreateBindingBuilder() | |
{ | |
return new BindingBuilder(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Alternatively one can discriminate on the
Context
. This version is more forward compatible: for instance theme inheritance with v22.1 will work