Skip to content
This repository was archived by the owner on May 1, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Xamarin.Forms.ControlGallery.Android/CustomRenderers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ protected override void UpdateMenuItemIcon(Context context, IMenuItem menuItem,
if (toolBarItem.IconImageSource is FileImageSource fileImageSource)
{
var name = IOPath.GetFileNameWithoutExtension(fileImageSource.File);
var id = Xamarin.Forms.Platform.Android.ResourceManager.GetDrawableByName(name);
var id = context.GetDrawableId(name);
if (id != 0)
{
if ((int)Build.VERSION.SdkInt >= 21)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@ protected override void OnCreate(Bundle bundle)
#endif
Forms.Init(this, bundle);

// null out the assembly on the Resource Manager
// so all of our tests run without using the reflection APIs
// At some point the Resources class types will go away so
// reflection will stop working
ResourceManager.Init(null);

FormsMaps.Init(this, bundle);
FormsMaterial.Init(this, bundle);
AndroidAppLinks.Init(this);
Expand Down
36 changes: 19 additions & 17 deletions Xamarin.Forms.Platform.Android.UnitTests/ButtonTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using Xamarin.Forms;
using Xamarin.Forms.CustomAttributes;
using AColor = Android.Graphics.Color;
using AContextThemeWrapper = Android.Support.V7.View.ContextThemeWrapper;

namespace Xamarin.Forms.Platform.Android.UnitTests
{
Expand Down Expand Up @@ -95,25 +96,26 @@ public void StyleTextAllCapsSettingIsRespected()
}

// This is the ideal test for Issue11703. It's currently being tabled due to a Resource linking bug that we're working out with Android team
//[Category("Button")]
//[Description("Account for user's setting of styles property textAllCaps")]
//[Issue(IssueTracker.Github, 11703, "[Bug] Android textAllCaps no longer works", issueTestNumber: 1)]
//[TestCase(false)]
//[TestCase(true)]
//public void StyleTextAllCapsSettingIsRespected(bool allCaps)
//{
// ContextThemeWrapper contextThemeWrapper = null;
// if (allCaps)
// contextThemeWrapper = new ContextThemeWrapper(Context, Resource.Style.TextAllCapsStyleTrue);
// else
// contextThemeWrapper = new ContextThemeWrapper(Context, Resource.Style.TextAllCapsStyleFalse);
/*[Category("Button")]
[Description("Account for user's setting of styles property textAllCaps")]
[Issue(IssueTracker.Github, 11703, "[Bug] Android textAllCaps no longer works", issueTestNumber: 1)]
[TestCase(false)]
[TestCase(true)]
public async Task StyleTextAllCapsSettingIsRespected(bool allCaps)
{
AContextThemeWrapper contextThemeWrapper = null;
if (allCaps)
contextThemeWrapper = new AContextThemeWrapper(Context, Context.GetStyle("TextAllCapsStyleTrue"));
else
contextThemeWrapper = new AContextThemeWrapper(Context, Context.GetStyle("TextAllCapsStyleFalse"));

// var button = new Button { Text = "foo" };
// var buttonControl = GetRenderer(button, contextThemeWrapper).View as AppCompatButton;
// var initialTextTransform = buttonControl.TransformationMethod;
var button = new Button { Text = "foo" };
var initialTextTransform = await GetControlProperty(button, x => x.TransformationMethod);

// Assert.AreEqual(allCaps, initialTextTransform is AllCapsTransformationMethod);
//}
// when set through a style the type is an internal version of AllCapsTransformationMethod
string typeName = $"{initialTextTransform}";
Assert.AreEqual(allCaps, typeName.Contains("AllCapsTransformationMethod"));
}*/

}
}
30 changes: 30 additions & 0 deletions Xamarin.Forms.Platform.Android.UnitTests/ResourceManagerTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System;
using System.Threading.Tasks;
using Android.Views;
using NUnit.Framework;

namespace Xamarin.Forms.Platform.Android.UnitTests
{
[TestFixture]
public class ResourceManagerTests : PlatformTestFixture
{
[Test, Category("Resource")]
[Description("Retrieve Resources by Name")]
public void RetrieveResourcesByName()
{
ResourceManager.Init(null);
ResourceManager.DrawableClass = null;
ResourceManager.LayoutClass = null;
ResourceManager.ResourceClass = null;
ResourceManager.StyleClass = null;

Assert.Greater(ResourceManager.GetDrawableId(this.Context, "DrawableTEST"), 0);
Assert.Greater(ResourceManager.GetDrawableId(this.Context, "DrawableTEST.png"), 0);
Assert.Greater(ResourceManager.GetLayout(this.Context, "LayoutTest"), 0);
Assert.Greater(ResourceManager.GetStyle(this.Context, "TextAllCapsStyleTrue"), 0);
Assert.Greater(ResourceManager.GetResource(this.Context, "namewith.adot"), 0);
Assert.Greater(ResourceManager.GetResource(this.Context, "namewith_adot"), 0);

}
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
>

<android.support.design.widget.AppBarLayout
android:id="@+id/namewith.adot"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
>

<android.support.v7.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

</android.support.design.widget.AppBarLayout>

</android.support.design.widget.CoordinatorLayout>
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
<Compile Include="ButtonTests.cs" />
<Compile Include="BackgroundTests.cs" />
<Compile Include="TestActivity.cs" />
<Compile Include="ResourceManagerTests.cs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="NUnit">
Expand Down Expand Up @@ -97,6 +98,12 @@
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\values\styles.xml" />
<AndroidResource Include="Resources\layout\LayoutTest.axml" />
<AndroidResource Include="Resources\drawable\DrawableTest.png" />
</ItemGroup>
<ItemGroup>
<Folder Include="Resources\drawable\" />
<Folder Include="Resources\layout\" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
</Project>
2 changes: 1 addition & 1 deletion Xamarin.Forms.Platform.Android/Platform.cs
Original file line number Diff line number Diff line change
Expand Up @@ -803,7 +803,7 @@ void GetNewMasterDetailToggle()
if (fileImageSource == null)
throw new InvalidOperationException("Icon property must be a FileImageSource on Master page");

int icon = ResourceManager.GetDrawableByName(fileImageSource);
int icon = _activity.GetDrawableId(fileImageSource);

FastRenderers.AutomationPropertiesProvider.GetDrawerAccessibilityResources(_activity, CurrentMasterDetailPage, out int resourceIdOpen, out int resourceIdClose);
#pragma warning disable 618 // Eventually we will need to determine how to handle the v7 ActionBarDrawerToggle for AppCompat
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ public override bool SelectDrawable(int index)
InJustDecodeBounds = true
};

int drawableIdentifier = ResourceManager.GetDrawableByName(file);
int drawableIdentifier = context.GetDrawableId(file);

if (drawableIdentifier != 0)
{
Expand Down
76 changes: 49 additions & 27 deletions Xamarin.Forms.Platform.Android/ResourceManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public static class ResourceManager
static Assembly _assembly;
static Type FindType(string name, string altName)
{
return _assembly.GetTypes().FirstOrDefault(x => x.Name == name || x.Name == altName);
return _assembly?.GetTypes().FirstOrDefault(x => x.Name == name || x.Name == altName);
}
static Type _drawableClass;
static Type _resourceClass;
Expand Down Expand Up @@ -93,7 +93,7 @@ public static Type LayoutClass {
if (imageSource is FileImageSource fileImageSource)
{
var file = fileImageSource.File;
var id = IdFromTitle(file, DrawableClass);
var id = IdFromTitle(file, DrawableClass, "drawable", context);

// try the drawables via id
if (id != 0)
Expand Down Expand Up @@ -353,29 +353,47 @@ public static Drawable GetDrawable(this Context context, string name)
return AndroidAppCompat.GetDrawable(context, id);
}

public static int GetDrawableId(this Context context, string title)
{
return IdFromTitle(title, DrawableClass, _drawableDefType, context);
}

[Obsolete("GetDrawableByName(string) is obsolete as of version 4.8. "
+ "Please use GetDrawableId(string, context) instead.")]
public static int GetDrawableByName(string name)
{
return IdFromTitle(name, DrawableClass);
return IdFromTitle(name, DrawableClass, _drawableDefType, Forms.ApplicationContext);
}

[Obsolete("GetResourceByName(string) is obsolete as of version 4.8. "
+ "Please use GetResource(string, context) instead.")]
public static int GetResourceByName(string name)
{
return IdFromTitle(name, ResourceClass);
return IdFromTitle(name, ResourceClass, "id", Forms.ApplicationContext);
}

public static int GetResource(this Context context, string title)
{
return IdFromTitle(title, ResourceClass, "id", context);
}

[Obsolete("GetLayoutByName(string) is obsolete as of version 4.8. "
+ "Please use GetLayout(string, context) instead.")]
public static int GetLayoutByName(string name)
{
return IdFromTitle(name, LayoutClass);
return IdFromTitle(name, LayoutClass, "layout", Forms.ApplicationContext);
}

public static int GetLayout(this Context context, string name)
{
return IdFromTitle(name, LayoutClass, "layout", context);
}

[Obsolete("GetStyleByName(string) is obsolete as of version 4.8. "
+ "Please use GetStyle(string, context) instead.")]
public static int GetStyleByName(string name)
{
return IdFromTitle(name, StyleClass);
return IdFromTitle(name, StyleClass, "style", Forms.ApplicationContext);
}

public static int GetStyle(this Context context, string name)
Expand All @@ -388,24 +406,14 @@ public static void Init(Assembly masterAssembly)
_assembly = masterAssembly;
}

static int IdFromTitle(string title, Type type)
{
if (title == null)
return 0;

string name = IOPath.GetFileNameWithoutExtension(title);
int id = GetId(type, name);
return id;
}

static int IdFromTitle(string title, Type resourceType, string defType, Resources resource)
{
return IdFromTitle(title, resourceType, defType, resource, AppCompat.Platform.GetPackageName());
}

static int IdFromTitle(string title, Type resourceType, string defType, Context context)
{
return IdFromTitle(title, resourceType, defType, context.Resources, context.PackageName);
return IdFromTitle(title, resourceType, defType, context?.Resources, context?.PackageName);
}

static int IdFromTitle(string title, Type resourceType, string defType, Resources resource, string packageName)
Expand All @@ -414,24 +422,38 @@ static int IdFromTitle(string title, Type resourceType, string defType, Resource
if (title == null)
return id;

string name = IOPath.GetFileNameWithoutExtension(title);
string name;

id = GetId(resourceType, name);
if (defType == "style" || (resourceType != null && resourceType == StyleClass))
name = title;
else
name = title.ToLower();

if (id > 0)
if (defType == _drawableDefType || (resourceType != null && resourceType == DrawableClass))
name = IOPath.GetFileNameWithoutExtension(name);

if ((id = SearchByIdentifier(name, defType, resource, packageName)) > 0)
return id;

if (packageName != null)
// When searching by reflection you would use a "_" instead of a "."
// So this accounts for cases where users were searching with an "_"
if ((id = SearchByIdentifier(name.Replace("_", "."), defType, resource, packageName)) > 0)
return id;

int SearchByIdentifier(string n, string d, Resources r, string p)
{
id = resource.GetIdentifier(name, defType, packageName);
int returnValue = 0;

if (id > 0)
return id;
}
if (p != null)
returnValue = r.GetIdentifier(n, d, p);

id = resource.GetIdentifier(name, defType, null);
if (returnValue == 0)
returnValue = r.GetIdentifier(n, d, null);

return returnValue;
}

return id;
return GetId(resourceType, name);
}

static int GetId(Type type, string memberName)
Expand Down